1 // 2 // ftime.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // The ftime() family of functions, which return the system date and time in a 7 // time structure. 8 // 9 #include <corecrt_internal_time.h> 10 #include <sys/timeb.h> 11 #include <sys/types.h> 12 13 14 15 // Cache for the minutes count for with DST status was last assessed 16 // CRT_REFACTOR TODO Check synchronization of access to this global variable. 17 static __time64_t elapsed_minutes_cache = 0; 18 19 20 21 // Three values of dstflag_cache 22 #define DAYLIGHT_TIME 1 23 #define STANDARD_TIME 0 24 #define UNKNOWN_TIME -1 25 26 27 28 // Cache for the last determined DST status: 29 static int dstflag_cache = UNKNOWN_TIME; 30 31 32 33 // Returns the system time in a structure; returns zero on success; returns an 34 // error code on failure. 35 template <typename TimeType, typename TimeBType> common_ftime_s(TimeBType * const tp)36static errno_t __cdecl common_ftime_s(TimeBType* const tp) throw() 37 { 38 _VALIDATE_RETURN_ERRCODE(tp != nullptr, EINVAL) 39 40 __tzset(); 41 42 long timezone = 0; 43 _ERRCHECK(_get_timezone(&timezone)); 44 tp->timezone = static_cast<short>(timezone / 60); 45 46 __crt_filetime_union system_time; 47 __acrt_GetSystemTimePreciseAsFileTime(&system_time._filetime); 48 49 // Obtain the current Daylight Savings Time status. Note that the status is 50 // cached and only updated once per minute, if necessary. 51 TimeType const current_minutes_value = static_cast<TimeType>(system_time._scalar / 600000000ll); 52 if (static_cast<__time64_t>(current_minutes_value) != elapsed_minutes_cache) 53 { 54 TIME_ZONE_INFORMATION tz_info; 55 DWORD const tz_state = GetTimeZoneInformation(&tz_info); 56 if (tz_state == 0xFFFFFFFF) 57 { 58 dstflag_cache = UNKNOWN_TIME; 59 } 60 else 61 { 62 // Must be very careful when determining whether or not Daylight 63 // Savings Time is in effect: 64 if (tz_state == TIME_ZONE_ID_DAYLIGHT && 65 tz_info.DaylightDate.wMonth != 0 && 66 tz_info.DaylightBias != 0) 67 { 68 dstflag_cache = DAYLIGHT_TIME; 69 } 70 else 71 { 72 // Assume Standard Time: 73 dstflag_cache = STANDARD_TIME; 74 } 75 } 76 77 elapsed_minutes_cache = current_minutes_value; 78 } 79 80 tp->dstflag = static_cast<short>(dstflag_cache); 81 tp->millitm = static_cast<unsigned short>((system_time._scalar / 10000ll) % 1000ll); 82 tp->time = static_cast<TimeType>((system_time._scalar - _EPOCH_BIAS) / 10000000ll); 83 84 return 0; 85 } 86 _ftime32_s(__timeb32 * const tp)87extern "C" errno_t __cdecl _ftime32_s(__timeb32* const tp) 88 { 89 return common_ftime_s<__time32_t>(tp); 90 } 91 _ftime32(__timeb32 * const tp)92extern "C" void __cdecl _ftime32(__timeb32* const tp) 93 { 94 _ftime32_s(tp); 95 } 96 _ftime64_s(__timeb64 * const tp)97extern "C" errno_t __cdecl _ftime64_s(__timeb64* const tp) 98 { 99 return common_ftime_s<__time64_t>(tp); 100 } 101 _ftime64(__timeb64 * const tp)102extern "C" void __cdecl _ftime64(__timeb64* const tp) 103 { 104 _ftime64_s(tp); 105 } 106