📄 tzset.c
字号:
_set_timezone(timezone);
_set_daylight(daylight);
}
}
/***
:t static void cvtdate( trantype, datetype, year, month, week, dayofweek,
* date, hour, min, second, millisec ) - convert
* transition date format
*
*Purpose:
* Convert the format of a transition date specification to a value of
* a transitiondate structure.
*
*Entry:
* int trantype - 1, if it is the start of DST
* 0, if is the end of DST (in which case the date is
* is a DST date)
* int datetype - 1, if a day-in-month format is specified.
* 0, if an absolute date is specified.
* int year - year for which the date is being converted (70 ==
* 1970)
* int month - month (0 == January)
* int week - week of month, if datetype == 1 (note that 5== last
* week of month),
* 0, otherwise.
* int dayofweek - day of week (0 == Sunday), if datetype == 1.
* 0, otherwise.
* int date - date of month (1 - 31)
* int hour - hours (0 - 23)
* int min - minutes (0 - 59)
* int sec - seconds (0 - 59)
* int msec - milliseconds (0 - 999)
*
*Exit:
* dststart or dstend is filled in with the converted date.
*
*******************************************************************************/
static void __cdecl cvtdate (
int trantype,
int datetype,
int year,
int month,
int week,
int dayofweek,
int date,
int hour,
int min,
int sec,
int msec
)
{
int yearday;
int monthdow;
long dstbias = 0;
if ( datetype == 1 ) {
/*
* Transition day specified in day-in-month format.
*/
/*
* Figure the year-day of the start of the month.
*/
yearday = 1 + (_IS_LEAP_YEAR(year) ? _lpdays[month - 1] :
_days[month - 1]);
/*
* Figure the day of the week of the start of the month.
*/
monthdow = (yearday + ((year - 70) * 365) +
_ELAPSED_LEAP_YEARS(year) + _BASE_DOW) % 7;
/*
* Figure the year-day of the transition date
*/
if ( monthdow <= dayofweek )
yearday += (dayofweek - monthdow) + (week - 1) * 7;
else
yearday += (dayofweek - monthdow) + week * 7;
/*
* May have to adjust the calculation above if week == 5 (meaning
* the last instance of the day in the month). Check if year falls
* beyond after month and adjust accordingly.
*/
if ( (week == 5) &&
(yearday > (_IS_LEAP_YEAR(year) ? _lpdays[month] :
_days[month])) )
{
yearday -= 7;
}
}
else {
/*
* Transition day specified as an absolute day
*/
yearday = _IS_LEAP_YEAR(year) ? _lpdays[month - 1] :
_days[month - 1];
yearday += date;
}
if ( trantype == 1 ) {
/*
* Converted date was for the start of DST
*/
dststart.yd = yearday;
dststart.ms = msec + (1000 * (sec + 60 * (min + 60 * hour)));
/*
* Set year field of dststart so that unnecessary calls to
* cvtdate() may be avoided.
*/
dststart.yr = year;
}
else {
/*
* Converted date was for the end of DST
*/
dstend.yd = yearday;
dstend.ms = msec + (1000 * (sec + 60 * (min + 60 * hour)));
/*
* The converted date is still a DST date. Must convert to a
* standard (local) date while being careful the millisecond field
* does not overflow or underflow.
*/
_ERRCHECK(_get_dstbias(&dstbias));
if ( (dstend.ms += (dstbias * 1000)) < 0 ) {
dstend.ms += DAY_MILLISEC;
dstend.yd--;
}
else if ( dstend.ms >= DAY_MILLISEC ) {
dstend.ms -= DAY_MILLISEC;
dstend.yd++;
}
/*
* Set year field of dstend so that unnecessary calls to cvtdate()
* may be avoided.
*/
dstend.yr = year;
}
return;
}
/***
*int _isindst(tb) - determine if broken-down time falls in DST
*
*Purpose:
* Determine if the given broken-down time falls within daylight saving
* time (DST). The DST rules are either obtained from Win32 (tzapiused !=
* TRUE) or assumed to be USA rules, post 1986.
*
* If the DST rules are obtained from Win32's GetTimeZoneInformation API,
* the transition dates to/from DST can be specified in either of two
* formats. First, a day-in-month format, similar to the way USA rules
* are specified, can be used. The transition date is given as the n-th
* occurence of a specified day of the week in a specified month. Second,
* an absolute date can be specified. The two cases are distinguished by
* the value of wYear field in the SYSTEMTIME structure (0 denotes a
* day-in-month format).
*
* USA rules for DST are that a time is in DST iff it is on or after
* 02:00 on the first Sunday in April, and before 01:00 on the last
* Sunday in October.
*
*Entry:
* struct tm *tb - structure holding broken-down time value
*
*Exit:
* 1, if time represented is in DST
* 0, otherwise
*
*******************************************************************************/
int __cdecl _isindst (
struct tm *tb
)
{
int retval;
_mlock( _TIME_LOCK );
__TRY
retval = _isindst_nolock( tb );
__FINALLY
_munlock( _TIME_LOCK );
__END_TRY_FINALLY
return retval;
}
static int __cdecl _isindst_nolock (
struct tm *tb
)
{
long ms;
int daylight = 0;
_ERRCHECK(_get_daylight(&daylight));
if ( daylight == 0 )
return 0;
/*
* Compute (recompute) the transition dates for daylight saving time
* if necessary.The yr (year) fields of dststart and dstend is
* compared to the year of interest to determine necessity.
*/
if ( (tb->tm_year != dststart.yr) || (tb->tm_year != dstend.yr) ) {
if ( tzapiused ) {
/*
* Convert the start of daylight saving time to dststart.
*/
if ( tzinfo.DaylightDate.wYear == 0 )
cvtdate( 1,
1, /* day-in-month format */
tb->tm_year,
tzinfo.DaylightDate.wMonth,
tzinfo.DaylightDate.wDay,
tzinfo.DaylightDate.wDayOfWeek,
0,
tzinfo.DaylightDate.wHour,
tzinfo.DaylightDate.wMinute,
tzinfo.DaylightDate.wSecond,
tzinfo.DaylightDate.wMilliseconds );
else
cvtdate( 1,
0, /* absolute date */
tb->tm_year,
tzinfo.DaylightDate.wMonth,
0,
0,
tzinfo.DaylightDate.wDay,
tzinfo.DaylightDate.wHour,
tzinfo.DaylightDate.wMinute,
tzinfo.DaylightDate.wSecond,
tzinfo.DaylightDate.wMilliseconds );
/*
* Convert start of standard time to dstend.
*/
if ( tzinfo.StandardDate.wYear == 0 )
cvtdate( 0,
1, /* day-in-month format */
tb->tm_year,
tzinfo.StandardDate.wMonth,
tzinfo.StandardDate.wDay,
tzinfo.StandardDate.wDayOfWeek,
0,
tzinfo.StandardDate.wHour,
tzinfo.StandardDate.wMinute,
tzinfo.StandardDate.wSecond,
tzinfo.StandardDate.wMilliseconds );
else
cvtdate( 0,
0, /* absolute date */
tb->tm_year,
tzinfo.StandardDate.wMonth,
0,
0,
tzinfo.StandardDate.wDay,
tzinfo.StandardDate.wHour,
tzinfo.StandardDate.wMinute,
tzinfo.StandardDate.wSecond,
tzinfo.StandardDate.wMilliseconds );
}
else {
/*
* GetTimeZoneInformation API was NOT used, or failed. USA
* daylight saving time rules are assumed.
*/
int startmonth = 3; /* March */
int startweek = 2; /* second week... */
int endmonth = 11;/* November */
int endweek = 1; /* first week */
if( 107 > tb->tm_year )
{
startmonth = 4; /* April */
startweek = 1; /* first week... */
endmonth = 10;/* October */
endweek = 5; /* last week */
}
cvtdate( 1,
1,
tb->tm_year,
startmonth,
startweek,
0, /* ...Sunday */
0,
2, /* 02:00 (2 AM) */
0,
0,
0 );
cvtdate( 0,
1,
tb->tm_year,
endmonth,
endweek,
0, /* ...Sunday */
0,
2, /* 02:00 (2 AM) */
0,
0,
0 );
}
}
/*
* Handle simple cases first.
*/
if ( dststart.yd < dstend.yd ) {
/*
* Northern hemisphere ordering
*/
if ( (tb->tm_yday < dststart.yd) || (tb->tm_yday > dstend.yd) )
return 0;
if ( (tb->tm_yday > dststart.yd) && (tb->tm_yday < dstend.yd) )
return 1;
}
else {
/*
* Southern hemisphere ordering
*/
if ( (tb->tm_yday < dstend.yd) || (tb->tm_yday > dststart.yd) )
return 1;
if ( (tb->tm_yday > dstend.yd) && (tb->tm_yday < dststart.yd) )
return 0;
}
ms = 1000 * (tb->tm_sec + 60 * tb->tm_min + 3600 * tb->tm_hour);
if ( tb->tm_yday == dststart.yd ) {
if ( ms >= dststart.ms )
return 1;
else
return 0;
}
else {
/*
* tb->tm_yday == dstend.yd
*/
if ( ms < dstend.ms )
return 1;
else
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -