/*********************************************************************** * * TITLE: * utc.c * * AUTHOR: * Kevin J. Miller, Ana Maria Guerrero * * DESCRIPTION: * This module is a generic OEL module which contains routines * which are used to perform operations on time values. * * CHANGE HISTORY * * $Log: utc.c,v $ * Revision 1.15 1996/12/27 23:24:48 kevin * fixed compiler warnings * * Revision 1.14 1995/04/21 21:59:01 kevin * added all-US local time zone support * * Revision 1.13 1994/05/20 22:45:03 kevin * added * * Revision 1.12 1994/05/04 21:01:03 kevin * changed print of utc_val * * Revision 1.11 1994/04/30 02:18:12 kevin * port to ANSI * * Revision 1.10 1992/12/31 23:44:13 kevin * added Chris' get_hms() and getx_days() functions * * Revision 1.9 1992/02/05 23:04:50 kevin * added local time function * * Revision 1.8 1991/09/05 00:01:15 kevin * added functions to return integer values * * Revision 1.7 1991/07/18 20:59:54 kevin * added week functions * * Revision 1.6 1991/06/21 01:56:46 kevin * added m/d/y functions * * Revision 1.5 1991/05/14 02:12:11 kevin * minor lint fixes * * Revision 1.4 1991/05/09 21:58:30 kevin * added standard function headers * * Revision 1.3 1991/04/12 01:11:31 kevin * added standard SFOC header * * Revision 1.2 1991/03/07 20:34:49 kevin * added getx_doy() and getx_year() functions * * Revision 1.1 1991/03/04 21:46:29 kevin * Initial revision * *********************************************************************** * * WARNINGS: * * EXTERNAL CALLABLE COMPONENTS (PUBLIC): * init_utc_resol() * set_utc() * setx_utc() * get_utc() * getx_utc() * getx_year() * get_doy() * getx_doy() * get_wkday() * getx_wkday() * set_mdy() * get_mdy() * set_week() * get_week() * set_loc_tzone() * * GLOBALS: * * WAIVERS: * * NOTES: * * MANPAGE: * ***********************************************************************/ #ifndef lint static const char rcsid[] = "$Id: utc.c,v 1.15 1996/12/27 23:24:48 kevin OEL $"; #endif #include #include #include #include #define TRUE 1 #define FALSE 0 #include "utc.h" static int resol = UTC_SECONDS; static int std_local_offset = - 8 * UTC_ONE_HOUR; static char *std_zone = "PST"; static char *dst_zone = "PDT"; static int mndays[2][13] = { { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; /*********************************************************************** * * FUNCTION: * init_utc_resol() * * INPUTS: * val - (int) new time resolution * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * resol - (static int) time resolution * * DESCRIPTION: * Set the time resolution for text output routines. This routine * exists in order to keep the resol variable static. */ void init_utc_resol(int val) { resol = val; } /*********************************************************************** * * FUNCTION: * setx_utc() * * INPUTS: * text - (char *) standard utc text string * * OUTPUTS: * * RETURNS: * tval - (utc_val) utc in seconds as a long int * UTC_INVALID - on conversion error (0xffffffff) * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Convert standard utc text string to utc value. Less significant * fields need not be present. */ utc_val setx_utc(char text[]) { int year, doy, hour, min, sec; int i; utc_val tval; year = doy = hour = min = sec = 0; for (i = 0; i < 4; i++) { /* extract year */ if (!isdigit(text[i])) return UTC_INVALID; year = 10 * year + text[i] - '0'; } if ((year < 1970) || (year >= 2100)) return UTC_INVALID; if (text[4] != '-') return UTC_INVALID; /* separator */ for (i = 5; i < 8; i++) { /* extract day of year */ if (!isdigit(text[i])) return UTC_INVALID; doy = 10 * doy + text[i] - '0'; } if ((doy < 1) || (doy > ((year % 4) ? 365 : 366))) return UTC_INVALID; if (text[8] == '\0') goto finish_up; if (text[8] != 'T') return UTC_INVALID; /* separator */ for (i = 9; i < 11; i++) { /* extract hour */ if (!isdigit(text[i])) return UTC_INVALID; hour = 10 * hour + text[i] - '0'; } if ((hour < 0) || (hour >= 24)) return UTC_INVALID; if (text[11] == '\0') goto finish_up; if (text[11] != ':') return UTC_INVALID; /* separator */ for (i = 12; i < 14; i++) { /* extract minute */ if (!isdigit(text[i])) return UTC_INVALID; min = 10 * min + text[i] - '0'; } if ((min < 0) || (min >= 60)) return UTC_INVALID; if (text[14] == '\0') goto finish_up; if (text[14] != ':') return UTC_INVALID; /* separator */ for (i = 15; i < 17; i++) { /* extract second */ if (!isdigit(text[i])) return UTC_INVALID; sec = 10 * sec + text[i] - '0'; } if ((sec < 0) || (sec >= 60)) return UTC_INVALID; if (text[17] != '\0') return UTC_INVALID; /* terminator */ finish_up: tval = (year - 1970) * 365 + (year - 1969) / 4 + (doy - 1); tval = (tval * 24) + hour; tval = (tval * 60) + min; tval = (tval * 60) + sec; return tval; } /*********************************************************************** * * FUNCTION: * get_utc() * * INPUTS: * tval - (utc_val) input time value (required) * * OUTPUTS: * year - (int *) four digit year (required) * doy - (int *) three digit day of year (required) * hour - (int *) two digit hour (if reolution <= UTC_HOURS) * min - (int *) two digit minute (if reolution <= UTC_MINUTES) * sec - (int *) two digit second (if reolution == UTC_SECONDS) * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Extracts year, doy, hour, min, and second from UTC time * value. This function is a varargs type, and the number * of arguments depends on the resolution set in the function * init_utc_resol(). */ void get_utc(utc_val tval, int *year_p, int *doy_p, ...) { va_list args; int year, doy, hour, min, sec; int *hour_p, *min_p, *sec_p; sec = tval % 60; tval /= 60; min = tval % 60; tval /= 60; hour = tval % 24; tval /= 24; doy = (tval + 365) % 1461; /* calculate days in blocks of four years */ year = 1969 + ((tval + 365) / 1461) * 4; if (doy == 1460) { year += 3; doy = 366; } else { year += (doy / 365); doy = (doy % 365) + 1; } *year_p = year; *doy_p = doy; va_start(args, doy_p); if (resol < UTC_DAYS) { hour_p = va_arg(args, int *); *hour_p = hour; if (resol < UTC_HOURS) { min_p = va_arg(args, int *); *min_p = min; if (resol < UTC_MINUTES) { sec_p = va_arg(args, int *); *sec_p = sec; } } } va_end(args); } /*********************************************************************** * * FUNCTION: * getx_utc() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * text - (char *) output time string * * RETURNS: * * EXTERNALLY READ: * resol - (static int) time resolution * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Convert utc value to standard utc text string using resol * to specify the resolution. */ void getx_utc(char text[], utc_val tval) { int year, doy, hour, min, sec; sec = tval % 60; tval /= 60; min = tval % 60; tval /= 60; hour = tval % 24; tval /= 24; doy = (tval + 365) % 1461; /* calculate days in blocks of four years */ year = 1969 + ((tval + 365) / 1461) * 4; if (doy == 1460) { year += 3; doy = 366; } else { year += (doy / 365); doy = (doy % 365) + 1; } text[0] = (year / 1000) + '0'; year %= 1000; text[1] = (year / 100) + '0'; year %= 100; text[2] = (year / 10) + '0'; year %= 10; text[3] = year + '0'; text[4] = '-'; text[5] = (doy / 100) + '0'; doy %= 100; text[6] = (doy / 10) + '0'; doy %= 10; text[7] = doy + '0'; if (resol == UTC_DAYS) { text[8] = '\0'; } else { text[8] = 'T'; text[9] = (hour / 10) + '0'; hour %= 10; text[10] = hour + '0'; if (resol == UTC_HOURS) { text[11] = '\0'; } else { text[11] = ':'; text[12] = (min / 10) + '0'; min %= 10; text[13] = min + '0'; if (resol == UTC_MINUTES) { text[14] = '\0'; } else { text[14] = ':'; text[15] = (sec / 10) + '0'; sec %= 10; text[16] = sec + '0'; text[17] = '\0'; } } } } /*********************************************************************** * * FUNCTION: * getx_year() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * text - (char *) output year string * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Extract 4 digit year text from utc_val. */ void getx_year(char text[], utc_val tval) { int year, doy; tval /= UTC_ONE_DAY; doy = (tval + 365) % 1461; /* calculate days in blocks of four years */ year = 1969 + ((tval + 365) / 1461) * 4; if (doy == 1460) { year += 3; } else { year += (doy / 365); } text[0] = (year / 1000) + '0'; year %= 1000; text[1] = (year / 100) + '0'; year %= 100; text[2] = (year / 10) + '0'; year %= 10; text[3] = year + '0'; text[4] = '\0'; } /*********************************************************************** * * FUNCTION: * get_doy() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * * RETURNS: * doy - (int) day-of-year * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Return day-of-year integer from utc_val. */ int get_doy(utc_val tval) { int doy; tval /= UTC_ONE_DAY; doy = (tval + 365) % 1461; /* calculate days in blocks of four years */ if (doy == 1460) { doy = 366; } else { doy = (doy % 365) + 1; } return doy; } /*********************************************************************** * * FUNCTION: * getx_doy() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * text - (char *) output day-of-year string * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Extract 3 digit day-of-year text from utc_val. */ void getx_doy(char text[], utc_val tval) { int doy; tval /= UTC_ONE_DAY; doy = (tval + 365) % 1461; /* calculate days in blocks of four years */ if (doy == 1460) { doy = 366; } else { doy = (doy % 365) + 1; } text[0] = (doy / 100) + '0'; doy %= 100; text[1] = (doy / 10) + '0'; doy %= 10; text[2] = doy + '0'; text[3] = '\0'; } /*********************************************************************** * * FUNCTION: * get_wkday() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * * RETURNS: * - (int) day of week * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Returns day of week (Monday is day 0). */ int get_wkday(utc_val tval) { tval /= UTC_ONE_DAY; return (tval + 3) % 7; } /*********************************************************************** * * FUNCTION: * getx_wkday() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * * RETURNS: * - (char *) day of week * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Returns day of week (Monday is day 0). */ char * getx_wkday(utc_val tval) { static char *day_text[] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; tval /= UTC_ONE_DAY; return day_text[(tval + 3) % 7]; } /*********************************************************************** * * FUNCTION: * set_mdy() * * INPUTS: * mo - (int) month value (1 to 12) * da - (int) day of month (1 to 31) * yr - (int) four digit year * * OUTPUTS: * * RETURNS: * tval - (utc_val) utc in seconds as a long int * UTC_INVALID - on conversion error (0xffffffff) * * EXTERNALLY READ: * mndays - (static int[][]) cum. array of days per month * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Converts time as mo/da/yr to standard utc_val. */ utc_val set_mdy(int mo, int da, int yr) { utc_val tval; int leap, doy; if ((yr < 1970) || (yr >= 2100)) return UTC_INVALID; leap = (yr % 4) ? 0 : 1; if ((mo < 1) || (mo > 12)) return UTC_INVALID; if ((da < 1) || (da > (mndays[leap][mo] - mndays[leap][mo - 1]))) return UTC_INVALID; doy = mndays[leap][mo - 1] + da; tval = (yr - 1970) * 365 + (yr - 1969) / 4 + (doy - 1); tval *= UTC_ONE_DAY; return tval; } /*********************************************************************** * * FUNCTION: * get_mdy() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * mo - (int *) pointer to returned month * da - (int *) pointer to returned day * yr - (int *) pointer to returned year * * RETURNS: * * EXTERNALLY READ: * mndays - (static int[][]) cum. array of days per month * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Convert utc value to integer mo/da/yr format. Hours, minutes, * and seconds are ignored. */ void get_mdy(int *mo, int *da, int *yr, utc_val tval) { int year, doy, leap; int l, m, h; tval /= UTC_ONE_DAY; doy = (tval + 365) % 1461; /* calculate days in blocks of four years */ year = 1969 + ((tval + 365) / 1461) * 4; if (doy == 1460) { year += 3; doy = 366; } else { year += (doy / 365); doy = (doy % 365) + 1; } leap = (year % 4) ? 0 : 1; /* * this is a standard binary search */ l = 0; h = 12; while (1) { if (l > h) { /* doy lies between */ m = l; break; } m = (l + h) / 2; if (mndays[leap][m] < doy) { l = m + 1; } else if (mndays[leap][m] > doy) { h = m - 1; } else { /* found doy exactly */ break; } } *yr = year; *mo = m; *da = doy - mndays[leap][m - 1]; } /*********************************************************************** * * FUNCTION: * set_week() * * INPUTS: * wk - (int) week number (1 to 53) * yr - (int) year (4 digits) * * OUTPUTS: * * RETURNS: * tval - (utc_val) utc in seconds of the 00:00:00 Monday * UTC_INVALID - on conversion error (0xffffffff) * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Takes an input week and year and converts these to the utc_val * of 00:00:00 on Monday of that week. * * The following shows several definitions of 'WEEK 1' * * 1988 JAN 4 - JAN 10 #7 * 1989 JAN 2 - JAN 8 #5 * 1990 JAN 1 - JAN 7 #4 * 1991 DEC 31 - JAN 6 #3 * 1992 DEC 30 - JAN 5 #2 * 1993 JAN 4 - JAN 10 #7 * 1994 JAN 3 - JAN 9 #6 * 1995 JAN 2 - JAN 8 #5 * 1996 JAN 1 - JAN 7 #4 * 1997 DEC 30 - JAN 5 #2 * 1998 DEC 29 - JAN 4 #1 * 1999 JAN 4 - JAN 10 #7 * * We can find out what day the year starts on with: * * dy = (yr + (yr - 1) / 4 - 2) % 7 * * where: 0 = MON, 1 = TUE, ... 6 = SUN * * The number of days that we need to add in order to get the first * Monday in January (where (dy % 7) == 0) is just (7 - dy) % 7. * Since years start on the 1st, the first Monday of the year is * ((7 - dy) % 7) + 1. * The full formula for the first Monday in January is: * * fm = ((7 - (yr + (yr - 1) / 4 - 2) % 7) % 7) + 1 * * which can be simplified to: * * fm = ((7 * N + 2) - (yr + (yr - 1) / 4)) % 7 + 1 * * where N is some large number chosen so that the expression in * parentheses is always positive. I will pick (7 * N + 2) = 7009. * * If the first Monday in January <= 4, then that is the start of the * year, otherwise the first week in the year starts in December of * the previous year. */ utc_val set_week(int wk, int yr) { utc_val tval, sval; int fm; if ((yr < 1970) || (yr >= 2100)) return UTC_INVALID; if ((wk < 1) || (wk >= 54)) return UTC_INVALID; /* some years permit a Week #53 */ fm = (7009 - (yr + (yr - 1) / 4)) % 7 + 1; tval = (yr - 1970) * 365 + (yr - 1969) / 4 + (fm - 1); if (fm > 4) tval -= 7; /* start last December */ tval += 7 * (wk - 1); /* add the week */ if (wk == 53) { /* need to check start of next year */ fm = (7009 - (yr + 1 + yr / 4)) % 7 + 1; sval = (yr - 1969) * 365 + (yr - 1968) / 4 + (fm - 1); if (fm > 4) sval -= 7; if (tval >= sval) return UTC_INVALID; } tval *= UTC_ONE_DAY; /* convert to seconds */ return tval; } /*********************************************************************** * * FUNCTION: * get_week() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * wk - (int *) pointer to returned week * yr - (int *) pointer to returned year * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Convert utc value to integer wk/yr format. Hours, minutes, * and seconds are ignored. All weeks start on Monday. * * First back off the day to the previous Monday, then find the year * and day of year, * * These Mondays always translate as follows: * * Jan 1 -> week 1 doy = 1 * Jan 2 -> week 1 doy = 2 * Jan 3 -> week 1 doy = 3 * Jan 4 -> week 1 doy = 4 * Jan 5 -> week 2 doy = 5 * Jan 6 -> week 3 doy = 6 * Jan 7 -> week 4 doy = 7 * : : : * Dec 26 -> week 52 doy = 360, 361 * Dec 27 (normal) -> week 52 doy = 361 * Dec 27 (leap) -> week 53 doy = 362 * Dec 28 -> week 53 doy = 362, 363 * Dec 29 -> week 1 (next year) doy = 363, 364 * Dec 30 -> week 1 (next year) doy = 364, 365 * Dec 31 -> week 1 (next year) doy = 365, 366 * * From this we see that one can generally use the formula: * * wk = (doy + 9) / 7 * * The exceptions are when (doy >= 364) or if (doy = 363) and is * not a leap year. */ void get_week(int *wk, int *yr, utc_val tval) { int year, doy, leap; tval /= UTC_ONE_DAY; /* * back off to the previous Monday */ tval -= (tval + 3) % 7; doy = (tval + 365) % 1461; /* * calculate days in blocks of four years */ year = 1969 + ((tval + 365) / 1461) * 4; if (doy == 1460) { year += 3; doy = 366; } else { year += (doy / 365); doy = (doy % 365) + 1; } leap = (year % 4) ? 0 : 1; if (doy - leap >= 363) { /* Dec 29, 30, 31 */ *wk = 1; *yr = year + 1; } else { /* normal situation */ *wk = (doy + 9) / 7; *yr = year; } } /*********************************************************************** * * FUNCTION: * get_local_offset() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * *isdst_ptr - (int) TRUE if DST if not NULL * *zone_ptr - (char [4]) time zone if not NULL * * RETURNS: * offset - (int) time to add to tval to get local * time * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Return day-of-year integer from utc_val. * * We change to DT on the first Sunday in April at 2 ST (3 DT). * We return to ST on the last Sunday in October at 1 ST (2 DT). * * The first Sunday in April is DOY: 91 to 97 in normal years. * The first Sunday in April is DOY: 92 to 98 in leap years. * The last Sunday in October is DOY: 298 to 304 in normal years. * The last Sunday in October is DOY: 299 to 305 in leap years. * * - Add standard offset to get local ST. * - Find DOY. * - Subtract 1 for leap year. * - Subtract 0 for Sunday, 1 for Monday, ... * - testday: --- .. 90 --> use ST * testday: 91 .. 97 (Sunday < 02:00:00 ST) ST else DT * testday: 98 .. 297 --> use DT * testday: 298 .. 304 (Sunday < 01:00:00 ST) DT else ST * testday: 305 .. +++ --> use ST */ int get_local_offset(utc_val tval, int *isdst_ptr, char *zone_ptr) { int secs; /* number of seconds in current day */ int jday; /* number of days since the epoch */ int year; int doy; /* day of year */ int dow; /* day of week (Sunday is 0 !!!) */ int testday; /* test value */ int isdst; /* TRUE if DST */ int offset; /* offset returned to get local times */ tval += std_local_offset; jday = tval / UTC_ONE_DAY; /* calculate days in blocks of four years */ doy = (jday + 365) % 1461; year = 1969 + ((jday + 365) / 1461) * 4; if (doy == 1460) { year += 3; doy = 366; } else { year += (doy / 365); doy = (doy % 365) + 1; } dow = (jday + 4) % 7; /* note change in formula */ testday = doy - dow; if (!(year % 4)) --testday; if ((testday <= 90) || (testday >= 305)) { isdst = FALSE; } else if ((testday >= 98) && (testday <= 297)) { isdst = TRUE; } else if ((testday >= 91) && (testday <= 97)) { if (dow == 0) { /* only check Sundays */ secs = tval % UTC_ONE_DAY; isdst = (secs >= 2 * UTC_ONE_HOUR); } else { isdst = TRUE; } } else if ((testday >= 298) && (testday <= 304)) { if (dow == 0) { /* only check Sundays */ secs = tval % UTC_ONE_DAY; isdst = (secs < UTC_ONE_HOUR); } else { isdst = FALSE; } } else { fprintf(stderr, "Major failure in UTC routines:\n"); fprintf(stderr, " tval = %u\n\n", (int)tval); isdst = 0; } if (isdst_ptr != NULL) *isdst_ptr = isdst; if (isdst) { if (zone_ptr != NULL) strcpy(zone_ptr, dst_zone); offset = std_local_offset + UTC_ONE_HOUR; } else { if (zone_ptr != NULL) strcpy(zone_ptr, std_zone); offset = std_local_offset; } return offset; } /*********************************************************************** * * FUNCTION: * get_hms() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * hrs - (int *) pointer to returned hours * min - (int *) pointer to returned minutes * sec - (int *) pointer to returned seconds * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * Convert utc value to integer hrs:min:sec format. Month, day, * and year are ignored. */ void get_hms(int *hrs, int *min, int *sec, utc_val tval) { tval %= UTC_ONE_DAY; *hrs = tval / UTC_ONE_HOUR; tval %= UTC_ONE_HOUR; *min = tval / UTC_ONE_MINUTE; *sec = tval % UTC_ONE_MINUTE; } /*********************************************************************** * * FUNCTION: * getx_days() * * INPUTS: * tval - (utc_val) input time * * OUTPUTS: * text - (char *) output year string * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * Extract 5 digit number of days text from utc_val. */ void getx_days(char *days, utc_val time) { int i, len; char temp[10]; time /= UTC_ONE_DAY; /* get number of days */ /* convert to string */ temp[0] = '0'; for (i=0; time > 0; i++) { temp[i] = (time % 10) + '0'; time /= 10; } if (i > 0) { temp[i] = '\0'; } else { temp[1] = '\0'; } len = strlen(temp); for (i=0; i < len; i++) { /* reverse the order of the digits */ days[i] = temp[len-i-1]; } days[len] = '\0'; } /*********************************************************************** * * FUNCTION: * set_loc_tzone() * * INPUTS: * zone - (int) time zone * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * Set time zone parameters in module space. */ void set_loc_tzone(int zone) { switch (zone) { case UTC_LCL_TZ_PST: std_local_offset = - 8 * UTC_ONE_HOUR; std_zone = "PST"; dst_zone = "PDT"; break; case UTC_LCL_TZ_MST: std_local_offset = - 7 * UTC_ONE_HOUR; std_zone = "MST"; dst_zone = "MDT"; break; case UTC_LCL_TZ_CST: std_local_offset = - 6 * UTC_ONE_HOUR; std_zone = "CST"; dst_zone = "CDT"; break; case UTC_LCL_TZ_EST: std_local_offset = - 5 * UTC_ONE_HOUR; std_zone = "EST"; dst_zone = "EDT"; break; default: std_local_offset = - 8 * UTC_ONE_HOUR; std_zone = "PST"; dst_zone = "PDT"; break; } }