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