1 //
2 // corecrt_internal_time.h
3 //
4 //      Copyright (c) Microsoft Corporation.  All rights reserved.
5 //
6 // This internal header defines internal utilities for working with the time
7 // library.
8 //
9 #pragma once
10 
11 #include <corecrt.h>
12 #include <corecrt_internal.h>
13 #include <corecrt_internal_traits.h>
14 #include <io.h>
15 #include <sys/utime.h>
16 #include <time.h>
17 
18 #pragma pack(push, _CRT_PACKING)
19 
20 
21 
22 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23 //
24 // Constants
25 //
26 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27 // Number of 100 nanosecond units from 1/1/1601 to 1/1/1970
28 #define _EPOCH_BIAS 116444736000000000ll
29 
30 #define _DAY_SEC       (24 * 60 * 60)    // Seconds in a day
31 #define _YEAR_SEC      (365 * _DAY_SEC)  // Seconds in a year
32 #define _FOUR_YEAR_SEC (1461 * _DAY_SEC) // Seconds in a four-year interval
33 #define _BASE_YEAR     70                // The epoch year (1970)
34 #define _BASE_DOW      4                 // The day of week of 01-Jan-70 (Thursday)
35 
36 // Maximum local time adjustment (GMT + 14 Hours, DST -0 Hours)
37 #define _MAX_LOCAL_TIME (14 * 60 * 60)
38 
39 // Minimum local time adjustment (GMT - 11 Hours, DST - 1 Hours)
40 #define _MIN_LOCAL_TIME (-12 * 60 * 60)
41 
42 #define _TZ_STRINGS_SIZE 64
43 
44 
45 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 //
47 // Global Data
48 //
49 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 extern "C"
51 {
52     extern char const __dnames[];
53     extern char const __mnames[];
54 
55     extern int const _days[];
56     extern int const _lpdays[];
57 }
58 
59 
60 
61 
62 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 //
64 // Integer Traits
65 //
66 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 template <typename TimeType>
68 struct __crt_time_time_t_traits;
69 
70 template <>
71 struct __crt_time_time_t_traits<__time32_t> : __crt_integer_traits<__time32_t>
72 {
73     typedef _timespec32 timespec_type;
74 
75     enum : long
76     {
77         // Number of seconds from 00:00:00, 01/01/1970 UTC to 23:59:59, 01/18/2038 UTC
78         max_time_t = 0x7fffd27f,
79     };
80 
81     enum : unsigned long
82     {
83         // The maximum representable year
84         max_year = 138,  // 2038 is the maximum year
85     };
86 };
87 
88 template <>
89 struct __crt_time_time_t_traits<__time64_t> : __crt_integer_traits<__time64_t>
90 {
91     typedef _timespec64 timespec_type;
92 
93     enum : long long
94     {
95         // Number of seconds from 00:00:00, 01/01/1970 UTC to 07:59:59, 01/19/3001 UTC
96         // Note that the end of the epoch was intended to be 23:59:59, 01/18/3001 UTC,
97         // but this was mistakenly computed from a PST value (thus the 8 hour delta).
98         max_time_t = 0x793582affLL,
99     };
100 
101     enum : unsigned long long
102     {
103         // The maximum representable year
104         max_year = 1101, // 3001 is the maximum year
105     };
106 };
107 
108 
109 
110 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111 //
112 // Combined Traits
113 //
114 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115 template <typename TimeType, typename Character>
116 struct __crt_time_traits
117     : __crt_char_traits<Character>,
118       __crt_time_time_t_traits<TimeType>
119 {
120 };
121 
122 
123 
124 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125 //
126 // Utilities
127 //
128 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
129 // Union to facilitate converting from FILETIME to unsigned __int64
130 union __crt_filetime_union
131 {
132     unsigned __int64 _scalar;
133     FILETIME         _filetime;
134 };
135 
136 
137 
138 extern "C"
139 {
140     int  __cdecl _isindst(_In_ tm* _Time);
141     void __cdecl __tzset();
142     tm*  __cdecl __getgmtimebuf();
143 
144     __time32_t __cdecl __loctotime32_t(int, int, int, int, int, int, int);
145     __time64_t __cdecl __loctotime64_t(int, int, int, int, int, int, int);
146 }
147 
148 
149 
150 // Tests if the given year is a leap year.  The year is not the absolute year;
151 // it is the number of years since 1900.
152 template <typename TimeType>
153 bool __cdecl __crt_time_is_leap_year(TimeType const yr) throw()
154 {
155     if (yr % 4 == 0 && yr % 100 != 0)
156         return true;
157 
158     if ((yr + 1900) % 400 == 0)
159         return true;
160 
161     return false;
162 }
163 
164 // Computes the number of leap years that have elapsed betwwen 1970 up to, but
165 // not including, the specified year.  The year is not the absolute year; it is
166 // the number of years since 1900.
167 template <typename TimeType>
168 TimeType __cdecl __crt_time_elapsed_leap_years(TimeType const yr) throw()
169 {
170     static TimeType const leap_years_between_1900_and_1970 = 17;
171 
172     TimeType const elapsed_leap_years = ((yr - 1) / 4) - ((yr - 1) / 100) + ((yr + 299) / 400);
173 
174     return elapsed_leap_years - leap_years_between_1900_and_1970;
175 }
176 
177 // Tests if the given date is valid (i.e., if such a day actually existed).
178 inline bool __cdecl __crt_time_is_day_valid(int const yr, int const mo, int const dy) throw()
179 {
180     if (dy <= 0)
181         return false;
182 
183     int const days_in_month = _days[mo + 1] - _days[mo];
184     if (dy <= days_in_month)
185         return true;
186 
187     // Special case for February:
188     if (__crt_time_is_leap_year(yr) && mo == 1 && dy <= 29)
189         return true;
190 
191     return false;
192 }
193 
194 inline int __crt_get_2digit_year(int const year) throw()
195 {
196     return (1900 + year) % 100;
197 }
198 
199 inline int __crt_get_century(int const year) throw()
200 {
201     return (1900 + year) / 100;
202 }
203 
204 extern "C" _Success_(return > 0) size_t __cdecl _Wcsftime_l(
205     _Out_writes_z_(max_size) wchar_t*       string,
206     _In_                     size_t         max_size,
207     _In_z_                   wchar_t const* format,
208     _In_                     tm const*      timeptr,
209     _In_opt_                 void*          lc_time_arg,
210     _In_opt_                 _locale_t      locale
211     );
212 
213 _Check_return_ _Deref_ret_z_
214 extern "C" wchar_t** __cdecl __wide_tzname();
215 
216 #pragma pack(pop)
217