1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Windows/Time.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/Defs.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Time.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NWindows { 10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NTime { 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kNumTimeQuantumsInSecond = 10000000; 13baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kFileTimeStartYear = 1601; 14baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kDosTimeStartYear = 1980; 15baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kUnixTimeStartYear = 1970; 16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear)); 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 19baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #if defined(_WIN32) && !defined(UNDER_CE) 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft)); 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft.dwLowDateTime = 0; 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft.dwHighDateTime = 0; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 res; 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!GetSecondsSince1601(kDosTimeStartYear + (dosTime >> 25), (dosTime >> 21) & 0xF, (dosTime >> 16) & 0x1F, 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (dosTime >> 11) & 0x1F, (dosTime >> 5) & 0x3F, (dosTime & 0x1F) * 2, res)) 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res *= kNumTimeQuantumsInSecond; 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft.dwLowDateTime = (UInt32)res; 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft.dwHighDateTime = (UInt32)(res >> 32); 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 37baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kHighDosTime = 0xFF9FBF7D; 38baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kLowDosTime = 0x210000; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define PERIOD_4 (4 * 365 + 1) 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define PERIOD_100 (PERIOD_4 * 25 - 1) 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define PERIOD_400 (PERIOD_100 * 4 + 1) 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 44baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #if defined(_WIN32) && !defined(UNDER_CE) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WORD datePart, timePart; 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!::FileTimeToDosDateTime(&ft, &datePart, &timePart)) 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dosTime = (ft.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime; 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dosTime = (((UInt32)datePart) << 16) + timePart; 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned year, mon, day, hour, min, sec; 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 v64 = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32); 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned temp; 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 v; 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v64 += (kNumTimeQuantumsInSecond * 2 - 1); 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v64 /= kNumTimeQuantumsInSecond; 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sec = (unsigned)(v64 % 60); 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v64 /= 60; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync min = (unsigned)(v64 % 60); 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v64 /= 60; 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync hour = (unsigned)(v64 % 24); 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v64 /= 24; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v = (UInt32)v64; 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync year = (unsigned)(kFileTimeStartYear + v / PERIOD_400 * 400); 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v %= PERIOD_400; 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync temp = (unsigned)(v / PERIOD_100); 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (temp == 4) 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync temp = 3; 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync year += temp * 100; 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v -= temp * PERIOD_100; 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync temp = v / PERIOD_4; 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (temp == 25) 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync temp = 24; 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync year += temp * 4; 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v -= temp * PERIOD_4; 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync temp = v / 365; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (temp == 4) 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync temp = 3; 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync year += temp; 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v -= temp * 365; 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ms[1] = 29; 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (mon = 1; mon <= 12; mon++) 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned s = ms[mon - 1]; 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (v < s) 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v -= s; 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync day = (unsigned)v + 1; 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dosTime = kLowDosTime; 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (year < kDosTimeStartYear) 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync year -= kDosTimeStartYear; 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dosTime = kHighDosTime; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (year >= 128) 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dosTime = (year << 25) | (mon << 21) | (day << 16) | (hour << 11) | (min << 5) | (sec >> 1); 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 118baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond; 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft.dwLowDateTime = (DWORD)v; 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft.dwHighDateTime = (DWORD)(v >> 32); 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 125baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (winTime < kUnixTimeStartValue) 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unixTime = 0; 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond; 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (winTime > 0xFFFFFFFF) 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unixTime = 0xFFFFFFFF; 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unixTime = (UInt32)winTime; 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 143baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync resSeconds = 0; 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 || 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numYears = year - kFileTimeStartYear; 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400; 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ms[1] = 29; 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync month--; 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (unsigned i = 0; i < month; i++) 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDays += ms[i]; 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDays += day - 1; 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec; 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 163baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid GetCurUtcFileTime(FILETIME &ft) 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SYSTEMTIME st; 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync GetSystemTime(&st); 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SystemTimeToFileTime(&st, &ft); 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 171