/src/gdal/frmts/grib/degrib/degrib/clock.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <ctype.h> |
2 | | #include <limits.h> |
3 | | #include <math.h> |
4 | | #include <stdio.h> |
5 | | #include <string.h> |
6 | | #include <stdlib.h> |
7 | | #include <time.h> |
8 | | #include "clock.h" |
9 | | #include "myutil.h" |
10 | | #include "myassert.h" |
11 | | #ifdef MEMWATCH |
12 | | #include "memwatch.h" |
13 | | #endif |
14 | | |
15 | | #include "cpl_port.h" |
16 | | |
17 | | /* Take a look at the options in: |
18 | | * http://www.unet.univie.ac.at/aix/cmds/aixcmds2/date.htm#A270961 |
19 | | */ |
20 | | /* Timezone is defined through out as the time needed to add to local time |
21 | | * to get UTC, rather than the reverse. So EST is +5 not -5. */ |
22 | | |
23 | 299k | #define PERIOD_YEARS 146097L |
24 | 209k | #define SEC_DAY 86400L |
25 | 3.57M | #define ISLEAPYEAR(y) (((y)%400 == 0) || (((y)%4 == 0) && ((y)%100 != 0))) |
26 | | |
27 | | /***************************************************************************** |
28 | | * ThirdMonday() -- |
29 | | * |
30 | | * Carl McCalla / MDL |
31 | | * |
32 | | * PURPOSE |
33 | | * Compute the day-of-the-month which is the third Monday of the month. |
34 | | * |
35 | | * ARGUMENTS |
36 | | * monthStartDOW = starting day of the week (e.g., 0 = Sunday, 1 = Monday, |
37 | | * etc.) (Input) |
38 | | * |
39 | | * RETURNS |
40 | | * int (the day-of-the-month which is the third Monday of the month) |
41 | | * |
42 | | * HISTORY |
43 | | * 6/2006 Carl McCalla, Sr. (MDL): Created |
44 | | * |
45 | | * NOTES |
46 | | * *************************************************************************** |
47 | | */ |
48 | | static int ThirdMonday (int monthStartDOW) |
49 | 0 | { |
50 | 0 | if (monthStartDOW == 0) { |
51 | 0 | return 16; |
52 | 0 | } else if (monthStartDOW == 1) { |
53 | 0 | return 15; |
54 | 0 | } else { |
55 | 0 | return ((7 - monthStartDOW) + 16); |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | | /***************************************************************************** |
60 | | * Memorialday() -- |
61 | | * |
62 | | * Carl McCalla / MDL |
63 | | * |
64 | | * PURPOSE |
65 | | * For the month of May, compute the day-of-the-month which is Memorial Day. |
66 | | * |
67 | | * ARGUMENTS |
68 | | * monthStartDOW = starting day of the week (e.g., 0 = Sunday, 1 = Monday, |
69 | | * etc.) (Input) |
70 | | * |
71 | | * RETURNS |
72 | | * int (the day-of-the-month which is Memorial Day) |
73 | | * |
74 | | * HISTORY |
75 | | * 6/2006 Carl McCalla, Sr. (MDL): Created |
76 | | * |
77 | | * NOTES |
78 | | * *************************************************************************** |
79 | | */ |
80 | | static int Memorialday (int monthStartDOW) |
81 | 0 | { |
82 | 0 | if (monthStartDOW == 0) { |
83 | 0 | return 30; |
84 | 0 | } else if (monthStartDOW == 6) { |
85 | 0 | return 31; |
86 | 0 | } else { |
87 | 0 | return ((5 - monthStartDOW) + 25); |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | | /***************************************************************************** |
92 | | * Laborday() -- |
93 | | * |
94 | | * Carl McCalla / MDL |
95 | | * |
96 | | * PURPOSE |
97 | | * For the month of September, compute the day-of-the-month which is Labor |
98 | | * Day. |
99 | | * |
100 | | * ARGUMENTS |
101 | | * monthStartDOW = starting day of the week (e.g., 0 = Sunday, 1 = Monday, |
102 | | * etc.) (Input) |
103 | | * |
104 | | * RETURNS |
105 | | * int (the day-of-the-month which is Labor Day) |
106 | | * |
107 | | * HISTORY |
108 | | * 6/2006 Carl McCalla, Sr. (MDL): Created |
109 | | * |
110 | | * NOTES |
111 | | * *************************************************************************** |
112 | | */ |
113 | | static int Laborday (int monthStartDOW) |
114 | 0 | { |
115 | 0 | if (monthStartDOW == 0) { |
116 | 0 | return 2; |
117 | 0 | } else if (monthStartDOW == 1) { |
118 | 0 | return 1; |
119 | 0 | } else { |
120 | 0 | return ((6 - monthStartDOW) + 3); |
121 | 0 | } |
122 | 0 | } |
123 | | |
124 | | /***************************************************************************** |
125 | | * Columbusday() -- |
126 | | * |
127 | | * Carl McCalla /MDL |
128 | | * |
129 | | * PURPOSE |
130 | | * For the month of October, compute the day-of-the-month which is Columbus |
131 | | * Day. |
132 | | * |
133 | | * ARGUMENTS |
134 | | * monthStartDOW = starting day of the week (e.g., 0 = Sunday, 1 = Monday, |
135 | | * etc.) (Input) |
136 | | * |
137 | | * RETURNS |
138 | | * int (the day-of-the-month which is Columbus Day) |
139 | | * |
140 | | * HISTORY |
141 | | * 6/2006 Carl McCalla, Sr. (MDL): Created |
142 | | * |
143 | | * NOTES |
144 | | * *************************************************************************** |
145 | | */ |
146 | | static int Columbusday (int monthStartDOW) |
147 | 0 | { |
148 | 0 | if ((monthStartDOW == 0) || (monthStartDOW == 1)) { |
149 | 0 | return (9 - monthStartDOW); |
150 | 0 | } else { |
151 | 0 | return (16 - monthStartDOW); |
152 | 0 | } |
153 | 0 | } |
154 | | |
155 | | /***************************************************************************** |
156 | | * Thanksgivingday() -- |
157 | | * |
158 | | * Carl McCalla /MDL |
159 | | * |
160 | | * PURPOSE |
161 | | * For the month of November, compute the day-of-the-month which is |
162 | | * Thanksgiving Day. |
163 | | * |
164 | | * ARGUMENTS |
165 | | * monthStartDOW = starting day of the week (e.g., 0 = Sunday, 1 = Monday, |
166 | | * etc.) (Input) |
167 | | * |
168 | | * RETURNS |
169 | | * int (the day-of-the-month which is Thanksgiving Day) |
170 | | * |
171 | | * HISTORY |
172 | | * 6/2006 Carl McCalla, Sr. (MDL): Created |
173 | | * |
174 | | * NOTES |
175 | | * *************************************************************************** |
176 | | */ |
177 | | static int Thanksgivingday (int monthStartDOW) |
178 | 0 | { |
179 | 0 | if ((monthStartDOW >= 0) && (monthStartDOW <= 4)) { |
180 | 0 | return (26 - monthStartDOW); |
181 | 0 | } else if (monthStartDOW == 5) { |
182 | 0 | return 28; |
183 | 0 | } else { |
184 | 0 | return 27; |
185 | 0 | } |
186 | 0 | } |
187 | | |
188 | | /***************************************************************************** |
189 | | * Clock_Holiday() -- |
190 | | * |
191 | | * Carl McCalla /MDL |
192 | | * |
193 | | * PURPOSE |
194 | | * Return a holiday string (e.g., Christmas Day, Thanksgiving Day, etc.), if |
195 | | * the current day of the month is a federal holiday. |
196 | | * |
197 | | * ARGUMENTS |
198 | | * month = month of the year (e.g., 1 = Jan, 2 = Feb, etc.) (Input) |
199 | | * day = the current day of the month (e.g., 1, 2, 3 ...) (Input) |
200 | | * monthStartDOW = the day-of-the-month which is the first day of the month |
201 | | * (e.g., 0 = Sunday, 1 = Monday, etc.) |
202 | | * answer = String containing the holiday string, if the current day is |
203 | | * a federal holiday, or a "", if the current day is not a |
204 | | * federal holiday. |
205 | | * |
206 | | * RETURNS |
207 | | * void |
208 | | * |
209 | | * HISTORY |
210 | | * 6/2006 Carl McCalla, Sr. (MDL): Created |
211 | | * |
212 | | * NOTES |
213 | | * *************************************************************************** |
214 | | */ |
215 | | static void Clock_Holiday (int month, int day, int monthStartDOW, |
216 | | char answer[100]) |
217 | 0 | { |
218 | 0 | switch (month) { |
219 | 0 | case 1: /* January */ |
220 | 0 | if (day == 1) { |
221 | 0 | strcpy (answer, "New Years Day"); |
222 | 0 | return; |
223 | 0 | } else if (ThirdMonday (monthStartDOW) == day) { |
224 | 0 | strcpy (answer, "Martin Luther King Jr Day"); |
225 | 0 | return; |
226 | 0 | } |
227 | 0 | break; |
228 | 0 | case 2: /* February */ |
229 | 0 | if (ThirdMonday (monthStartDOW) == day) { |
230 | 0 | strcpy (answer, "Presidents Day"); |
231 | 0 | return; |
232 | 0 | } |
233 | 0 | break; |
234 | 0 | case 5: /* May */ |
235 | 0 | if (Memorialday (monthStartDOW) == day) { |
236 | 0 | strcpy (answer, "Memorial Day"); |
237 | 0 | return; |
238 | 0 | } |
239 | 0 | break; |
240 | 0 | case 7: /* July */ |
241 | 0 | if (day == 4) { |
242 | 0 | strcpy (answer, "Independence Day"); |
243 | 0 | return; |
244 | 0 | } |
245 | 0 | break; |
246 | 0 | case 9: /* September */ |
247 | 0 | if (Laborday (monthStartDOW) == day) { |
248 | 0 | strcpy (answer, "Labor Day"); |
249 | 0 | return; |
250 | 0 | } |
251 | 0 | break; |
252 | 0 | case 10: /* October */ |
253 | 0 | if (Columbusday (monthStartDOW) == day) { |
254 | 0 | strcpy (answer, "Columbus Day"); |
255 | 0 | return; |
256 | 0 | } |
257 | 0 | break; |
258 | 0 | case 11: /* November */ |
259 | 0 | if (day == 11) { |
260 | 0 | strcpy (answer, "Veterans Day"); |
261 | 0 | return; |
262 | 0 | } else if (Thanksgivingday (monthStartDOW) == day) { |
263 | 0 | strcpy (answer, "Thanksgiving Day"); |
264 | 0 | return; |
265 | 0 | } |
266 | 0 | break; |
267 | 0 | case 12: /* December */ |
268 | 0 | if (day == 25) { |
269 | 0 | strcpy (answer, "Christmas Day"); |
270 | 0 | return; |
271 | 0 | } |
272 | 0 | break; |
273 | 0 | } |
274 | 0 | strcpy (answer, ""); |
275 | 0 | return; |
276 | 0 | } |
277 | | |
278 | | /***************************************************************************** |
279 | | * Clock_Epock2YearDay() -- |
280 | | * |
281 | | * Arthur Taylor / MDL |
282 | | * |
283 | | * PURPOSE |
284 | | * To convert the days since the beginning of the epoch to days since |
285 | | * beginning of the year and years since the beginning of the epoch. |
286 | | * |
287 | | * ARGUMENTS |
288 | | * totDay = Number of days since the beginning of the epoch. (Input) |
289 | | * Day = The days since the beginning of the year. (Output) |
290 | | * Yr = The years since the epoch. (Output) |
291 | | * |
292 | | * RETURNS: void |
293 | | * |
294 | | * HISTORY |
295 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
296 | | * 6/2004 AAT (MDL): Updated. |
297 | | * |
298 | | * NOTES |
299 | | ***************************************************************************** |
300 | | */ |
301 | | void Clock_Epoch2YearDay (sInt4 totDay, int *Day, sInt4 *Yr) |
302 | 104k | { |
303 | 104k | sInt4 year; /* Local copy of the year. */ |
304 | | |
305 | 104k | year = 1970; |
306 | | /* Jump to the correct 400 year period of time. */ |
307 | 104k | if ((totDay <= -PERIOD_YEARS) || (totDay >= PERIOD_YEARS)) { |
308 | 30.5k | year += 400 * (totDay / PERIOD_YEARS); |
309 | 30.5k | totDay -= PERIOD_YEARS * (totDay / PERIOD_YEARS); |
310 | 30.5k | } |
311 | 104k | if (totDay >= 0) { |
312 | 3.02M | while (totDay >= 366) { |
313 | 2.93M | if (ISLEAPYEAR (year)) { |
314 | 2.52M | if (totDay >= 1461) { |
315 | 2.46M | year += 4; |
316 | 2.46M | totDay -= 1461; |
317 | 2.46M | } else if (totDay >= 1096) { |
318 | 9.73k | year += 3; |
319 | 9.73k | totDay -= 1096; |
320 | 47.7k | } else if (totDay >= 731) { |
321 | 39.6k | year += 2; |
322 | 39.6k | totDay -= 731; |
323 | 39.6k | } else { |
324 | 8.01k | year++; |
325 | 8.01k | totDay -= 366; |
326 | 8.01k | } |
327 | 2.52M | } else { |
328 | 412k | year++; |
329 | 412k | totDay -= 365; |
330 | 412k | } |
331 | 2.93M | } |
332 | 95.0k | if ((totDay == 365) && (!ISLEAPYEAR (year))) { |
333 | 913 | year++; |
334 | 913 | totDay -= 365; |
335 | 913 | } |
336 | 95.0k | } else { |
337 | 165k | while (totDay <= -366) { |
338 | 155k | year--; |
339 | 155k | if (ISLEAPYEAR (year)) { |
340 | 142k | if (totDay <= -1461) { |
341 | 132k | year -= 3; |
342 | 132k | totDay += 1461; |
343 | 132k | } else if (totDay <= -1096) { |
344 | 732 | year -= 2; |
345 | 732 | totDay += 1096; |
346 | 8.83k | } else if (totDay <= -731) { |
347 | 2.02k | year--; |
348 | 2.02k | totDay += 731; |
349 | 6.80k | } else { |
350 | 6.80k | totDay += 366; |
351 | 6.80k | } |
352 | 142k | } else { |
353 | 13.4k | totDay += 365; |
354 | 13.4k | } |
355 | 155k | } |
356 | 9.79k | if (totDay < 0) { |
357 | 9.72k | year--; |
358 | 9.72k | if (ISLEAPYEAR (year)) { |
359 | 199 | totDay += 366; |
360 | 9.52k | } else { |
361 | 9.52k | totDay += 365; |
362 | 9.52k | } |
363 | 9.72k | } |
364 | 9.79k | } |
365 | 104k | *Day = (int) totDay; |
366 | 104k | *Yr = year; |
367 | 104k | } |
368 | | |
369 | | /***************************************************************************** |
370 | | * Clock_MonthNum() -- |
371 | | * |
372 | | * Arthur Taylor / MDL |
373 | | * |
374 | | * PURPOSE |
375 | | * Determine which numbered month it is given the day since the beginning of |
376 | | * the year, and the year since the beginning of the epoch. |
377 | | * |
378 | | * ARGUMENTS |
379 | | * day = Day since the beginning of the year. (Input) |
380 | | * year = Year since the beginning of the epoch. (Input) |
381 | | * |
382 | | * RETURNS: int (which month it is) |
383 | | * |
384 | | * HISTORY |
385 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
386 | | * 6/2004 AAT (MDL): Updated. |
387 | | * |
388 | | * NOTES |
389 | | ***************************************************************************** |
390 | | */ |
391 | | int Clock_MonthNum (int day, sInt4 year) |
392 | 104k | { |
393 | 104k | if (day < 31) |
394 | 31.1k | return 1; |
395 | 73.7k | if (ISLEAPYEAR (year)) |
396 | 21.5k | day -= 1; |
397 | 73.7k | if (day < 59) |
398 | 17.3k | return 2; |
399 | 56.3k | if (day <= 89) |
400 | 6.65k | return 3; |
401 | 49.7k | if (day == 242) |
402 | 322 | return 8; |
403 | 49.4k | return ((day + 64) * 5) / 153 - 1; |
404 | 49.7k | } |
405 | | |
406 | | /***************************************************************************** |
407 | | * Clock_NumDay() -- |
408 | | * |
409 | | * Arthur Taylor / MDL |
410 | | * |
411 | | * PURPOSE |
412 | | * Returns either the number of days in the month or the number of days |
413 | | * since the beginning of the year. |
414 | | * |
415 | | * ARGUMENTS |
416 | | * month = Month in question. (Input) |
417 | | * day = Day of month in question (Input) |
418 | | * year = years since the epoch (Input) |
419 | | * f_tot = 1 if we want total days from beginning of year, |
420 | | * 0 if we want total days in the month. (Input) |
421 | | * |
422 | | * RETURNS: int |
423 | | * Either the number of days in the month, or |
424 | | * the number of days since the beginning of they year. |
425 | | * |
426 | | * HISTORY |
427 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
428 | | * |
429 | | * NOTES |
430 | | ***************************************************************************** |
431 | | */ |
432 | | int Clock_NumDay (int month, int day, sInt4 year, char f_tot) |
433 | 1.43M | { |
434 | 1.43M | if (f_tot == 1) { |
435 | 757k | if (month > 2) { |
436 | 278k | if (ISLEAPYEAR (year)) { |
437 | 29.4k | return ((month + 1) * 153) / 5 - 63 + day; |
438 | 248k | } else { |
439 | 248k | return ((month + 1) * 153) / 5 - 64 + day; |
440 | 248k | } |
441 | 479k | } else { |
442 | 479k | return (month - 1) * 31 + day - 1; |
443 | 479k | } |
444 | 757k | } else { |
445 | 678k | if (month == 1) { |
446 | 333k | return 31; |
447 | 344k | } else if (month != 2) { |
448 | 221k | if ((((month - 3) % 5) % 2) == 1) { |
449 | 66.6k | return 30; |
450 | 155k | } else { |
451 | 155k | return 31; |
452 | 155k | } |
453 | 221k | } else { |
454 | 122k | if (ISLEAPYEAR (year)) { |
455 | 82.9k | return 29; |
456 | 82.9k | } else { |
457 | 40.0k | return 28; |
458 | 40.0k | } |
459 | 122k | } |
460 | 678k | } |
461 | 1.43M | } |
462 | | |
463 | | /***************************************************************************** |
464 | | * Clock_FormatParse() -- |
465 | | * |
466 | | * Arthur Taylor / MDL |
467 | | * |
468 | | * PURPOSE |
469 | | * To format part of the output clock string. |
470 | | * |
471 | | * ARGUMENTS |
472 | | * buffer = The output string to write to. (Output) |
473 | | * sec = Seconds since beginning of day. (Input) |
474 | | * floatSec = Part of a second since beginning of second. (Input) |
475 | | * totDay = Days since the beginning of the epoch. (Input) |
476 | | * year = Years since the beginning of the epoch (Input) |
477 | | * month = Month since the beginning of the year (Input) |
478 | | * day = Days since the beginning of the year (Input) |
479 | | * format = Which part of the format string we are working on. (Input) |
480 | | * |
481 | | * RETURNS: void |
482 | | * |
483 | | * HISTORY |
484 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
485 | | * 6/2004 AAT (MDL): Updated. |
486 | | * |
487 | | * NOTES |
488 | | ***************************************************************************** |
489 | | */ |
490 | 523k | #define SIZEOF_BUFFER 100 |
491 | | static void Clock_FormatParse (char buffer[SIZEOF_BUFFER], sInt4 sec, float floatSec, |
492 | | sInt4 totDay, sInt4 year, int month, int day, |
493 | | char format) |
494 | 523k | { |
495 | 523k | static const char * const MonthName[] = { |
496 | 523k | "January", "February", "March", "April", "May", "June", "July", |
497 | 523k | "August", "September", "October", "November", "December" |
498 | 523k | }; |
499 | 523k | static const char * const DayName[] = { |
500 | 523k | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", |
501 | 523k | "Saturday" |
502 | 523k | }; |
503 | 523k | int dy; /* # of days from start of year to start of month. */ |
504 | 523k | int i; /* Temporary variable to help with computations. */ |
505 | 523k | int DOM; /* Day of the Month (e.g., 1-31) */ |
506 | 523k | int DOW; /* Numeric day of the week (e.g., 0 = Sunday, 1 = |
507 | | * Monday, etc. */ |
508 | 523k | int monthStartDOW; /* Numeric day of the week of the 1st day of the |
509 | | * month */ |
510 | 523k | char temp[100]; /* Helps parse the %D, %T, %r, and %R options. */ |
511 | | |
512 | 523k | switch (format) { |
513 | 104k | case 'd': |
514 | 104k | dy = (Clock_NumDay (month, 1, year, 1) - 1); |
515 | 104k | snprintf(buffer, SIZEOF_BUFFER, "%02d", day - dy); |
516 | 104k | return; |
517 | 104k | case 'm': |
518 | 104k | snprintf(buffer, SIZEOF_BUFFER, "%02d", month); |
519 | 104k | return; |
520 | 0 | case 'E': |
521 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%2d", month); |
522 | 0 | return; |
523 | 104k | case 'Y': |
524 | 104k | snprintf(buffer, SIZEOF_BUFFER, "%04d", year); |
525 | 104k | return; |
526 | 104k | case 'H': |
527 | 104k | snprintf(buffer, SIZEOF_BUFFER, "%02d", (int) ((sec % 86400L) / 3600)); |
528 | 104k | return; |
529 | 0 | case 'G': |
530 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%2d", (int) ((sec % 86400L) / 3600)); |
531 | 0 | return; |
532 | 104k | case 'M': |
533 | 104k | snprintf(buffer, SIZEOF_BUFFER, "%02d", (int) ((sec % 3600) / 60)); |
534 | 104k | return; |
535 | 0 | case 'S': |
536 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%02d", (int) (sec % 60)); |
537 | 0 | return; |
538 | 0 | case 'f': |
539 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%05.2f", ((int) (sec % 60)) + floatSec); |
540 | 0 | return; |
541 | 0 | case 'n': |
542 | 0 | snprintf(buffer, SIZEOF_BUFFER, "\n"); |
543 | 0 | return; |
544 | 0 | case '%': |
545 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%%"); |
546 | 0 | return; |
547 | 0 | case 't': |
548 | 0 | snprintf(buffer, SIZEOF_BUFFER, "\t"); |
549 | 0 | return; |
550 | 0 | case 'y': |
551 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%02d", (int) (year % 100)); |
552 | 0 | return; |
553 | 0 | case 'I': |
554 | 0 | i = ((sec % 43200L) / 3600); |
555 | 0 | if (i == 0) { |
556 | 0 | snprintf(buffer, SIZEOF_BUFFER, "12"); |
557 | 0 | } else { |
558 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%02d", i); |
559 | 0 | } |
560 | 0 | return; |
561 | 0 | case 'p': |
562 | 0 | if (((sec % 86400L) / 3600) >= 12) { |
563 | 0 | snprintf(buffer, SIZEOF_BUFFER, "PM"); |
564 | 0 | } else { |
565 | 0 | snprintf(buffer, SIZEOF_BUFFER, "AM"); |
566 | 0 | } |
567 | 0 | return; |
568 | 0 | case 'B': |
569 | 0 | strcpy (buffer, MonthName[month - 1]); |
570 | 0 | return; |
571 | 0 | case 'A': |
572 | 0 | strcpy (buffer, DayName[(4 + totDay) % 7]); |
573 | 0 | return; |
574 | 0 | case 'b': |
575 | 0 | case 'h': |
576 | 0 | strcpy (buffer, MonthName[month - 1]); |
577 | 0 | buffer[3] = '\0'; |
578 | 0 | return; |
579 | 0 | case 'a': |
580 | 0 | strcpy (buffer, DayName[(4 + totDay) % 7]); |
581 | 0 | buffer[3] = '\0'; |
582 | 0 | return; |
583 | 0 | case 'w': |
584 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%d", (int) ((4 + totDay) % 7)); |
585 | 0 | return; |
586 | 0 | case 'j': |
587 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%03d", day + 1); |
588 | 0 | return; |
589 | 0 | case 'e': |
590 | 0 | dy = (Clock_NumDay (month, 1, year, 1) - 1); |
591 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%d", (int) (day - dy)); |
592 | 0 | return; |
593 | 0 | case 'W': |
594 | 0 | i = (1 - ((4 + totDay - day) % 7)) % 7; |
595 | 0 | if (day < i) |
596 | 0 | snprintf(buffer, SIZEOF_BUFFER, "00"); |
597 | 0 | else |
598 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%02d", ((day - i) / 7) + 1); |
599 | 0 | return; |
600 | 0 | case 'U': |
601 | 0 | i = (-((4 + totDay - day) % 7)) % 7; |
602 | 0 | if (day < i) |
603 | 0 | snprintf(buffer, SIZEOF_BUFFER, "00"); |
604 | 0 | else |
605 | 0 | snprintf(buffer, SIZEOF_BUFFER, "%02d", ((day - i) / 7) + 1); |
606 | 0 | return; |
607 | 0 | case 'D': |
608 | 0 | Clock_FormatParse (buffer, sec, floatSec, totDay, year, month, |
609 | 0 | day, 'm'); |
610 | 0 | strcat (buffer, "/"); |
611 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
612 | 0 | day, 'd'); |
613 | 0 | strcat (buffer, temp); |
614 | 0 | strcat (buffer, "/"); |
615 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
616 | 0 | day, 'Y'); |
617 | 0 | strcat (buffer, temp); |
618 | 0 | return; |
619 | 0 | case 'T': |
620 | 0 | Clock_FormatParse (buffer, sec, floatSec, totDay, year, month, |
621 | 0 | day, 'H'); |
622 | 0 | strcat (buffer, ":"); |
623 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
624 | 0 | day, 'M'); |
625 | 0 | strcat (buffer, temp); |
626 | 0 | strcat (buffer, ":"); |
627 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
628 | 0 | day, 'S'); |
629 | 0 | strcat (buffer, temp); |
630 | 0 | return; |
631 | 0 | case 'r': |
632 | 0 | Clock_FormatParse (buffer, sec, floatSec, totDay, year, month, |
633 | 0 | day, 'I'); |
634 | 0 | strcat (buffer, ":"); |
635 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
636 | 0 | day, 'M'); |
637 | 0 | strcat (buffer, temp); |
638 | 0 | strcat (buffer, ":"); |
639 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
640 | 0 | day, 'S'); |
641 | 0 | strcat (buffer, temp); |
642 | 0 | strcat (buffer, " "); |
643 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
644 | 0 | day, 'p'); |
645 | 0 | strcat (buffer, temp); |
646 | 0 | return; |
647 | 0 | case 'R': |
648 | 0 | Clock_FormatParse (buffer, sec, floatSec, totDay, year, month, |
649 | 0 | day, 'H'); |
650 | 0 | strcat (buffer, ":"); |
651 | 0 | Clock_FormatParse (temp, sec, floatSec, totDay, year, month, |
652 | 0 | day, 'M'); |
653 | 0 | strcat (buffer, temp); |
654 | 0 | return; |
655 | | |
656 | | /* If the current day is a federal holiday, then return a pointer to |
657 | | * the appropriate holiday string (e.g., "Martin Luther King Day") */ |
658 | 0 | case 'v': |
659 | | /* Clock_FormatParse 'd' */ |
660 | 0 | dy = (Clock_NumDay (month, 1, year, 1) - 1); |
661 | 0 | DOM = day - dy; |
662 | | /* Clock_FormatParse 'w' */ |
663 | 0 | DOW = (int) ((4 + totDay) % 7); |
664 | |
|
665 | 0 | if ((DOM % 7) != 1) { |
666 | 0 | monthStartDOW = DOW - ((DOM % 7) - 1); |
667 | 0 | if (monthStartDOW < 0) { |
668 | 0 | monthStartDOW = 7 + monthStartDOW; |
669 | 0 | } |
670 | 0 | } else { |
671 | 0 | monthStartDOW = DOW; |
672 | 0 | } |
673 | |
|
674 | 0 | Clock_Holiday (month, DOM, monthStartDOW, temp); |
675 | 0 | if (temp[0] != '\0') { |
676 | 0 | strcpy (buffer, temp); |
677 | 0 | } else { |
678 | 0 | Clock_FormatParse (buffer, sec, floatSec, totDay, year, month, |
679 | 0 | day, 'A'); |
680 | 0 | } |
681 | 0 | return; |
682 | 0 | default: |
683 | 0 | snprintf(buffer, SIZEOF_BUFFER, "unknown %c", format); |
684 | 0 | return; |
685 | 523k | } |
686 | 523k | } |
687 | | |
688 | | /***************************************************************************** |
689 | | * Clock_GetTimeZone() -- |
690 | | * |
691 | | * Arthur Taylor / MDL |
692 | | * |
693 | | * PURPOSE |
694 | | * Returns the time zone offset in hours to add to local time to get UTC. |
695 | | * So EST is +5 not -5. |
696 | | * |
697 | | * ARGUMENTS |
698 | | * |
699 | | * RETURNS: int |
700 | | * |
701 | | * HISTORY |
702 | | * 6/2004 Arthur Taylor (MDL): Created. |
703 | | * 3/2005 AAT: Found bug... Used to use 1/1/1970 00Z and find the local |
704 | | * hour. If CET, this means use 1969 date, which causes it to die. |
705 | | * Switched to 1/2/1970 00Z. |
706 | | * 3/2005 AAT: timeZone (see CET) can be < 0. don't add 24 if timeZone < 0 |
707 | | * |
708 | | * NOTES |
709 | | ***************************************************************************** |
710 | | */ |
711 | | sChar Clock_GetTimeZone () |
712 | 0 | { |
713 | 0 | struct tm l_time; |
714 | 0 | time_t ansTime; |
715 | 0 | static int timeZone = 9999; |
716 | |
|
717 | 0 | if (timeZone == 9999) { |
718 | | /* Cheap method of getting global time_zone variable. */ |
719 | 0 | memset (&l_time, 0, sizeof (struct tm)); |
720 | 0 | l_time.tm_year = 70; |
721 | 0 | l_time.tm_mday = 2; |
722 | 0 | ansTime = mktime (&l_time); |
723 | 0 | #if HAVE_GMTIME_R |
724 | 0 | struct tm gmTime; |
725 | 0 | const struct tm *gmTimePtr = gmtime_r(&ansTime, &gmTime); |
726 | | #elif defined(_WIN32) |
727 | | struct tm gmTime; |
728 | | const struct tm *gmTimePtr = gmtime_s(&gmTime, &ansTime) == 0 ? &gmTime : NULL; |
729 | | #else |
730 | | const struct tm *gmTimePtr = gmtime (&ansTime); |
731 | | #endif |
732 | 0 | timeZone = 0; |
733 | 0 | if (gmTimePtr) |
734 | 0 | { |
735 | 0 | timeZone = gmTimePtr->tm_hour; |
736 | 0 | if (gmTimePtr->tm_mday != 2) { |
737 | 0 | timeZone -= 24; |
738 | 0 | } |
739 | 0 | } |
740 | 0 | } |
741 | 0 | return timeZone; |
742 | 0 | } |
743 | | |
744 | | /***************************************************************************** |
745 | | * Clock_IsDaylightSaving() -- |
746 | | * |
747 | | * Arthur Taylor / MDL |
748 | | * |
749 | | * PURPOSE |
750 | | * To determine if daylight savings is in effect. Daylight savings is in |
751 | | * effect from the first sunday in April to the last sunday in October. |
752 | | * At 2 AM ST (or 3 AM DT) in April -> 3 AM DT (and we return 1) |
753 | | * At 2 AM DT (or 1 AM ST) in October -> 1 AM ST (and we return 0) |
754 | | * |
755 | | * ARGUMENTS |
756 | | * l_clock = The time stored as a double. (Input) |
757 | | * TimeZone = hours to add to local time to get UTC. (Input) |
758 | | * |
759 | | * RETURNS: int |
760 | | * 0 if not in daylight savings time. |
761 | | * 1 if in daylight savings time. |
762 | | * |
763 | | * HISTORY |
764 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
765 | | * 6/2004 AAT (MDL): Updated. |
766 | | * 2/2007 AAT : Updated yet again. |
767 | | * |
768 | | * NOTES |
769 | | * From 1987 through 2006, the start and end dates were the first Sunday in |
770 | | * April and the last Sunday in October. |
771 | | * |
772 | | * Since 1996 the European Union has observed DST from the last Sunday in |
773 | | * March to the last Sunday in October, with transitions at 01:00 UTC. |
774 | | * |
775 | | * On August 8, 2005, President George W. Bush signed the Energy Policy Act |
776 | | * of 2005. This Act changed the time change dates for Daylight Saving Time in |
777 | | * the U.S. Beginning in 2007, DST will begin on the second Sunday in March |
778 | | * and end the first Sunday in November. |
779 | | |
780 | | * The Secretary of Energy will report the impact of this change to |
781 | | * Congress. Congress retains the right to resume the 2005 Daylight Saving |
782 | | * Time schedule once the Department of Energy study is complete. |
783 | | * |
784 | | * 1st-apr last-oct 2nd-mar 1st-nov |
785 | | * 1/1/1995 Sun (0) 4/2 10/29 3/12 11/5 |
786 | | * 1/1/2001 mon (1) 4/1 10/28 3/11 11/4 |
787 | | * 1/1/1991 tue (2) 4/7 10/27 3/10 11/3 |
788 | | * 1/1/2003 Wed (3) 4/6 10/26 3/9 11/2 |
789 | | * 1/1/1987 thu (4) 4/5 10/25 3/8 11/1 |
790 | | * 1/1/1999 fri (5) 4/4 10/31 3/14 11/7 |
791 | | * 1/1/2005 Sat (6) 4/3 10/30 3/13 11/6 |
792 | | * |
793 | | * Leap years: |
794 | | * 1/1/2012 Sun (0) |
795 | | * 1/1/1996 Mon (1) 4/7 10/27 3/10 11/3 |
796 | | * 1/1/2008 Tue (2) 4/6 10/26 3/9 11/2 |
797 | | * 1/1/2020 Wed (3) 4/5 10/25 3/8 11/1 |
798 | | |
799 | | * 1/1/2004 Thu (4) 4/4 10/31 3/14 11/7 |
800 | | * 1/1/2032 Thu (4) 4/4 10/31 3/14 11/7 |
801 | | |
802 | | * 1/1/2016 Fri (5) |
803 | | * 1/1/2028 Sat (6) |
804 | | * --- Since there is an extra day, the delta is the same |
805 | | * --- Problems occur with leap years pre 2007 which start on Mon or Thur |
806 | | * (delta shift by 7 days = 604,800 seconds) After 2007, it was leap |
807 | | * years starting only on Thur. |
808 | | ***************************************************************************** |
809 | | */ |
810 | | int Clock_IsDaylightSaving2 (double l_clock, sChar TimeZone) |
811 | 0 | { |
812 | 0 | sInt4 totDay, year; |
813 | 0 | int day, first; |
814 | 0 | double secs; |
815 | 0 | sInt4 start, end; |
816 | | |
817 | | /* These are the deltas between the 1st sun in apr and beginning of year |
818 | | * in seconds + 2 hours. */ |
819 | 0 | static const sInt4 start2006[7] = {7869600, 7783200, 8301600, 8215200, |
820 | 0 | 8128800, 8042400, 7956000}; |
821 | | /* These are the deltas between the last sun in oct and beginning of year |
822 | | * in seconds + 1 hour. */ |
823 | 0 | static const sInt4 end2006[7] = {26010000, 25923600, 25837200, 25750800, |
824 | 0 | 25664400, 26182800, 26096400}; |
825 | | /* Previous version had typo ...26664400 -> 25664400 */ |
826 | | |
827 | | /* These are the deltas between the 2nd sun in mar and beginning of year |
828 | | * in seconds + 2 hours. */ |
829 | 0 | static const sInt4 start2007[7] = {6055200, 5968800, 5882400, 5796000, |
830 | 0 | 5709600, 6228000, 6141600}; |
831 | | /* These are the deltas between the 1st sun in nov and beginning of year |
832 | | * in seconds + 1 hour. */ |
833 | 0 | static const sInt4 end2007[7] = {26614800, 26528400, 26442000, 26355600, |
834 | 0 | 26269200, 26787600, 26701200}; |
835 | |
|
836 | 0 | l_clock = l_clock - TimeZone * 3600.; |
837 | | /* Clock should now be in Standard Time, so comparisons later have to be |
838 | | * based on Standard Time. */ |
839 | |
|
840 | 0 | totDay = (sInt4) floor (l_clock / SEC_DAY); |
841 | 0 | Clock_Epoch2YearDay (totDay, &day, &year); |
842 | | /* Figure out number of seconds since beginning of year. */ |
843 | 0 | secs = l_clock - (totDay - day) * SEC_DAY; |
844 | | |
845 | | /* figure out if 1/1/year is mon/tue/.../sun */ |
846 | 0 | first = ((4 + (totDay - day)) % 7); /* -day should get 1/1 but may need |
847 | | * -day+1 => sun == 0, ... sat == 6 */ |
848 | |
|
849 | 0 | if (year >= 2007) { |
850 | 0 | start = start2007[first]; |
851 | 0 | end = end2007[first]; |
852 | 0 | if (((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0))) { |
853 | 0 | if (first == 4) { |
854 | 0 | start += 604800; |
855 | 0 | end += 604800; |
856 | 0 | } |
857 | 0 | } |
858 | 0 | } else { |
859 | 0 | start = start2006[first]; |
860 | 0 | end = end2006[first]; |
861 | 0 | if (((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0))) { |
862 | 0 | if (first == 1) { |
863 | 0 | start += 604800; |
864 | 0 | } else if (first == 4) { |
865 | 0 | end += 604800; |
866 | 0 | } |
867 | 0 | } |
868 | 0 | } |
869 | 0 | if ((secs >= start) && (secs <= end)) { |
870 | 0 | return 1; |
871 | 0 | } else { |
872 | 0 | return 0; |
873 | 0 | } |
874 | 0 | } |
875 | | |
876 | | /***************************************************************************** |
877 | | * Clock_PrintDate() -- |
878 | | * |
879 | | * Arthur Taylor / MDL |
880 | | * |
881 | | * PURPOSE |
882 | | * |
883 | | * ARGUMENTS |
884 | | * l_clock = The time stored as a double. (Input) |
885 | | * year = The year. (Output) |
886 | | * month = The month. (Output) |
887 | | * day = The day. (Output) |
888 | | * hour = The hour. (Output) |
889 | | * min = The min. (Output) |
890 | | * sec = The second. (Output) |
891 | | * |
892 | | * RETURNS: void |
893 | | * |
894 | | * HISTORY |
895 | | * 3/2005 Arthur Taylor (MDL): Commented. |
896 | | * |
897 | | * NOTES |
898 | | ***************************************************************************** |
899 | | */ |
900 | | void Clock_PrintDate (double l_clock, sInt4 *year, int *month, int *day, |
901 | | int *hour, int *min, double *sec) |
902 | 0 | { |
903 | 0 | sInt4 totDay; |
904 | 0 | sInt4 intSec; |
905 | |
|
906 | 0 | totDay = (sInt4) floor (l_clock / SEC_DAY); |
907 | 0 | Clock_Epoch2YearDay (totDay, day, year); |
908 | 0 | *month = Clock_MonthNum (*day, *year); |
909 | 0 | *day = *day - Clock_NumDay (*month, 1, *year, 1) + 1; |
910 | 0 | *sec = l_clock - ((double) totDay) * SEC_DAY; |
911 | 0 | intSec = (sInt4) (*sec); |
912 | 0 | *hour = (int) ((intSec % 86400L) / 3600); |
913 | 0 | *min = (int) ((intSec % 3600) / 60); |
914 | 0 | *sec = (intSec % 60) + (*sec - intSec); |
915 | 0 | } |
916 | | |
917 | | /***************************************************************************** |
918 | | * Clock_Print() -- |
919 | | * |
920 | | * Arthur Taylor / MDL |
921 | | * |
922 | | * PURPOSE |
923 | | * To create formatted output from a time structure that is stored as a |
924 | | * double. |
925 | | * |
926 | | * ARGUMENTS |
927 | | * buffer = Destination to write the format to. (Output) |
928 | | * n = The number of characters in buffer. (Input) |
929 | | * l_clock = The time stored as a double. (Input) |
930 | | * format = The desired output format. (Input) |
931 | | * f_gmt = 0 output GMT, 1 output LDT, 2 output LST. (Input) |
932 | | * |
933 | | * RETURNS: void |
934 | | * |
935 | | * HISTORY |
936 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
937 | | * 6/2004 AAT (MDL): Updated. |
938 | | * |
939 | | * NOTES |
940 | | ***************************************************************************** |
941 | | */ |
942 | | void Clock_Print (char *buffer, int n, double l_clock, const char *format, |
943 | | char f_gmt) |
944 | 104k | { |
945 | 104k | sInt4 totDay, year; |
946 | 104k | sInt4 sec; |
947 | 104k | double floatSec; |
948 | 104k | int month, day; |
949 | 104k | size_t i; |
950 | 104k | int j; |
951 | 104k | char f_perc; |
952 | 104k | char locBuff[100]; |
953 | 104k | sChar timeZone; /* Hours to add to local time to get UTC. */ |
954 | | |
955 | | /* Handle gmt problems. */ |
956 | 104k | if (f_gmt != 0) { |
957 | 0 | timeZone = Clock_GetTimeZone (); |
958 | | /* l_clock is currently in UTC */ |
959 | 0 | l_clock -= timeZone * 3600; |
960 | | /* l_clock is now in local standard time Note: A 0 is passed to |
961 | | * DaylightSavings so it converts from local to local standard time. */ |
962 | 0 | if ((f_gmt == 1) && (Clock_IsDaylightSaving2 (l_clock, 0) == 1)) { |
963 | 0 | l_clock = l_clock + 3600; |
964 | 0 | } |
965 | 0 | } |
966 | | /* Convert from seconds to days and seconds. */ |
967 | 104k | totDay = (sInt4) floor (l_clock / SEC_DAY); |
968 | 104k | Clock_Epoch2YearDay (totDay, &day, &year); |
969 | 104k | month = Clock_MonthNum (day, year); |
970 | 104k | floatSec = l_clock - ((double) totDay) * SEC_DAY; |
971 | 104k | sec = (sInt4) floatSec; |
972 | 104k | floatSec = floatSec - sec; |
973 | | |
974 | 104k | f_perc = 0; |
975 | 104k | j = 0; |
976 | 1.15M | for (i = 0; i < strlen (format); i++) { |
977 | 1.04M | if (j >= n) |
978 | 0 | return; |
979 | 1.04M | if (format[i] == '%') { |
980 | 523k | f_perc = 1; |
981 | 523k | } else { |
982 | 523k | if (f_perc == 0) { |
983 | 0 | buffer[j] = format[i]; |
984 | 0 | j++; |
985 | 0 | buffer[j] = '\0'; |
986 | 523k | } else { |
987 | 523k | Clock_FormatParse (locBuff, sec, (float)floatSec, totDay, year, month, |
988 | 523k | day, format[i]); |
989 | 523k | buffer[j] = '\0'; |
990 | 523k | strncat (buffer, locBuff, n - j); |
991 | 523k | j += (int)strlen (locBuff); |
992 | 523k | f_perc = 0; |
993 | 523k | } |
994 | 523k | } |
995 | 1.04M | } |
996 | 104k | } |
997 | | |
998 | | /***************************************************************************** |
999 | | * Clock_Print2() -- |
1000 | | * |
1001 | | * Arthur Taylor / MDL |
1002 | | * |
1003 | | * PURPOSE |
1004 | | * To create formatted output from a time structure that is stored as a |
1005 | | * double. This is similar to Clock_Print, except it bases the timezone |
1006 | | * shift on what the user supplies rather than the system timezone, and |
1007 | | * accepts a flag that indicates whether to inquire about daylight savings. |
1008 | | * If f_dayCheck, then it looks at the local time and see's if daylight is |
1009 | | * in effect. This allows for points where daylight is never in effect |
1010 | | * (f_dayCheck = 0). |
1011 | | * |
1012 | | * ARGUMENTS |
1013 | | * buffer = Destination to write the format to. (Output) |
1014 | | * n = The number of characters in buffer. (Input) |
1015 | | * l_clock = The time stored as a double (assumed in UTC). (Input) |
1016 | | * format = The desired output format. (Input) |
1017 | | * timeZone = Hours to add to local time to get UTC. (Input) |
1018 | | * f_dayCheck = True if we should check if daylight savings is in effect, |
1019 | | * after converting to LST. (Input) |
1020 | | * |
1021 | | * RETURNS: void |
1022 | | * |
1023 | | * HISTORY |
1024 | | * 1/2006 Arthur Taylor (MDL/RSIS): Created. |
1025 | | * |
1026 | | * NOTES |
1027 | | ***************************************************************************** |
1028 | | */ |
1029 | | void Clock_Print2 (char *buffer, int n, double l_clock, char *format, |
1030 | | sChar timeZone, sChar f_dayCheck) |
1031 | 0 | { |
1032 | 0 | sInt4 totDay, year; |
1033 | 0 | sInt4 sec; |
1034 | 0 | double floatSec; |
1035 | 0 | int month, day; |
1036 | 0 | size_t i; |
1037 | 0 | int j; |
1038 | 0 | char f_perc; |
1039 | 0 | char locBuff[100]; |
1040 | | |
1041 | | /* l_clock is currently in UTC */ |
1042 | 0 | l_clock -= timeZone * 3600; |
1043 | | /* l_clock is now in local standard time */ |
1044 | 0 | if (f_dayCheck) { |
1045 | | /* Note: A 0 is passed to DaylightSavings so it converts from local to |
1046 | | * local standard time. */ |
1047 | 0 | if (Clock_IsDaylightSaving2 (l_clock, 0) == 1) { |
1048 | 0 | l_clock += 3600; |
1049 | 0 | } |
1050 | 0 | } |
1051 | | |
1052 | | /* Convert from seconds to days and seconds. */ |
1053 | 0 | totDay = (sInt4) floor (l_clock / SEC_DAY); |
1054 | 0 | Clock_Epoch2YearDay (totDay, &day, &year); |
1055 | 0 | month = Clock_MonthNum (day, year); |
1056 | 0 | floatSec = l_clock - ((double) totDay) * SEC_DAY; |
1057 | 0 | sec = (sInt4) floatSec; |
1058 | 0 | floatSec = floatSec - sec; |
1059 | |
|
1060 | 0 | f_perc = 0; |
1061 | 0 | j = 0; |
1062 | 0 | for (i = 0; i < strlen (format); i++) { |
1063 | 0 | if (j >= n) |
1064 | 0 | return; |
1065 | 0 | if (format[i] == '%') { |
1066 | 0 | f_perc = 1; |
1067 | 0 | } else { |
1068 | 0 | if (f_perc == 0) { |
1069 | 0 | buffer[j] = format[i]; |
1070 | 0 | j++; |
1071 | 0 | buffer[j] = '\0'; |
1072 | 0 | } else { |
1073 | 0 | Clock_FormatParse (locBuff, sec, (float)floatSec, totDay, year, month, |
1074 | 0 | day, format[i]); |
1075 | 0 | buffer[j] = '\0'; |
1076 | 0 | strncat (buffer, locBuff, n - j); |
1077 | 0 | j += (int)strlen (locBuff); |
1078 | 0 | f_perc = 0; |
1079 | 0 | } |
1080 | 0 | } |
1081 | 0 | } |
1082 | 0 | } |
1083 | | |
1084 | | /***************************************************************************** |
1085 | | * Clock_Clicks() -- |
1086 | | * |
1087 | | * Arthur Taylor / MDL |
1088 | | * |
1089 | | * PURPOSE |
1090 | | * Returns the number of clicks since the program started execution. |
1091 | | * |
1092 | | * ARGUMENTS |
1093 | | * |
1094 | | * RETURNS: double |
1095 | | * Number of clicks since the beginning of the program. |
1096 | | * |
1097 | | * HISTORY |
1098 | | * 6/2004 Arthur Taylor (MDL): Created. |
1099 | | * |
1100 | | * NOTES |
1101 | | ***************************************************************************** |
1102 | | */ |
1103 | | double Clock_Clicks (void) |
1104 | 0 | { |
1105 | 0 | double ans; |
1106 | |
|
1107 | 0 | ans = (double) clock (); |
1108 | 0 | return ans; |
1109 | 0 | } |
1110 | | |
1111 | | /***************************************************************************** |
1112 | | * Clock_Seconds() -- |
1113 | | * |
1114 | | * Arthur Taylor / MDL |
1115 | | * |
1116 | | * PURPOSE |
1117 | | * Returns the current number of seconds since the beginning of the epoch. |
1118 | | * Using the local system time zone. |
1119 | | * |
1120 | | * ARGUMENTS |
1121 | | * |
1122 | | * RETURNS: double |
1123 | | * Number of seconds since beginning of the epoch. |
1124 | | * |
1125 | | * HISTORY |
1126 | | * 6/2004 Arthur Taylor (MDL): Created. |
1127 | | * |
1128 | | * NOTES |
1129 | | ***************************************************************************** |
1130 | | */ |
1131 | | int Clock_SetSeconds (double *ptime, sChar f_set) |
1132 | 0 | { |
1133 | 0 | static double ans = 0; |
1134 | 0 | static int f_ansSet = 0; |
1135 | |
|
1136 | 0 | if (f_set) { |
1137 | 0 | ans = *ptime; |
1138 | 0 | f_ansSet = 1; |
1139 | 0 | } else if (f_ansSet) { |
1140 | 0 | *ptime = ans; |
1141 | 0 | } |
1142 | 0 | return f_ansSet; |
1143 | 0 | } |
1144 | | |
1145 | | double Clock_Seconds (void) |
1146 | 0 | { |
1147 | 0 | double ans; |
1148 | |
|
1149 | 0 | if (Clock_SetSeconds (&ans, 0) == 0) { |
1150 | 0 | ans = time (NULL); |
1151 | 0 | } |
1152 | 0 | return ans; |
1153 | 0 | } |
1154 | | |
1155 | | /***************************************************************************** |
1156 | | * Clock_PrintZone() -- |
1157 | | * |
1158 | | * Arthur Taylor / MDL |
1159 | | * |
1160 | | * PURPOSE |
1161 | | * Prints the time zone based on the shift from UTC and if it is daylight |
1162 | | * savings or not. |
1163 | | * |
1164 | | * ARGUMENTS |
1165 | | * ptr = The character string to scan. (Output) |
1166 | | * TimeZone = Hours to add to local time to get UTC. (Input) |
1167 | | * f_day = True if we are dealing with daylight savings. (Input) |
1168 | | * |
1169 | | * RETURNS: int |
1170 | | * 0 if we read TimeZone, -1 if not. |
1171 | | * |
1172 | | * HISTORY |
1173 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
1174 | | * 6/2004 AAT (MDL): Updated. |
1175 | | * |
1176 | | * NOTES |
1177 | | ***************************************************************************** |
1178 | | */ |
1179 | | int Clock_PrintZone2 (char *ptr, sChar TimeZone, char f_day) |
1180 | 0 | { |
1181 | 0 | if (TimeZone == 0) { |
1182 | 0 | strcpy (ptr, "UTC"); |
1183 | 0 | return 0; |
1184 | 0 | } else if (TimeZone == 5) { |
1185 | 0 | if (f_day) { |
1186 | 0 | strcpy (ptr, "EDT"); |
1187 | 0 | } else { |
1188 | 0 | strcpy (ptr, "EST"); |
1189 | 0 | } |
1190 | 0 | return 0; |
1191 | 0 | } else if (TimeZone == 6) { |
1192 | 0 | if (f_day) { |
1193 | 0 | strcpy (ptr, "CDT"); |
1194 | 0 | } else { |
1195 | 0 | strcpy (ptr, "CST"); |
1196 | 0 | } |
1197 | 0 | return 0; |
1198 | 0 | } else if (TimeZone == 7) { |
1199 | 0 | if (f_day) { |
1200 | 0 | strcpy (ptr, "MDT"); |
1201 | 0 | } else { |
1202 | 0 | strcpy (ptr, "MST"); |
1203 | 0 | } |
1204 | 0 | return 0; |
1205 | 0 | } else if (TimeZone == 8) { |
1206 | 0 | if (f_day) { |
1207 | 0 | strcpy (ptr, "PDT"); |
1208 | 0 | } else { |
1209 | 0 | strcpy (ptr, "PST"); |
1210 | 0 | } |
1211 | 0 | return 0; |
1212 | 0 | } else if (TimeZone == 9) { |
1213 | 0 | if (f_day) { |
1214 | 0 | strcpy (ptr, "YDT"); |
1215 | 0 | } else { |
1216 | 0 | strcpy (ptr, "YST"); |
1217 | 0 | } |
1218 | 0 | return 0; |
1219 | 0 | } |
1220 | 0 | ptr[0] = '\0'; |
1221 | 0 | return -1; |
1222 | 0 | } |
1223 | | |
1224 | | /***************************************************************************** |
1225 | | * Clock_ScanZone() -- |
1226 | | * |
1227 | | * Arthur Taylor / MDL |
1228 | | * |
1229 | | * PURPOSE |
1230 | | * Scans a character string to determine the timezone. |
1231 | | * |
1232 | | * ARGUMENTS |
1233 | | * ptr = The character string to scan. (Input) |
1234 | | * TimeZone = Hours to add to local time to get UTC. (Output) |
1235 | | * f_day = True if we are dealing with daylight savings. (Output) |
1236 | | * |
1237 | | * RETURNS: int |
1238 | | * 0 if we read TimeZone, -1 if not. |
1239 | | * |
1240 | | * HISTORY |
1241 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
1242 | | * 6/2004 AAT (MDL): Updated. |
1243 | | * |
1244 | | * NOTES |
1245 | | ***************************************************************************** |
1246 | | */ |
1247 | | int Clock_ScanZone2 (char *ptr, sChar *TimeZone, char *f_day) |
1248 | 0 | { |
1249 | 0 | switch (ptr[0]) { |
1250 | 0 | case 'G': |
1251 | 0 | if (strcmp (ptr, "GMT") == 0) { |
1252 | 0 | *f_day = 0; |
1253 | 0 | *TimeZone = 0; |
1254 | 0 | return 0; |
1255 | 0 | } |
1256 | 0 | return -1; |
1257 | 0 | case 'U': |
1258 | 0 | if (strcmp (ptr, "UTC") == 0) { |
1259 | 0 | *f_day = 0; |
1260 | 0 | *TimeZone = 0; |
1261 | 0 | return 0; |
1262 | 0 | } |
1263 | 0 | return -1; |
1264 | 0 | case 'E': |
1265 | 0 | if (strcmp (ptr, "EDT") == 0) { |
1266 | 0 | *f_day = 1; |
1267 | 0 | *TimeZone = 5; |
1268 | 0 | return 0; |
1269 | 0 | } else if (strcmp (ptr, "EST") == 0) { |
1270 | 0 | *f_day = 0; |
1271 | 0 | *TimeZone = 5; |
1272 | 0 | return 0; |
1273 | 0 | } |
1274 | 0 | return -1; |
1275 | 0 | case 'C': |
1276 | 0 | if (strcmp (ptr, "CDT") == 0) { |
1277 | 0 | *f_day = 1; |
1278 | 0 | *TimeZone = 6; |
1279 | 0 | return 0; |
1280 | 0 | } else if (strcmp (ptr, "CST") == 0) { |
1281 | 0 | *f_day = 0; |
1282 | 0 | *TimeZone = 6; |
1283 | 0 | return 0; |
1284 | 0 | } |
1285 | 0 | return -1; |
1286 | 0 | case 'M': |
1287 | 0 | if (strcmp (ptr, "MDT") == 0) { |
1288 | 0 | *f_day = 1; |
1289 | 0 | *TimeZone = 7; |
1290 | 0 | return 0; |
1291 | 0 | } else if (strcmp (ptr, "MST") == 0) { |
1292 | 0 | *f_day = 0; |
1293 | 0 | *TimeZone = 7; |
1294 | 0 | return 0; |
1295 | 0 | } |
1296 | 0 | return -1; |
1297 | 0 | case 'P': |
1298 | 0 | if (strcmp (ptr, "PDT") == 0) { |
1299 | 0 | *f_day = 1; |
1300 | 0 | *TimeZone = 8; |
1301 | 0 | return 0; |
1302 | 0 | } else if (strcmp (ptr, "PST") == 0) { |
1303 | 0 | *f_day = 0; |
1304 | 0 | *TimeZone = 8; |
1305 | 0 | return 0; |
1306 | 0 | } |
1307 | 0 | return -1; |
1308 | 0 | case 'Y': |
1309 | 0 | if (strcmp (ptr, "YDT") == 0) { |
1310 | 0 | *f_day = 1; |
1311 | 0 | *TimeZone = 9; |
1312 | 0 | return 0; |
1313 | 0 | } else if (strcmp (ptr, "YST") == 0) { |
1314 | 0 | *f_day = 0; |
1315 | 0 | *TimeZone = 9; |
1316 | 0 | return 0; |
1317 | 0 | } |
1318 | 0 | return -1; |
1319 | 0 | case 'Z': |
1320 | 0 | if (strcmp (ptr, "Z") == 0) { |
1321 | 0 | *f_day = 0; |
1322 | 0 | *TimeZone = 0; |
1323 | 0 | return 0; |
1324 | 0 | } |
1325 | 0 | return -1; |
1326 | 0 | } |
1327 | 0 | return -1; |
1328 | 0 | } |
1329 | | |
1330 | | /***************************************************************************** |
1331 | | * Clock_ScanMonth() -- |
1332 | | * |
1333 | | * Arthur Taylor / MDL |
1334 | | * |
1335 | | * PURPOSE |
1336 | | * Scans a string looking for a month word. Assumes string is all caps. |
1337 | | * |
1338 | | * ARGUMENTS |
1339 | | * ptr = The character string to scan. (Input) |
1340 | | * |
1341 | | * RETURNS: int |
1342 | | * Returns the month number read, or -1 if no month word seen. |
1343 | | * |
1344 | | * HISTORY |
1345 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
1346 | | * 6/2004 AAT (MDL): Updated. |
1347 | | * |
1348 | | * NOTES |
1349 | | ***************************************************************************** |
1350 | | */ |
1351 | | int Clock_ScanMonth (char *ptr) |
1352 | 0 | { |
1353 | 0 | switch (*ptr) { |
1354 | 0 | case 'A': |
1355 | 0 | if ((strcmp (ptr, "APR") == 0) || (strcmp (ptr, "APRIL") == 0)) |
1356 | 0 | return 4; |
1357 | 0 | else if ((strcmp (ptr, "AUG") == 0) || (strcmp (ptr, "AUGUST") == 0)) |
1358 | 0 | return 8; |
1359 | 0 | return -1; |
1360 | 0 | case 'D': |
1361 | 0 | if ((strcmp (ptr, "DEC") == 0) || (strcmp (ptr, "DECEMBER") == 0)) |
1362 | 0 | return 12; |
1363 | 0 | return -1; |
1364 | 0 | case 'F': |
1365 | 0 | if ((strcmp (ptr, "FEB") == 0) || (strcmp (ptr, "FEBRUARY") == 0)) |
1366 | 0 | return 2; |
1367 | 0 | return -1; |
1368 | 0 | case 'J': |
1369 | 0 | if ((strcmp (ptr, "JAN") == 0) || (strcmp (ptr, "JANUARY") == 0)) |
1370 | 0 | return 1; |
1371 | 0 | else if ((strcmp (ptr, "JUN") == 0) || (strcmp (ptr, "JUNE") == 0)) |
1372 | 0 | return 6; |
1373 | 0 | else if ((strcmp (ptr, "JUL") == 0) || (strcmp (ptr, "JULY") == 0)) |
1374 | 0 | return 7; |
1375 | 0 | return -1; |
1376 | 0 | case 'M': |
1377 | 0 | if ((strcmp (ptr, "MAR") == 0) || (strcmp (ptr, "MARCH") == 0)) |
1378 | 0 | return 3; |
1379 | 0 | else if (strcmp (ptr, "MAY") == 0) |
1380 | 0 | return 5; |
1381 | 0 | return -1; |
1382 | 0 | case 'N': |
1383 | 0 | if ((strcmp (ptr, "NOV") == 0) || (strcmp (ptr, "NOVEMBER") == 0)) |
1384 | 0 | return 11; |
1385 | 0 | return -1; |
1386 | 0 | case 'O': |
1387 | 0 | if ((strcmp (ptr, "OCT") == 0) || (strcmp (ptr, "OCTOBER") == 0)) |
1388 | 0 | return 10; |
1389 | 0 | return -1; |
1390 | 0 | case 'S': |
1391 | 0 | if ((strcmp (ptr, "SEP") == 0) || (strcmp (ptr, "SEPTEMBER") == 0)) |
1392 | 0 | return 9; |
1393 | 0 | return -1; |
1394 | 0 | } |
1395 | 0 | return -1; |
1396 | 0 | } |
1397 | | |
1398 | | /***************************************************************************** |
1399 | | * Clock_PrintMonth3() -- |
1400 | | * |
1401 | | * Arthur Taylor / MDL |
1402 | | * |
1403 | | * PURPOSE |
1404 | | * |
1405 | | * ARGUMENTS |
1406 | | * |
1407 | | * RETURNS: void |
1408 | | * |
1409 | | * HISTORY |
1410 | | * 3/2005 Arthur Taylor (MDL/RSIS): Commented. |
1411 | | * |
1412 | | * NOTES |
1413 | | ***************************************************************************** |
1414 | | */ |
1415 | | void Clock_PrintMonth3 (int mon, char *buffer, CPL_UNUSED int buffLen) |
1416 | 0 | { |
1417 | 0 | static const char * const MonthName[] = { |
1418 | 0 | "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", |
1419 | 0 | "NOV", "DEC" |
1420 | 0 | }; |
1421 | 0 | myAssert ((mon > 0) && (mon < 13)); |
1422 | 0 | myAssert (buffLen > 3); |
1423 | 0 | strcpy (buffer, MonthName[mon - 1]); |
1424 | 0 | } |
1425 | | |
1426 | | /***************************************************************************** |
1427 | | * Clock_PrintMonth() -- |
1428 | | * |
1429 | | * Arthur Taylor / MDL |
1430 | | * |
1431 | | * PURPOSE |
1432 | | * |
1433 | | * ARGUMENTS |
1434 | | * |
1435 | | * RETURNS: void |
1436 | | * |
1437 | | * HISTORY |
1438 | | * 3/2005 Arthur Taylor (MDL/RSIS): Commented. |
1439 | | * |
1440 | | * NOTES |
1441 | | ***************************************************************************** |
1442 | | */ |
1443 | | void Clock_PrintMonth (int mon, char *buffer, CPL_UNUSED int buffLen) |
1444 | 0 | { |
1445 | 0 | static const char * const MonthName[] = { |
1446 | 0 | "January", "February", "March", "April", "May", "June", "July", |
1447 | 0 | "August", "September", "October", "November", "December" |
1448 | 0 | }; |
1449 | 0 | myAssert ((mon > 0) && (mon < 13)); |
1450 | 0 | myAssert (buffLen > 9); |
1451 | 0 | strcpy (buffer, MonthName[mon - 1]); |
1452 | 0 | } |
1453 | | |
1454 | | /***************************************************************************** |
1455 | | * Clock_ScanWeekday() -- |
1456 | | * |
1457 | | * Arthur Taylor / MDL |
1458 | | * |
1459 | | * PURPOSE |
1460 | | * Scans a string looking for a day word. Assumes string is all caps. |
1461 | | * |
1462 | | * ARGUMENTS |
1463 | | * ptr = The character string to scan. (Input) |
1464 | | * |
1465 | | * RETURNS: int |
1466 | | * Returns the day number read, or -1 if no day word seen. |
1467 | | * |
1468 | | * HISTORY |
1469 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
1470 | | * 6/2004 AAT (MDL): Updated. |
1471 | | * |
1472 | | * NOTES |
1473 | | ***************************************************************************** |
1474 | | */ |
1475 | | |
1476 | | #ifdef unused_by_GDAL |
1477 | | static int Clock_ScanWeekday (char *ptr) |
1478 | | { |
1479 | | switch (*ptr) { |
1480 | | case 'S': |
1481 | | if ((strcmp (ptr, "SUN") == 0) || (strcmp (ptr, "SUNDAY") == 0)) |
1482 | | return 0; |
1483 | | else if ((strcmp (ptr, "SAT") == 0) || |
1484 | | (strcmp (ptr, "SATURDAY") == 0)) |
1485 | | return 6; |
1486 | | return -1; |
1487 | | case 'M': |
1488 | | if ((strcmp (ptr, "MON") == 0) || (strcmp (ptr, "MONDAY") == 0)) |
1489 | | return 1; |
1490 | | return -1; |
1491 | | case 'T': |
1492 | | if ((strcmp (ptr, "TUE") == 0) || (strcmp (ptr, "TUESDAY") == 0)) |
1493 | | return 2; |
1494 | | else if ((strcmp (ptr, "THU") == 0) || |
1495 | | (strcmp (ptr, "THURSDAY") == 0)) |
1496 | | return 4; |
1497 | | return -1; |
1498 | | case 'W': |
1499 | | if ((strcmp (ptr, "WED") == 0) || (strcmp (ptr, "WEDNESDAY") == 0)) |
1500 | | return 3; |
1501 | | return -1; |
1502 | | case 'F': |
1503 | | if ((strcmp (ptr, "FRI") == 0) || (strcmp (ptr, "FRIDAY") == 0)) |
1504 | | return 5; |
1505 | | return -1; |
1506 | | } |
1507 | | return -1; |
1508 | | } |
1509 | | |
1510 | | /***************************************************************************** |
1511 | | * Clock_ScanColon() -- |
1512 | | * |
1513 | | * Arthur Taylor / MDL |
1514 | | * |
1515 | | * PURPOSE |
1516 | | * Parses a word assuming it is : separated and is dealing with |
1517 | | * hours:minutes:seconds or hours:minutes. Returns the resulting time as |
1518 | | * a double. |
1519 | | * |
1520 | | * ARGUMENTS |
1521 | | * ptr = The character string to scan. (Input) |
1522 | | * |
1523 | | * RETURNS: double |
1524 | | * The time after converting the : separated string. |
1525 | | * |
1526 | | * HISTORY |
1527 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
1528 | | * 6/2004 AAT (MDL): Updated. |
1529 | | * |
1530 | | * NOTES |
1531 | | ***************************************************************************** |
1532 | | */ |
1533 | | |
1534 | | static double Clock_ScanColon (char *ptr) |
1535 | | { |
1536 | | sInt4 hour, min; |
1537 | | double sec; |
1538 | | char *ptr3; |
1539 | | |
1540 | | ptr3 = strchr (ptr, ':'); |
1541 | | if( !ptr3 ) return 0; |
1542 | | *ptr3 = '\0'; |
1543 | | hour = atoi (ptr); |
1544 | | *ptr3 = ':'; |
1545 | | ptr = ptr3 + 1; |
1546 | | /* Check for second :, other wise it is hh:mm */ |
1547 | | if ((ptr3 = strchr (ptr, ':')) == NULL) { |
1548 | | min = atoi (ptr); |
1549 | | sec = 0; |
1550 | | } else { |
1551 | | *ptr3 = '\0'; |
1552 | | min = atoi (ptr); |
1553 | | *ptr3 = ':'; |
1554 | | ptr = ptr3 + 1; |
1555 | | sec = atof (ptr); |
1556 | | } |
1557 | | return (sec + 60 * min + 3600 * hour); |
1558 | | } |
1559 | | |
1560 | | /***************************************************************************** |
1561 | | * Clock_ScanSlash() -- |
1562 | | * |
1563 | | * Arthur Taylor / MDL |
1564 | | * |
1565 | | * PURPOSE |
1566 | | * Parses a word assuming it is / separated and is dealing with |
1567 | | * months/days/years or months/days. |
1568 | | * |
1569 | | * ARGUMENTS |
1570 | | * word = The character string to scan. (Input) |
1571 | | * mon = The month that was seen. (Output) |
1572 | | * day = The day that was seen. (Output) |
1573 | | * year = The year that was seen. (Output) |
1574 | | * f_year = True if the year is valid. (Output) |
1575 | | * |
1576 | | * RETURNS: int |
1577 | | * -1 if mon or day is out of range. |
1578 | | * 0 if no problems. |
1579 | | * |
1580 | | * HISTORY |
1581 | | * 9/2002 Arthur Taylor (MDL/RSIS): Created. |
1582 | | * 6/2004 AAT (MDL): Updated. |
1583 | | * |
1584 | | * NOTES |
1585 | | ***************************************************************************** |
1586 | | */ |
1587 | | |
1588 | | static int Clock_ScanSlash (char *word, int *mon, int *day, sInt4 *year, |
1589 | | char *f_year) |
1590 | | { |
1591 | | char *ptr3; |
1592 | | char *ptr = word; |
1593 | | |
1594 | | ptr3 = strchr (ptr, '/'); |
1595 | | if( !ptr3 ) return -1; |
1596 | | *ptr3 = '\0'; |
1597 | | *mon = atoi (ptr); |
1598 | | *ptr3 = '/'; |
1599 | | ptr = ptr3 + 1; |
1600 | | /* Check for second /, other wise it is mm/dd */ |
1601 | | if ((ptr3 = strchr (ptr, '/')) == NULL) { |
1602 | | *day = atoi (ptr); |
1603 | | *year = 1970; |
1604 | | *f_year = 0; |
1605 | | } else { |
1606 | | *ptr3 = '\0'; |
1607 | | *day = atoi (ptr); |
1608 | | *ptr3 = '/'; |
1609 | | ptr = ptr3 + 1; |
1610 | | *year = atoi (ptr); |
1611 | | *f_year = 1; |
1612 | | } |
1613 | | if ((*mon < 1) || (*mon > 12) || (*day < 1) || (*day > 31)) { |
1614 | | printf ("Errors parsing %s\n", word); |
1615 | | return -1; |
1616 | | } |
1617 | | return 0; |
1618 | | } |
1619 | | |
1620 | | /* http://www.w3.org/TR/NOTE-datetime |
1621 | | Year and month: |
1622 | | YYYY-MM (eg 1997-07) |
1623 | | Complete date: |
1624 | | YYYY-MM-DD (eg 1997-07-16) |
1625 | | Complete date plus hours and minutes: |
1626 | | YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00) |
1627 | | Complete date plus hours, minutes and seconds: |
1628 | | YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00) |
1629 | | Complete date plus hours, minutes, seconds and a decimal fraction of a |
1630 | | second |
1631 | | YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00) |
1632 | | |
1633 | | Example: |
1634 | | 1994-11-05T08:15:30-05:00 corresponds to November 5, 1994, 8:15:30 am, |
1635 | | US Eastern Standard Time. |
1636 | | 1994-11-05T13:15:30Z corresponds to the same instant. |
1637 | | */ |
1638 | | |
1639 | | static int Clock_ScanDash (char *word, int *mon, int *day, sInt4 *year, |
1640 | | double *ptime, char *f_time) |
1641 | | { |
1642 | | char *ptr3; |
1643 | | char *ptr = word; |
1644 | | sInt4 hour, min; |
1645 | | double sec; |
1646 | | char temp; |
1647 | | sInt4 offset; |
1648 | | |
1649 | | ptr3 = strchr (ptr, '-'); |
1650 | | if( !ptr3 ) return -1; |
1651 | | *ptr3 = '\0'; |
1652 | | *year = atoi (ptr); |
1653 | | *ptr3 = '-'; |
1654 | | ptr = ptr3 + 1; |
1655 | | /* Check for second -, other wise it is yyyy-mm */ |
1656 | | if ((ptr3 = strchr (ptr, '-')) == NULL) { |
1657 | | /* Don't touch time or f_time */ |
1658 | | *mon = atoi (ptr); |
1659 | | *day = 1; |
1660 | | if ((*mon < 1) || (*mon > 12)) { |
1661 | | printf ("Errors parsing %s\n", word); |
1662 | | return -1; |
1663 | | } |
1664 | | return 0; |
1665 | | } |
1666 | | *ptr3 = '\0'; |
1667 | | *mon = atoi (ptr); |
1668 | | *ptr3 = '-'; |
1669 | | ptr = ptr3 + 1; |
1670 | | if ((ptr3 = strchr (ptr, 'T')) == NULL) { |
1671 | | /* Don't touch time or f_time */ |
1672 | | *day = atoi (ptr); |
1673 | | if ((*mon < 1) || (*mon > 12) || (*day < 1) || (*day > 31)) { |
1674 | | printf ("Errors parsing %s\n", word); |
1675 | | return -1; |
1676 | | } |
1677 | | return 0; |
1678 | | } |
1679 | | *ptr3 = '\0'; |
1680 | | *day = atoi (ptr); |
1681 | | *ptr3 = 'T'; |
1682 | | ptr = ptr3 + 1; |
1683 | | /* hh:mmTZD */ |
1684 | | /* hh:mm:ssTZD */ |
1685 | | /* hh:mm:ss.sTZD */ |
1686 | | if (strlen (ptr) < 5) { |
1687 | | printf ("Errors parsing %s\n", word); |
1688 | | return -1; |
1689 | | } |
1690 | | ptr[2] = '\0'; |
1691 | | hour = atoi (ptr); |
1692 | | ptr[2] = ':'; |
1693 | | ptr += 3; |
1694 | | offset = 0; |
1695 | | sec = 0; |
1696 | | if (strlen (ptr) == 2) { |
1697 | | min = atoi (ptr); |
1698 | | } else { |
1699 | | temp = ptr[2]; |
1700 | | ptr[2] = '\0'; |
1701 | | min = atoi (ptr); |
1702 | | ptr[2] = temp; |
1703 | | if (temp == ':') { |
1704 | | ptr += 3; |
1705 | | if ((ptr3 = strchr (ptr, '+')) == NULL) { |
1706 | | if ((ptr3 = strchr (ptr, '-')) == NULL) { |
1707 | | ptr3 = strchr (ptr, 'Z'); |
1708 | | } |
1709 | | } |
1710 | | if (ptr3 == NULL) { |
1711 | | sec = atof (ptr); |
1712 | | } else { |
1713 | | temp = *ptr3; |
1714 | | *ptr3 = '\0'; |
1715 | | sec = atof (ptr); |
1716 | | *ptr3 = temp; |
1717 | | if (temp != 'Z') { |
1718 | | ptr = ptr3; |
1719 | | ptr[3] = '\0'; |
1720 | | offset = atoi (ptr) * 3600; |
1721 | | ptr[3] = ':'; |
1722 | | ptr += 4; |
1723 | | offset += atoi (ptr) * 60; |
1724 | | } |
1725 | | } |
1726 | | } else if (temp != 'Z') { |
1727 | | ptr += 2; |
1728 | | ptr[3] = '\0'; |
1729 | | offset = atoi (ptr) * 3600; |
1730 | | ptr[3] = ':'; |
1731 | | ptr += 4; |
1732 | | offset += atoi (ptr) * 60; |
1733 | | } |
1734 | | } |
1735 | | *f_time = 1; |
1736 | | *ptime = sec + min * 60 + hour * 3600 - offset; |
1737 | | return 0; |
1738 | | } |
1739 | | #endif // unused_by_GDAL |
1740 | | |
1741 | | /***************************************************************************** |
1742 | | * Clock_ScanDate() -- |
1743 | | * |
1744 | | * Arthur Taylor / MDL |
1745 | | * |
1746 | | * PURPOSE |
1747 | | * |
1748 | | * ARGUMENTS |
1749 | | * |
1750 | | * RETURNS: void |
1751 | | * |
1752 | | * HISTORY |
1753 | | * 3/2005 Arthur Taylor (MDL/RSIS): Commented. |
1754 | | * |
1755 | | * NOTES |
1756 | | ***************************************************************************** |
1757 | | */ |
1758 | | /* prj::slosh prj::stm2trk and prj::degrib use this with l_clock zero'ed |
1759 | | out, so I have now made sure l_clock is zero'ed. */ |
1760 | | void Clock_ScanDate (double *l_clock, sInt4 year, int mon, int day) |
1761 | 829k | { |
1762 | 829k | int i; |
1763 | 829k | sInt4 delt, temp, totDay; |
1764 | | |
1765 | | /* Makes sure l_clock is zero'ed out. */ |
1766 | 829k | *l_clock = 0; |
1767 | | |
1768 | 829k | if ((mon < 1) || (mon > 12) || (day < 0) || (day > 31)) |
1769 | 74.1k | return; |
1770 | 755k | if( year < -10000 || year > 10000 ) |
1771 | 77.1k | return; |
1772 | 678k | totDay = Clock_NumDay (mon, day, year, 0); |
1773 | 678k | if (day > totDay) |
1774 | 25.0k | return; |
1775 | 652k | totDay = Clock_NumDay (mon, day, year, 1); |
1776 | 652k | temp = 1970; |
1777 | 652k | delt = year - temp; |
1778 | 652k | if ((delt >= 400) || (delt <= -400)) { |
1779 | 128k | i = (delt / 400); |
1780 | 128k | temp += 400 * i; |
1781 | 128k | totDay += 146097L * i; |
1782 | 128k | } |
1783 | 652k | if (temp < year) { |
1784 | 12.9M | while (temp < year) { |
1785 | 12.6M | if (((temp % 4) == 0) && |
1786 | 12.6M | (((temp % 100) != 0) || ((temp % 400) == 0))) { |
1787 | 10.6M | if ((temp + 4) < year) { |
1788 | 10.2M | totDay += 1461; |
1789 | 10.2M | temp += 4; |
1790 | 10.2M | } else if ((temp + 3) < year) { |
1791 | 134k | totDay += 1096; |
1792 | 134k | temp += 3; |
1793 | 214k | } else if ((temp + 2) < year) { |
1794 | 98.6k | totDay += 731; |
1795 | 98.6k | temp += 2; |
1796 | 115k | } else { |
1797 | 115k | totDay += 366; |
1798 | 115k | temp++; |
1799 | 115k | } |
1800 | 10.6M | } else { |
1801 | 2.01M | totDay += 365; |
1802 | 2.01M | temp++; |
1803 | 2.01M | } |
1804 | 12.6M | } |
1805 | 364k | } else if (temp > year) { |
1806 | 3.37M | while (temp > year) { |
1807 | 3.11M | temp--; |
1808 | 3.11M | if (((temp % 4) == 0) && |
1809 | 3.11M | (((temp % 100) != 0) || ((temp % 400) == 0))) { |
1810 | 2.61M | if (year < temp - 3) { |
1811 | 2.35M | totDay -= 1461; |
1812 | 2.35M | temp -= 3; |
1813 | 2.35M | } else if (year < (temp - 2)) { |
1814 | 58.8k | totDay -= 1096; |
1815 | 58.8k | temp -= 2; |
1816 | 196k | } else if (year < (temp - 1)) { |
1817 | 112k | totDay -= 731; |
1818 | 112k | temp--; |
1819 | 112k | } else { |
1820 | 84.8k | totDay -= 366; |
1821 | 84.8k | } |
1822 | 2.61M | } else { |
1823 | 503k | totDay -= 365; |
1824 | 503k | } |
1825 | 3.11M | } |
1826 | 258k | } |
1827 | 652k | *l_clock = *l_clock + ((double) (totDay)) * 24 * 3600; |
1828 | 652k | } |
1829 | | |
1830 | | #ifdef unused_by_GDAL |
1831 | | |
1832 | | int Clock_ScanDateNumber (double *l_clock, char *buffer) |
1833 | | { |
1834 | | int buffLen = (int)strlen (buffer); |
1835 | | sInt4 year; |
1836 | | int mon = 1; |
1837 | | int day = 1; |
1838 | | int hour = 0; |
1839 | | int min = 0; |
1840 | | int sec = 0; |
1841 | | char c_temp; |
1842 | | |
1843 | | *l_clock = 0; |
1844 | | if ((buffLen != 4) && (buffLen != 6) && (buffLen != 8) && |
1845 | | (buffLen != 10) && (buffLen != 12) && (buffLen != 14)) { |
1846 | | return 1; |
1847 | | } |
1848 | | c_temp = buffer[4]; |
1849 | | buffer[4] = '\0'; |
1850 | | year = atoi (buffer); |
1851 | | buffer[4] = c_temp; |
1852 | | if (buffLen > 4) { |
1853 | | c_temp = buffer[6]; |
1854 | | buffer[6] = '\0'; |
1855 | | mon = atoi (buffer + 4); |
1856 | | buffer[6] = c_temp; |
1857 | | } |
1858 | | if (buffLen > 6) { |
1859 | | c_temp = buffer[8]; |
1860 | | buffer[8] = '\0'; |
1861 | | day = atoi (buffer + 6); |
1862 | | buffer[8] = c_temp; |
1863 | | } |
1864 | | if (buffLen > 8) { |
1865 | | c_temp = buffer[10]; |
1866 | | buffer[10] = '\0'; |
1867 | | hour = atoi (buffer + 8); |
1868 | | buffer[10] = c_temp; |
1869 | | } |
1870 | | if (buffLen > 10) { |
1871 | | c_temp = buffer[12]; |
1872 | | buffer[12] = '\0'; |
1873 | | min = atoi (buffer + 10); |
1874 | | buffer[12] = c_temp; |
1875 | | } |
1876 | | if (buffLen > 12) { |
1877 | | c_temp = buffer[14]; |
1878 | | buffer[14] = '\0'; |
1879 | | sec = atoi (buffer + 12); |
1880 | | buffer[14] = c_temp; |
1881 | | } |
1882 | | Clock_ScanDate (l_clock, year, mon, day); |
1883 | | *l_clock = *l_clock + sec + min * 60 + hour * 3600; |
1884 | | return 0; |
1885 | | } |
1886 | | |
1887 | | void Clock_PrintDateNumber (double l_clock, char buffer[15]) |
1888 | | { |
1889 | | sInt4 year; |
1890 | | int month, day, hour, min, sec; |
1891 | | double d_sec; |
1892 | | |
1893 | | Clock_PrintDate (l_clock, &year, &month, &day, &hour, &min, &d_sec); |
1894 | | sec = (int) d_sec; |
1895 | | snprintf(buffer, 15, "%04d%02d%02d%02d%02d%02d", year, month, day, hour, min, |
1896 | | sec); |
1897 | | } |
1898 | | |
1899 | | /* Word_types: none, ':' word, '/' word, '-' word, integer word, 'AM'/'PM' |
1900 | | * word, timeZone word, month word, weekDay word, Preceeder to a relativeDate |
1901 | | * word, Postceeder to a relativeDate word, relativeDate word unit, Adjust Day |
1902 | | * word |
1903 | | */ |
1904 | | enum { |
1905 | | WT_NONE, WT_COLON, WT_SLASH, WT_DASH, WT_INTEGER, WT_AMPM, WT_TIMEZONE, |
1906 | | WT_MONTH, WT_DAY, WT_PRE_RELATIVE, WT_POST_RELATIVE, WT_RELATIVE_UNIT, |
1907 | | WT_ADJDAY |
1908 | | }; |
1909 | | |
1910 | | /***************************************************************************** |
1911 | | * Clock_GetWord() -- |
1912 | | * |
1913 | | * Arthur Taylor / MDL |
1914 | | * |
1915 | | * PURPOSE |
1916 | | * |
1917 | | * ARGUMENTS |
1918 | | * |
1919 | | * RETURNS: void |
1920 | | * |
1921 | | * HISTORY |
1922 | | * 3/2005 Arthur Taylor (MDL/RSIS): Commented. |
1923 | | * |
1924 | | * NOTES |
1925 | | ***************************************************************************** |
1926 | | */ |
1927 | | /* Start at *Start. Advance Start until it is at first non-space, |
1928 | | * non-',' non-'.' character. Move End to first space, ',' or '.' after |
1929 | | * new Start location. Copy up to 30 characters (in caps) into word. */ |
1930 | | /* return -1 if no next word, 0 otherwise */ |
1931 | | |
1932 | | static int Clock_GetWord (char **Start, char **End, char word[30], |
1933 | | int *wordType) |
1934 | | { |
1935 | | char *ptr; |
1936 | | int cnt; |
1937 | | int f_integer; |
1938 | | |
1939 | | *wordType = WT_NONE; |
1940 | | if (*Start == NULL) { |
1941 | | return -1; |
1942 | | } |
1943 | | ptr = *Start; |
1944 | | /* Find start of next word (first non-space non-',' non-'.' char.) */ |
1945 | | while ((*ptr == ' ') || (*ptr == ',') || (*ptr == '.')) { |
1946 | | ptr++; |
1947 | | } |
1948 | | /* There is no next word. */ |
1949 | | if (*ptr == '\0') { |
1950 | | return -1; |
1951 | | } |
1952 | | *Start = ptr; |
1953 | | /* Find end of next word. */ |
1954 | | cnt = 0; |
1955 | | f_integer = 1; |
1956 | | while ((*ptr != ' ') && (*ptr != ',') && (*ptr != '\0')) { |
1957 | | if (cnt < 29) { |
1958 | | word[cnt] = (char) toupper ((unsigned char)*ptr); |
1959 | | cnt++; |
1960 | | } |
1961 | | if (*ptr == ':') { |
1962 | | if (*wordType == WT_NONE) |
1963 | | *wordType = WT_COLON; |
1964 | | f_integer = 0; |
1965 | | } else if (*ptr == '/') { |
1966 | | if (*wordType == WT_NONE) |
1967 | | *wordType = WT_SLASH; |
1968 | | f_integer = 0; |
1969 | | } else if (*ptr == '-') { |
1970 | | if (ptr != *Start) { |
1971 | | if (*wordType == WT_NONE) |
1972 | | *wordType = WT_DASH; |
1973 | | f_integer = 0; |
1974 | | } |
1975 | | } else if (*ptr == '.') { |
1976 | | if (!isdigit ((unsigned char)*(ptr + 1))) { |
1977 | | break; |
1978 | | } else { |
1979 | | f_integer = 0; |
1980 | | } |
1981 | | } else if (!isdigit ((unsigned char)*ptr)) { |
1982 | | f_integer = 0; |
1983 | | } |
1984 | | ptr++; |
1985 | | } |
1986 | | word[cnt] = '\0'; |
1987 | | *End = ptr; |
1988 | | if (f_integer) { |
1989 | | *wordType = WT_INTEGER; |
1990 | | } |
1991 | | return 0; |
1992 | | } |
1993 | | |
1994 | | typedef struct { |
1995 | | sInt4 val; |
1996 | | int len; /* read from len char string? */ |
1997 | | } stackType; |
1998 | | |
1999 | | typedef struct { |
2000 | | int relUnit; |
2001 | | int f_negate; |
2002 | | int amount; |
2003 | | } relType; |
2004 | | |
2005 | | /***************************************************************************** |
2006 | | * Clock_Scan() -- |
2007 | | * |
2008 | | * Arthur Taylor / MDL |
2009 | | * |
2010 | | * PURPOSE |
2011 | | * |
2012 | | * ARGUMENTS |
2013 | | * |
2014 | | * RETURNS: void |
2015 | | * |
2016 | | * HISTORY |
2017 | | * |
2018 | | * NOTES |
2019 | | * * f_gmt == 0 no adjust, 1 adjust as LDT, 2 adjust as LST * |
2020 | | * Adjusted from: |
2021 | | * if ((f_gmt == 2) && (Clock_IsDaylightSaving2 (*l_clock, 0) == 1)) { |
2022 | | * to: |
2023 | | * if ((f_gmt == 1) && (Clock_IsDaylightSaving2 (*l_clock, 0) == 1)) { |
2024 | | |
2025 | | ***************************************************************************** |
2026 | | */ |
2027 | | |
2028 | | int Clock_Scan (double *l_clock, char *buffer, char f_gmt) |
2029 | | { |
2030 | | char *ptr, *ptr2; |
2031 | | char *ptr3; |
2032 | | char word[30]; |
2033 | | int wordType; |
2034 | | int lastWordType; |
2035 | | sChar TimeZone = Clock_GetTimeZone (); |
2036 | | /* hours to add to local time to get UTC. */ |
2037 | | char f_dayLight = 0; |
2038 | | int month = 0; |
2039 | | int day; |
2040 | | sInt4 year; |
2041 | | char f_year = 0; |
2042 | | int l_index; |
2043 | | int ans; |
2044 | | stackType *Stack = NULL; |
2045 | | relType *Rel = NULL; |
2046 | | int lenRel = 0; |
2047 | | int lenStack = 0; |
2048 | | static const char * const PreRel[] = { "LAST", "THIS", "NEXT", NULL }; |
2049 | | static const char * const RelUnit[] = { |
2050 | | "YEAR", "YEARS", "MONTH", "MONTHS", "FORTNIGHT", "FORTNIGHTS", "WEEK", |
2051 | | "WEEKS", "DAY", "DAYS", "HOUR", "HOURS", "MIN", "MINS", "MINUTE", |
2052 | | "MINUTES", "SEC", "SECS", "SECOND", "SECONDS", NULL |
2053 | | }; |
2054 | | static const char * const AdjDay[] = { "YESTERDAY", "TODAY", "TOMORROW", NULL }; |
2055 | | sChar f_ampm = -1; |
2056 | | char f_timeZone = 0; |
2057 | | char f_time = 0; |
2058 | | /* char f_date = 0; */ |
2059 | | char f_slashWord = 0; |
2060 | | char f_dateWord = 0; |
2061 | | char f_monthWord = 0; |
2062 | | char f_dayWord = 0; |
2063 | | double curTime; |
2064 | | sInt4 sec; |
2065 | | int i; |
2066 | | int monthAdj; |
2067 | | int yearAdj; |
2068 | | |
2069 | | /* Check that they gave us a string */ |
2070 | | ptr = buffer; |
2071 | | if (*ptr == '\0') |
2072 | | return 0; |
2073 | | |
2074 | | f_time = 0; |
2075 | | /* f_date = 0; */ |
2076 | | lastWordType = WT_NONE; |
2077 | | curTime = 0; |
2078 | | while (Clock_GetWord (&ptr, &ptr2, word, &wordType) == 0) { |
2079 | | if (wordType == WT_COLON) { |
2080 | | if (f_time) { |
2081 | | printf ("Detected multiple time pieces\n"); |
2082 | | goto errorReturn; |
2083 | | } |
2084 | | curTime = Clock_ScanColon (word); |
2085 | | f_time = 1; |
2086 | | } else if (wordType == WT_SLASH) { |
2087 | | if ((f_slashWord) || (f_dateWord)) { |
2088 | | printf ("Detected multiple date pieces\n"); |
2089 | | goto errorReturn; |
2090 | | } |
2091 | | Clock_ScanSlash (word, &month, &day, &year, &f_year); |
2092 | | f_slashWord = 1; |
2093 | | } else if (wordType == WT_DASH) { |
2094 | | if ((f_slashWord) || (f_dateWord)) { |
2095 | | printf ("Detected multiple date pieces\n"); |
2096 | | goto errorReturn; |
2097 | | } |
2098 | | Clock_ScanDash (word, &month, &day, &year, &curTime, &f_time); |
2099 | | f_year = 1; |
2100 | | f_slashWord = 1; |
2101 | | TimeZone = 0; |
2102 | | } else if (wordType == WT_INTEGER) { |
2103 | | lenStack++; |
2104 | | Stack = (stackType *) realloc ((void *) Stack, |
2105 | | lenStack * sizeof (stackType)); |
2106 | | Stack[lenStack - 1].val = atoi (word); |
2107 | | Stack[lenStack - 1].len = (int)strlen (word); |
2108 | | } else if (strcmp (word, "AM") == 0) { |
2109 | | if (f_ampm != -1) { |
2110 | | printf ("Detected multiple am/pm\n"); |
2111 | | goto errorReturn; |
2112 | | } |
2113 | | f_ampm = 1; |
2114 | | wordType = WT_AMPM; |
2115 | | } else if (strcmp (word, "PM") == 0) { |
2116 | | if (f_ampm != -1) { |
2117 | | printf ("Detected multiple am/pm\n"); |
2118 | | goto errorReturn; |
2119 | | } |
2120 | | f_ampm = 2; |
2121 | | wordType = WT_AMPM; |
2122 | | } else if (Clock_ScanZone2 (word, &TimeZone, &f_dayLight) == 0) { |
2123 | | if (f_timeZone) { |
2124 | | printf ("Detected multiple time zones.\n"); |
2125 | | goto errorReturn; |
2126 | | } |
2127 | | if (f_dayLight == 0) { |
2128 | | f_gmt = 2; |
2129 | | } else { |
2130 | | f_gmt = 1; |
2131 | | } |
2132 | | f_timeZone = 1; |
2133 | | wordType = WT_TIMEZONE; |
2134 | | } else if ((l_index = Clock_ScanMonth (word)) != -1) { |
2135 | | if ((f_slashWord) || (f_monthWord)) { |
2136 | | printf ("Detected multiple months or already defined month.\n"); |
2137 | | goto errorReturn; |
2138 | | } |
2139 | | month = l_index; |
2140 | | /* Get the next word? First preserve the pointer */ |
2141 | | ptr3 = ptr2; |
2142 | | ptr = ptr2; |
2143 | | ans = Clock_GetWord (&ptr, &ptr2, word, &wordType); |
2144 | | if ((ans != 0) || (wordType != WT_INTEGER)) { |
2145 | | /* Next word not integer, so previous word is integral day. */ |
2146 | | if (lastWordType != WT_INTEGER) { |
2147 | | printf ("Problems with month word and finding the day.\n"); |
2148 | | goto errorReturn; |
2149 | | } |
2150 | | lenStack--; |
2151 | | if( Stack ) day = Stack[lenStack].val; |
2152 | | /* Put the next word back under consideration. */ |
2153 | | wordType = WT_MONTH; |
2154 | | ptr2 = ptr3; |
2155 | | } else { |
2156 | | /* If word is trailed by comma, then it is day, and the next one |
2157 | | * is the year, otherwise it is a year, and the number before the |
2158 | | * month is the day. */ |
2159 | | if (*ptr2 == ',') { |
2160 | | day = atoi (word); |
2161 | | ptr = ptr2; |
2162 | | ans = Clock_GetWord (&ptr, &ptr2, word, &wordType); |
2163 | | if ((ans != 0) || (wordType != WT_INTEGER)) { |
2164 | | printf ("Couldn't find the year after the day.\n"); |
2165 | | goto errorReturn; |
2166 | | } |
2167 | | year = atoi (word); |
2168 | | f_year = 1; |
2169 | | } else { |
2170 | | year = atoi (word); |
2171 | | f_year = 1; |
2172 | | if (lastWordType != WT_INTEGER) { |
2173 | | printf ("Problems with month word and finding the day.\n"); |
2174 | | goto errorReturn; |
2175 | | } |
2176 | | lenStack--; |
2177 | | if( Stack ) day = Stack[lenStack].val; |
2178 | | } |
2179 | | } |
2180 | | f_monthWord = 1; |
2181 | | f_dateWord = 1; |
2182 | | |
2183 | | /* Ignore the day of the week info? */ |
2184 | | } else if ((l_index = Clock_ScanWeekday (word)) != -1) { |
2185 | | if ((f_slashWord) || (f_dayWord)) { |
2186 | | printf ("Detected multiple day of week or already defined " |
2187 | | "day.\n"); |
2188 | | goto errorReturn; |
2189 | | } |
2190 | | wordType = WT_DAY; |
2191 | | f_dayWord = 1; |
2192 | | f_dateWord = 1; |
2193 | | } else if (GetIndexFromStr (word, PreRel, &l_index) != -1) { |
2194 | | wordType = WT_PRE_RELATIVE; |
2195 | | /* Next word must be a unit word. */ |
2196 | | ptr = ptr2; |
2197 | | if (Clock_GetWord (&ptr, &ptr2, word, &wordType) != 0) { |
2198 | | printf ("Couldn't get the next word after Pre-Relative time " |
2199 | | "word\n"); |
2200 | | goto errorReturn; |
2201 | | } |
2202 | | if (GetIndexFromStr (word, RelUnit, &ans) == -1) { |
2203 | | printf ("Couldn't get the Relative unit\n"); |
2204 | | goto errorReturn; |
2205 | | } |
2206 | | if (l_index != 1) { |
2207 | | lenRel++; |
2208 | | Rel = (relType *) realloc ((void *) Rel, |
2209 | | lenRel * sizeof (relType)); |
2210 | | Rel[lenRel - 1].relUnit = ans; |
2211 | | Rel[lenRel - 1].amount = 1; |
2212 | | if (l_index == 0) { |
2213 | | Rel[lenRel - 1].f_negate = 1; |
2214 | | } else { |
2215 | | Rel[lenRel - 1].f_negate = 0; |
2216 | | } |
2217 | | } |
2218 | | printf ("Pre Relative Word: %s %d\n", word, l_index); |
2219 | | |
2220 | | } else if (strcmp (word, "AGO") == 0) { |
2221 | | if ((lastWordType != WT_PRE_RELATIVE) && |
2222 | | (lastWordType != WT_RELATIVE_UNIT)) { |
2223 | | printf ("Ago did not follow relative words\n"); |
2224 | | goto errorReturn; |
2225 | | } |
2226 | | Rel[lenRel - 1].f_negate = 1; |
2227 | | wordType = WT_POST_RELATIVE; |
2228 | | } else if (GetIndexFromStr (word, RelUnit, &l_index) != -1) { |
2229 | | lenRel++; |
2230 | | Rel = (relType *) realloc ((void *) Rel, lenRel * sizeof (relType)); |
2231 | | Rel[lenRel - 1].relUnit = l_index; |
2232 | | Rel[lenRel - 1].amount = 1; |
2233 | | Rel[lenRel - 1].f_negate = 0; |
2234 | | if (lastWordType == WT_INTEGER && Stack) { |
2235 | | lenStack--; |
2236 | | Rel[lenRel - 1].amount = Stack[lenStack].val; |
2237 | | } |
2238 | | wordType = WT_RELATIVE_UNIT; |
2239 | | } else if (GetIndexFromStr (word, AdjDay, &l_index) != -1) { |
2240 | | if (l_index != 1) { |
2241 | | lenRel++; |
2242 | | Rel = (relType *) realloc ((void *) Rel, |
2243 | | lenRel * sizeof (relType)); |
2244 | | Rel[lenRel - 1].relUnit = 13; /* DAY in RelUnit list */ |
2245 | | Rel[lenRel - 1].amount = 1; |
2246 | | if (l_index == 0) { |
2247 | | Rel[lenRel - 1].f_negate = 1; |
2248 | | } else { |
2249 | | Rel[lenRel - 1].f_negate = 0; |
2250 | | } |
2251 | | } |
2252 | | wordType = WT_ADJDAY; |
2253 | | } else { |
2254 | | printf ("unknown: %s\n", word); |
2255 | | goto errorReturn; |
2256 | | } |
2257 | | ptr = ptr2; |
2258 | | lastWordType = wordType; |
2259 | | } |
2260 | | |
2261 | | /* Deal with time left on the integer stack. */ |
2262 | | if (lenStack > 1) { |
2263 | | printf ("Too many integers on the stack?\n"); |
2264 | | goto errorReturn; |
2265 | | } |
2266 | | if (lenStack == 1) { |
2267 | | if (Stack[0].val < 0) { |
2268 | | printf ("Unable to deduce a negative time?\n"); |
2269 | | goto errorReturn; |
2270 | | } |
2271 | | if (f_time) { |
2272 | | if (f_dateWord || f_slashWord) { |
2273 | | printf ("Already have date and time...\n"); |
2274 | | goto errorReturn; |
2275 | | } |
2276 | | if ((Stack[0].len == 6) || (Stack[0].len == 8)) { |
2277 | | year = Stack[0].val / 10000; |
2278 | | f_year = 1; |
2279 | | month = (Stack[0].val % 10000) / 100; |
2280 | | day = Stack[0].val % 100; |
2281 | | f_slashWord = 1; |
2282 | | if ((month < 1) || (month > 12) || (day < 1) || (day > 31)) { |
2283 | | printf ("Unable to deduce the integer value\n"); |
2284 | | return -1; |
2285 | | } |
2286 | | } else { |
2287 | | printf ("Unable to deduce the integer value\n"); |
2288 | | goto errorReturn; |
2289 | | } |
2290 | | } else { |
2291 | | if (Stack[0].len < 3) { |
2292 | | curTime = Stack[0].val * 3600; |
2293 | | f_time = 1; |
2294 | | } else if (Stack[0].len < 5) { |
2295 | | curTime = ((Stack[0].val / 100) * 3600. + |
2296 | | (Stack[0].val % 100) * 60.); |
2297 | | f_time = 1; |
2298 | | } else if ((Stack[0].len == 6) || (Stack[0].len == 8)) { |
2299 | | year = Stack[0].val / 10000; |
2300 | | f_year = 1; |
2301 | | month = (Stack[0].val % 10000) / 100; |
2302 | | day = Stack[0].val % 100; |
2303 | | f_slashWord = 1; |
2304 | | if ((month < 1) || (month > 12) || (day < 1) || (day > 31)) { |
2305 | | printf ("Unable to deduce the integer value\n"); |
2306 | | free( Rel ); |
2307 | | free( Stack ); |
2308 | | return -1; |
2309 | | } |
2310 | | } else { |
2311 | | printf ("Unable to deduce the time\n"); |
2312 | | goto errorReturn; |
2313 | | } |
2314 | | } |
2315 | | /*lenStack = 0;*/ |
2316 | | } |
2317 | | if (!f_time) { |
2318 | | if (f_ampm != -1) { |
2319 | | printf ("Problems setting the time to 0\n"); |
2320 | | goto errorReturn; |
2321 | | } |
2322 | | curTime = 0; |
2323 | | } |
2324 | | if (f_ampm == 1) { |
2325 | | /* Adjust for 12 am */ |
2326 | | sec = (sInt4) (curTime - (floor (curTime / SEC_DAY)) * SEC_DAY); |
2327 | | if (((sec % 43200L) / 3600) == 0) { |
2328 | | curTime -= 43200L; |
2329 | | } |
2330 | | } else if (f_ampm == 2) { |
2331 | | /* Adjust for 12 pm */ |
2332 | | curTime += 43200L; |
2333 | | sec = (sInt4) (curTime - (floor (curTime / SEC_DAY)) * SEC_DAY); |
2334 | | if (((sec % 43200L) / 3600) == 0) { |
2335 | | curTime -= 43200L; |
2336 | | } |
2337 | | } |
2338 | | for (i = 0; i < lenRel; i++) { |
2339 | | if (Rel[i].f_negate) { |
2340 | | Rel[i].amount = -1 * Rel[i].amount; |
2341 | | } |
2342 | | } |
2343 | | /* Deal with adjustments by year or month. */ |
2344 | | if (f_dateWord || f_slashWord) { |
2345 | | /* Check if we don't have the year. */ |
2346 | | if (!f_year) { |
2347 | | *l_clock = Clock_Seconds (); |
2348 | | Clock_Epoch2YearDay ((sInt4) (floor (*l_clock / SEC_DAY)), &i, &year); |
2349 | | } |
2350 | | /* Deal with relative adjust by year and month. */ |
2351 | | for (i = 0; i < lenRel; i++) { |
2352 | | if ((Rel[i].relUnit == 0) || (Rel[i].relUnit == 1)) { |
2353 | | year += Rel[i].amount; |
2354 | | } else if ((Rel[i].relUnit == 2) || (Rel[i].relUnit == 3)) { |
2355 | | month += Rel[i].amount; |
2356 | | } |
2357 | | } |
2358 | | if (month > 12) { |
2359 | | int incrYearDueToMonth = (month-1) / 12; |
2360 | | year += incrYearDueToMonth; |
2361 | | month -= 12 * incrYearDueToMonth; |
2362 | | } |
2363 | | else if( month <= 0) { |
2364 | | int incrYearDueToMonth = (month-12) / 12; |
2365 | | year += incrYearDueToMonth; |
2366 | | month -= 12 * incrYearDueToMonth; |
2367 | | } |
2368 | | *l_clock = 0; |
2369 | | Clock_ScanDate (l_clock, year, month, day); |
2370 | | |
2371 | | } else { |
2372 | | /* Pure Time words. */ |
2373 | | *l_clock = Clock_Seconds (); |
2374 | | /* round off to start of day */ |
2375 | | *l_clock = (floor (*l_clock / SEC_DAY)) * SEC_DAY; |
2376 | | /* Deal with relative adjust by year and month. */ |
2377 | | monthAdj = 0; |
2378 | | yearAdj = 0; |
2379 | | for (i = 0; i < lenRel; i++) { |
2380 | | if ((Rel[i].relUnit == 0) || (Rel[i].relUnit == 1)) { |
2381 | | if (Rel[i].f_negate) { |
2382 | | yearAdj -= Rel[i].amount; |
2383 | | } else { |
2384 | | yearAdj += Rel[i].amount; |
2385 | | } |
2386 | | } else if ((Rel[i].relUnit == 2) || (Rel[i].relUnit == 3)) { |
2387 | | if (Rel[i].f_negate) { |
2388 | | monthAdj -= Rel[i].amount; |
2389 | | } else { |
2390 | | monthAdj += Rel[i].amount; |
2391 | | } |
2392 | | } |
2393 | | } |
2394 | | if ((monthAdj != 0) || (yearAdj != 0)) { |
2395 | | /* Break l_clock into mon/day/year */ |
2396 | | Clock_Epoch2YearDay ((sInt4) (floor (*l_clock / SEC_DAY)), |
2397 | | &day, &year); |
2398 | | month = Clock_MonthNum (day, year); |
2399 | | day -= (Clock_NumDay (month, 1, year, 1) - 1); |
2400 | | month += monthAdj; |
2401 | | year += yearAdj; |
2402 | | if (month > 12) { |
2403 | | int incrYearDueToMonth = (month-1) / 12; |
2404 | | year += incrYearDueToMonth; |
2405 | | month -= 12 * incrYearDueToMonth; |
2406 | | } |
2407 | | else if( month <= 0) { |
2408 | | int incrYearDueToMonth = (month-12) / 12; |
2409 | | year += incrYearDueToMonth; |
2410 | | month -= 12 * incrYearDueToMonth; |
2411 | | } |
2412 | | *l_clock = 0; |
2413 | | Clock_ScanDate (l_clock, year, month, day); |
2414 | | } |
2415 | | } |
2416 | | |
2417 | | /* Join the date and the time. */ |
2418 | | *l_clock += curTime; |
2419 | | |
2420 | | /* Finish the relative adjustments. */ |
2421 | | for (i = 0; i < lenRel; i++) { |
2422 | | switch (Rel[i].relUnit) { |
2423 | | case 3: /* Fortnight. */ |
2424 | | case 4: |
2425 | | *l_clock += (Rel[i].amount * 14 * 24 * 3600.); |
2426 | | break; |
2427 | | case 5: /* Week. */ |
2428 | | case 6: |
2429 | | *l_clock += (Rel[i].amount * 7 * 24 * 3600.); |
2430 | | break; |
2431 | | case 7: /* Day. */ |
2432 | | case 8: |
2433 | | *l_clock += (Rel[i].amount * 24 * 3600.); |
2434 | | break; |
2435 | | case 9: /* Hour. */ |
2436 | | case 10: |
2437 | | *l_clock += (Rel[i].amount * 3600.); |
2438 | | break; |
2439 | | case 11: /* Minute. */ |
2440 | | case 12: |
2441 | | case 13: |
2442 | | case 14: |
2443 | | *l_clock += (Rel[i].amount * 60.); |
2444 | | break; |
2445 | | case 15: /* Second. */ |
2446 | | case 16: |
2447 | | case 17: |
2448 | | case 18: |
2449 | | *l_clock += Rel[i].amount; |
2450 | | break; |
2451 | | } |
2452 | | } |
2453 | | |
2454 | | if (f_gmt != 0) { |
2455 | | /* IsDaylightSaving takes l_clock in GMT, and Timezone. */ |
2456 | | /* Note: A 0 is passed to DaylightSavings so it converts from LST to |
2457 | | * LST. */ |
2458 | | if ((f_gmt == 1) && (Clock_IsDaylightSaving2 (*l_clock, 0) == 1)) { |
2459 | | *l_clock = *l_clock - 3600; |
2460 | | } |
2461 | | /* Handle gmt problems. We are going from Local time to GMT so we add |
2462 | | * the TimeZone here. */ |
2463 | | *l_clock = *l_clock + TimeZone * 3600; |
2464 | | } |
2465 | | |
2466 | | free (Stack); |
2467 | | free (Rel); |
2468 | | return 0; |
2469 | | |
2470 | | errorReturn: |
2471 | | free (Stack); |
2472 | | free (Rel); |
2473 | | return -1; |
2474 | | } |
2475 | | |
2476 | | #endif // unused_by_GDAL |
2477 | | |
2478 | | double Clock_AddMonthYear (double refTime, int incrMonth, int incrYear) |
2479 | 179 | { |
2480 | 179 | sInt4 totDay; |
2481 | 179 | int day; |
2482 | 179 | sInt4 year; |
2483 | 179 | int month; |
2484 | 179 | double d_remain; |
2485 | 179 | int i; |
2486 | | |
2487 | 179 | if( !(fabs(refTime) < (double)SEC_DAY * 365 * 10000) ) |
2488 | 0 | { |
2489 | 0 | fprintf(stderr, "invalid refTime = %f\n", refTime); |
2490 | 0 | return 0; |
2491 | 0 | } |
2492 | | |
2493 | 179 | totDay = (sInt4) floor (refTime / SEC_DAY); |
2494 | 179 | Clock_Epoch2YearDay (totDay, &day, &year); |
2495 | 179 | month = Clock_MonthNum (day, year); |
2496 | 179 | day = day - Clock_NumDay (month, 1, year, 1) + 1; |
2497 | 179 | d_remain = refTime - (double)totDay * 3600 * 24.0; |
2498 | | |
2499 | | /* Add the month */ |
2500 | 179 | if (incrMonth != 0) { |
2501 | 63 | if( incrMonth > 0 && month > INT_MAX - incrMonth ) |
2502 | 0 | { |
2503 | 0 | fprintf(stderr, "invalid incrMonth = %d\n", incrMonth); |
2504 | 0 | return 0; |
2505 | 0 | } |
2506 | 63 | if( incrMonth < 0 && month < INT_MIN-(-12) - incrMonth ) |
2507 | 0 | { |
2508 | 0 | fprintf(stderr, "invalid incrMonth = %d\n", incrMonth); |
2509 | 0 | return 0; |
2510 | 0 | } |
2511 | 63 | month += incrMonth; |
2512 | 63 | if (month > 12) { |
2513 | 63 | int incrYearDueToMonth = (month-1) / 12; |
2514 | 63 | year += incrYearDueToMonth; |
2515 | 63 | month -= 12 * incrYearDueToMonth; |
2516 | 63 | } |
2517 | 0 | else if( month <= 0) { |
2518 | 0 | int incrYearDueToMonth = (month-12) / 12; |
2519 | 0 | year += incrYearDueToMonth; |
2520 | 0 | month -= 12 * incrYearDueToMonth; |
2521 | 0 | } |
2522 | 63 | } |
2523 | | /* Add the year. */ |
2524 | 179 | if (incrYear != 0) { |
2525 | 116 | if (incrYear > 0 && year > INT_MAX - incrYear) { |
2526 | 0 | fprintf(stderr, "overflow. year: %d incrYear: %d\n", year, incrYear); |
2527 | 0 | return 0; |
2528 | 0 | } |
2529 | 116 | if (incrYear < 0 && year < INT_MIN - incrYear) { |
2530 | 0 | fprintf(stderr, "overflow. year: %d incrYear: %d\n", year, incrYear); |
2531 | 0 | return 0; |
2532 | 0 | } |
2533 | 116 | year += incrYear; |
2534 | 116 | } |
2535 | | |
2536 | | /* Recompose the date */ |
2537 | 179 | i = Clock_NumDay (month, 1, year, 0); |
2538 | 179 | if (day > i) { |
2539 | 0 | day = i; |
2540 | 0 | } |
2541 | 179 | refTime = 0; |
2542 | 179 | Clock_ScanDate (&refTime, year, month, day); |
2543 | 179 | refTime += d_remain; |
2544 | 179 | return refTime; |
2545 | 179 | } |
2546 | | |
2547 | | #ifdef CLOCK_PROGRAM |
2548 | | /* See clockstart.c */ |
2549 | | #endif |