mirror of
https://github.com/reactos/reactos.git
synced 2024-08-21 19:03:01 +00:00
252 lines
5.9 KiB
C
252 lines
5.9 KiB
C
/*
|
|
* COPYRIGHT: LGPL, See LGPL.txt in the top level directory
|
|
* PROJECT: ReactOS CRT library
|
|
* FILE: lib/sdk/crt/time/timezone.c
|
|
* PURPOSE: Implementation of time zone functions
|
|
* PROGRAMERS: Timo Kreuzer
|
|
*/
|
|
#include "precomp.h"
|
|
|
|
char _tz_is_set = 0;
|
|
|
|
/* buffers must hold 64 characters! */
|
|
static char tz_name[64] = "PST";
|
|
static char tz_dst_name[64] = "PDT";
|
|
|
|
long dst_begin = 0;
|
|
long dst_end = 0;
|
|
|
|
/******************************************************************************
|
|
* \var _tzname
|
|
*/
|
|
char * _tzname[2] = {
|
|
tz_name,
|
|
tz_dst_name,
|
|
};
|
|
|
|
/******************************************************************************
|
|
* \var _daylight
|
|
*/
|
|
int _daylight = 0;
|
|
|
|
/******************************************************************************
|
|
* \name __p__daylight
|
|
* \brief Returns a pointer to the _daylight variable;
|
|
*/
|
|
void *
|
|
__p__daylight(void)
|
|
{
|
|
return &_daylight;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* \var _timezone
|
|
* \brief
|
|
*/
|
|
long _timezone = 28800;
|
|
|
|
/******************************************************************************
|
|
* \name __p__timezone
|
|
* \brief Returns a pointer to the _timezone variable;
|
|
*/
|
|
long *
|
|
__p__timezone(void)
|
|
{
|
|
return &_timezone;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* \var _dstbias
|
|
* \brief
|
|
*/
|
|
long _dstbias = 0;
|
|
|
|
/******************************************************************************
|
|
* \name __p__dstbias
|
|
* \brief Returns a pointer to the _dstbias variable;
|
|
*/
|
|
long *
|
|
__p__dstbias(void)
|
|
{
|
|
return &_dstbias;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* \name __p__tzname
|
|
* \brief Returns a pointer to the _tzname buffer;
|
|
*/
|
|
char **
|
|
__p__tzname(void)
|
|
{
|
|
return _tzname;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* \name _tzset
|
|
* \brief Initializes the variables _daylight, _timezone, and _tzname from the
|
|
* "TZ" environment variable if available or else by calling
|
|
* GetTimeZoneInformation.
|
|
* \sa http://msdn.microsoft.com/en-us/library/90s5c885.aspx
|
|
*/
|
|
void
|
|
_tzset(void)
|
|
{
|
|
const char * str;
|
|
|
|
if (_tz_is_set)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Try to read the timezone from environment */
|
|
str = getenv("TZ");
|
|
if (str && str[0] != 0)
|
|
{
|
|
long hour = 0, min = 0, sec = 0;
|
|
size_t len = strnlen(str, 16);
|
|
int sign = 1;
|
|
|
|
dst_begin = 0;
|
|
|
|
for (;;)
|
|
{
|
|
/* Copy timezone name */
|
|
strncpy(tz_name, str, 3);
|
|
str += 3;
|
|
len -= 3;
|
|
|
|
if (len < 1) break;
|
|
|
|
if (*str == '+' || *str == '-')
|
|
{
|
|
sign = *str == '-' ? -1 : 1;
|
|
str++;
|
|
len--;
|
|
}
|
|
|
|
if (len < 1) break;
|
|
|
|
hour = atol(str);
|
|
|
|
while (*str != 0 && *str != ':') str++;
|
|
if (*str == 0) break;
|
|
|
|
min = atol(++str);
|
|
|
|
while (*str != 0 && *str != ':') str++;
|
|
if (*str == 0) break;
|
|
|
|
sec = atol(++str);
|
|
|
|
while (*str != 0 && *str <= '9') str++;
|
|
if (*str == 0) break;
|
|
|
|
/* Copy DST name */
|
|
strncpy(tz_dst_name, str, 3);
|
|
|
|
// FIXME: set dst_begin etc
|
|
|
|
/* We are finished */
|
|
break;
|
|
}
|
|
|
|
_timezone = sign * (((hour * 60) + min) * 60 + sec);
|
|
|
|
}
|
|
else
|
|
{
|
|
TIME_ZONE_INFORMATION tzi;
|
|
DWORD ret;
|
|
|
|
ret = GetTimeZoneInformation(&tzi);
|
|
if (ret == TIME_ZONE_ID_INVALID)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ret = WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
tzi.StandardName,
|
|
-1,
|
|
tz_name,
|
|
sizeof(tz_name),
|
|
NULL,
|
|
NULL);
|
|
|
|
ret = WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
tzi.DaylightName,
|
|
-1,
|
|
tz_dst_name,
|
|
sizeof(tz_dst_name),
|
|
NULL,
|
|
NULL);
|
|
|
|
_timezone = tzi.Bias * 60;
|
|
|
|
if (tzi.DaylightDate.wMonth)
|
|
{
|
|
struct tm _tm;
|
|
|
|
_daylight = 1;
|
|
_dstbias = (tzi.DaylightBias - tzi.StandardBias) * 60;
|
|
_tm.tm_year = 70;
|
|
_tm.tm_mon = tzi.DaylightDate.wMonth - 1;
|
|
_tm.tm_mday = tzi.DaylightDate.wDay;
|
|
_tm.tm_hour = tzi.DaylightDate.wHour;
|
|
_tm.tm_min = tzi.DaylightDate.wMinute;
|
|
_tm.tm_sec = tzi.DaylightDate.wSecond;
|
|
dst_begin = (long)_mkgmtime(&_tm);
|
|
_tm.tm_mon = tzi.StandardDate.wMonth - 1;
|
|
_tm.tm_mday = tzi.StandardDate.wDay;
|
|
_tm.tm_hour = tzi.StandardDate.wHour;
|
|
_tm.tm_min = tzi.StandardDate.wMinute;
|
|
_tm.tm_sec = tzi.StandardDate.wSecond;
|
|
dst_end = (long)_mkgmtime(&_tm);
|
|
}
|
|
else
|
|
{
|
|
_daylight = 0;
|
|
_dstbias = 0;
|
|
}
|
|
|
|
}
|
|
_tz_is_set = 1;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* _get_tzname (MSVCRT.@)
|
|
*/
|
|
int CDECL _get_tzname(size_t *ret, char *buf, size_t bufsize, int index)
|
|
{
|
|
char *str_timezone;
|
|
|
|
switch (index)
|
|
{
|
|
case 0:
|
|
str_timezone = tz_name;
|
|
break;
|
|
|
|
case 1:
|
|
str_timezone = tz_dst_name;
|
|
break;
|
|
|
|
default:
|
|
*_errno() = EINVAL;
|
|
return EINVAL;
|
|
}
|
|
|
|
if (!ret || (!buf && (bufsize > 0)) || (buf && !bufsize))
|
|
{
|
|
*_errno() = EINVAL;
|
|
return EINVAL;
|
|
}
|
|
|
|
*ret = strlen(str_timezone) + 1;
|
|
if(!buf && !bufsize)
|
|
return 0;
|
|
|
|
strncpy(buf, str_timezone, bufsize);
|
|
return 0;
|
|
}
|