LCOV - code coverage report
Current view: directory - frmts/grib/degrib18/degrib - clock.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1087 93 8.6 %
Date: 2010-01-09 Functions: 32 6 18.8 %

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

Generated by: LCOV version 1.7