1*04e0dc4aSTimo Kreuzer //
2*04e0dc4aSTimo Kreuzer // timeset.cpp
3*04e0dc4aSTimo Kreuzer //
4*04e0dc4aSTimo Kreuzer // Copyright (c) Microsoft Corporation. All rights reserved.
5*04e0dc4aSTimo Kreuzer //
6*04e0dc4aSTimo Kreuzer // The time zone values for the default time zone, and other global time data.
7*04e0dc4aSTimo Kreuzer //
8*04e0dc4aSTimo Kreuzer #include <corecrt_internal_time.h>
9*04e0dc4aSTimo Kreuzer
10*04e0dc4aSTimo Kreuzer #undef _daylight
11*04e0dc4aSTimo Kreuzer #undef _dstbias
12*04e0dc4aSTimo Kreuzer #undef _timezone
13*04e0dc4aSTimo Kreuzer #undef _tzname
14*04e0dc4aSTimo Kreuzer
15*04e0dc4aSTimo Kreuzer
16*04e0dc4aSTimo Kreuzer
17*04e0dc4aSTimo Kreuzer __crt_state_management::dual_state_global<long> _timezone; // Pacific Time Zone
18*04e0dc4aSTimo Kreuzer __crt_state_management::dual_state_global<int> _daylight; // Daylight Saving Time (DST) in timezone
19*04e0dc4aSTimo Kreuzer __crt_state_management::dual_state_global<long> _dstbias; // DST offset in seconds
20*04e0dc4aSTimo Kreuzer
21*04e0dc4aSTimo Kreuzer // Note that NT POSIX's TZNAME_MAX is only 10.
22*04e0dc4aSTimo Kreuzer
23*04e0dc4aSTimo Kreuzer #define _PST_STRING "PST"
24*04e0dc4aSTimo Kreuzer #define _PDT_STRING "PDT"
25*04e0dc4aSTimo Kreuzer
26*04e0dc4aSTimo Kreuzer #define L_PST_STRING L"PST"
27*04e0dc4aSTimo Kreuzer #define L_PDT_STRING L"PDT"
28*04e0dc4aSTimo Kreuzer
29*04e0dc4aSTimo Kreuzer static char tzstd_program[_TZ_STRINGS_SIZE] = { _PST_STRING };
30*04e0dc4aSTimo Kreuzer static char tzdst_program[_TZ_STRINGS_SIZE] = { _PDT_STRING };
31*04e0dc4aSTimo Kreuzer
32*04e0dc4aSTimo Kreuzer static wchar_t w_tzstd_program[_TZ_STRINGS_SIZE] = { L_PST_STRING };
33*04e0dc4aSTimo Kreuzer static wchar_t w_tzdst_program[_TZ_STRINGS_SIZE] = { L_PDT_STRING };
34*04e0dc4aSTimo Kreuzer
35*04e0dc4aSTimo Kreuzer #ifdef _CRT_GLOBAL_STATE_ISOLATION
36*04e0dc4aSTimo Kreuzer static char tzstd_os[_TZ_STRINGS_SIZE] = { _PST_STRING };
37*04e0dc4aSTimo Kreuzer static char tzdst_os[_TZ_STRINGS_SIZE] = { _PDT_STRING };
38*04e0dc4aSTimo Kreuzer
39*04e0dc4aSTimo Kreuzer static wchar_t w_tzstd_os[_TZ_STRINGS_SIZE] = { L_PST_STRING };
40*04e0dc4aSTimo Kreuzer static wchar_t w_tzdst_os[_TZ_STRINGS_SIZE] = { L_PDT_STRING };
41*04e0dc4aSTimo Kreuzer #endif
42*04e0dc4aSTimo Kreuzer
43*04e0dc4aSTimo Kreuzer static char* tzname_states[__crt_state_management::state_index_count][2] =
44*04e0dc4aSTimo Kreuzer {
45*04e0dc4aSTimo Kreuzer { tzstd_program, tzdst_program },
46*04e0dc4aSTimo Kreuzer #ifdef _CRT_GLOBAL_STATE_ISOLATION
47*04e0dc4aSTimo Kreuzer { tzstd_os, tzdst_os }
48*04e0dc4aSTimo Kreuzer #endif
49*04e0dc4aSTimo Kreuzer };
50*04e0dc4aSTimo Kreuzer
51*04e0dc4aSTimo Kreuzer static wchar_t* w_tzname_states[__crt_state_management::state_index_count][2] =
52*04e0dc4aSTimo Kreuzer {
53*04e0dc4aSTimo Kreuzer { w_tzstd_program, w_tzdst_program },
54*04e0dc4aSTimo Kreuzer #ifdef _CRT_GLOBAL_STATE_ISOLATION
55*04e0dc4aSTimo Kreuzer { w_tzstd_os, w_tzdst_os }
56*04e0dc4aSTimo Kreuzer #endif
57*04e0dc4aSTimo Kreuzer };
58*04e0dc4aSTimo Kreuzer
59*04e0dc4aSTimo Kreuzer static __crt_state_management::dual_state_global<char **> _tzname;
60*04e0dc4aSTimo Kreuzer static __crt_state_management::dual_state_global<wchar_t **> w_tzname;
61*04e0dc4aSTimo Kreuzer
62*04e0dc4aSTimo Kreuzer // Initializer for the timeset globals:
63*04e0dc4aSTimo Kreuzer _CRT_LINKER_FORCE_INCLUDE(__acrt_timeset_initializer);
64*04e0dc4aSTimo Kreuzer
__acrt_initialize_timeset()65*04e0dc4aSTimo Kreuzer extern "C" int __cdecl __acrt_initialize_timeset()
66*04e0dc4aSTimo Kreuzer {
67*04e0dc4aSTimo Kreuzer _timezone.initialize(8 * 3600L);
68*04e0dc4aSTimo Kreuzer _daylight.initialize(1);
69*04e0dc4aSTimo Kreuzer _dstbias.initialize (-3600);
70*04e0dc4aSTimo Kreuzer
71*04e0dc4aSTimo Kreuzer char*** const first_state = _tzname.dangerous_get_state_array();
72*04e0dc4aSTimo Kreuzer for (unsigned i = 0; i != __crt_state_management::state_index_count; ++i)
73*04e0dc4aSTimo Kreuzer {
74*04e0dc4aSTimo Kreuzer first_state[i] = tzname_states[i];
75*04e0dc4aSTimo Kreuzer }
76*04e0dc4aSTimo Kreuzer
77*04e0dc4aSTimo Kreuzer wchar_t*** const w_first_state = w_tzname.dangerous_get_state_array();
78*04e0dc4aSTimo Kreuzer for (unsigned i = 0; i != __crt_state_management::state_index_count; ++i)
79*04e0dc4aSTimo Kreuzer {
80*04e0dc4aSTimo Kreuzer w_first_state[i] = w_tzname_states[i];
81*04e0dc4aSTimo Kreuzer }
82*04e0dc4aSTimo Kreuzer
83*04e0dc4aSTimo Kreuzer return 0;
84*04e0dc4aSTimo Kreuzer }
85*04e0dc4aSTimo Kreuzer
_get_daylight(int * const result)86*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _get_daylight(int* const result)
87*04e0dc4aSTimo Kreuzer {
88*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL);
89*04e0dc4aSTimo Kreuzer
90*04e0dc4aSTimo Kreuzer // This variable is correctly inited at startup, so no need to check if
91*04e0dc4aSTimo Kreuzer // CRT init finished.
92*04e0dc4aSTimo Kreuzer *result = _daylight.value();
93*04e0dc4aSTimo Kreuzer return 0;
94*04e0dc4aSTimo Kreuzer }
95*04e0dc4aSTimo Kreuzer
_get_dstbias(long * result)96*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _get_dstbias(long* result)
97*04e0dc4aSTimo Kreuzer {
98*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL);
99*04e0dc4aSTimo Kreuzer
100*04e0dc4aSTimo Kreuzer // This variable is correctly inited at startup, so no need to check if
101*04e0dc4aSTimo Kreuzer // CRT init finished.
102*04e0dc4aSTimo Kreuzer *result = _dstbias.value();
103*04e0dc4aSTimo Kreuzer return 0;
104*04e0dc4aSTimo Kreuzer }
105*04e0dc4aSTimo Kreuzer
_get_timezone(long * result)106*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _get_timezone(long* result)
107*04e0dc4aSTimo Kreuzer {
108*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL);
109*04e0dc4aSTimo Kreuzer
110*04e0dc4aSTimo Kreuzer // This variable is correctly inited at startup, so no need to check if
111*04e0dc4aSTimo Kreuzer // CRT init finished.
112*04e0dc4aSTimo Kreuzer *result = _timezone.value();
113*04e0dc4aSTimo Kreuzer return 0;
114*04e0dc4aSTimo Kreuzer }
115*04e0dc4aSTimo Kreuzer
_get_tzname(size_t * const length,char * const buffer,size_t const size_in_bytes,int const index)116*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _get_tzname(
117*04e0dc4aSTimo Kreuzer size_t* const length,
118*04e0dc4aSTimo Kreuzer char* const buffer,
119*04e0dc4aSTimo Kreuzer size_t const size_in_bytes,
120*04e0dc4aSTimo Kreuzer int const index)
121*04e0dc4aSTimo Kreuzer {
122*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(
123*04e0dc4aSTimo Kreuzer (buffer != nullptr && size_in_bytes > 0) ||
124*04e0dc4aSTimo Kreuzer (buffer == nullptr && size_in_bytes == 0),
125*04e0dc4aSTimo Kreuzer EINVAL);
126*04e0dc4aSTimo Kreuzer
127*04e0dc4aSTimo Kreuzer if (buffer != nullptr)
128*04e0dc4aSTimo Kreuzer buffer[0] = '\0';
129*04e0dc4aSTimo Kreuzer
130*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(length != nullptr, EINVAL);
131*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(index == 0 || index == 1, EINVAL);
132*04e0dc4aSTimo Kreuzer
133*04e0dc4aSTimo Kreuzer // _tzname is correctly inited at startup, so no need to check if
134*04e0dc4aSTimo Kreuzer // CRT init finished.
135*04e0dc4aSTimo Kreuzer *length = strlen(_tzname.value()[index]) + 1;
136*04e0dc4aSTimo Kreuzer
137*04e0dc4aSTimo Kreuzer // If the buffer pointer is null, the caller is interested only in the size
138*04e0dc4aSTimo Kreuzer // of the string, not in the actual value of the string:
139*04e0dc4aSTimo Kreuzer if (buffer == nullptr)
140*04e0dc4aSTimo Kreuzer return 0;
141*04e0dc4aSTimo Kreuzer
142*04e0dc4aSTimo Kreuzer if (*length > size_in_bytes)
143*04e0dc4aSTimo Kreuzer return ERANGE;
144*04e0dc4aSTimo Kreuzer
145*04e0dc4aSTimo Kreuzer return strcpy_s(buffer, size_in_bytes, _tzname.value()[index]);
146*04e0dc4aSTimo Kreuzer }
147*04e0dc4aSTimo Kreuzer
148*04e0dc4aSTimo Kreuzer
149*04e0dc4aSTimo Kreuzer
150*04e0dc4aSTimo Kreuzer // Day names must be three character abbreviations strung together
151*04e0dc4aSTimo Kreuzer extern "C" const char __dnames[] =
152*04e0dc4aSTimo Kreuzer {
153*04e0dc4aSTimo Kreuzer "SunMonTueWedThuFriSat"
154*04e0dc4aSTimo Kreuzer };
155*04e0dc4aSTimo Kreuzer
156*04e0dc4aSTimo Kreuzer // Month names must be three character abbreviations strung together
157*04e0dc4aSTimo Kreuzer extern "C" const char __mnames[] =
158*04e0dc4aSTimo Kreuzer {
159*04e0dc4aSTimo Kreuzer "JanFebMarAprMayJunJulAugSepOctNovDec"
160*04e0dc4aSTimo Kreuzer };
161*04e0dc4aSTimo Kreuzer
162*04e0dc4aSTimo Kreuzer
163*04e0dc4aSTimo Kreuzer
164*04e0dc4aSTimo Kreuzer // Accessors for the global time data
__daylight()165*04e0dc4aSTimo Kreuzer extern "C" int* __cdecl __daylight()
166*04e0dc4aSTimo Kreuzer {
167*04e0dc4aSTimo Kreuzer return &_daylight.value();
168*04e0dc4aSTimo Kreuzer }
169*04e0dc4aSTimo Kreuzer
__dstbias()170*04e0dc4aSTimo Kreuzer extern "C" long* __cdecl __dstbias()
171*04e0dc4aSTimo Kreuzer {
172*04e0dc4aSTimo Kreuzer return &_dstbias.value();
173*04e0dc4aSTimo Kreuzer }
174*04e0dc4aSTimo Kreuzer
__timezone()175*04e0dc4aSTimo Kreuzer extern "C" long* __cdecl __timezone()
176*04e0dc4aSTimo Kreuzer {
177*04e0dc4aSTimo Kreuzer return &_timezone.value();
178*04e0dc4aSTimo Kreuzer }
179*04e0dc4aSTimo Kreuzer
__tzname()180*04e0dc4aSTimo Kreuzer extern "C" char** __cdecl __tzname()
181*04e0dc4aSTimo Kreuzer {
182*04e0dc4aSTimo Kreuzer return _tzname.value();
183*04e0dc4aSTimo Kreuzer }
184*04e0dc4aSTimo Kreuzer
__wide_tzname()185*04e0dc4aSTimo Kreuzer extern "C" wchar_t** __cdecl __wide_tzname()
186*04e0dc4aSTimo Kreuzer {
187*04e0dc4aSTimo Kreuzer return w_tzname.value();
188*04e0dc4aSTimo Kreuzer }
189