reactos/sdk/lib/crt/time/timezone.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;
}