unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

timefn.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
4{
5#ifdef _WIN_ALL
6 FILETIME ft;
7 GetWinFT(&ft);
8 FILETIME lft;
9
10 if (WinNT() < WNT_VISTA)
11 {
12 // SystemTimeToTzSpecificLocalTime based code produces 1 hour error on XP.
13 FileTimeToLocalFileTime(&ft,&lft);
14 }
15 else
16 {
17 // We use these functions instead of FileTimeToLocalFileTime according to
18 // MSDN recommendation: "To account for daylight saving time
19 // when converting a file time to a local time ..."
20 SYSTEMTIME st1,st2;
21 FileTimeToSystemTime(&ft,&st1);
22 SystemTimeToTzSpecificLocalTime(NULL,&st1,&st2);
23 SystemTimeToFileTime(&st2,&lft);
24
25 // Correct precision loss (low 4 decimal digits) in FileTimeToSystemTime.
26 FILETIME rft;
27 SystemTimeToFileTime(&st1,&rft);
28 uint64 Corrected=INT32TO64(ft.dwHighDateTime,ft.dwLowDateTime)-
29 INT32TO64(rft.dwHighDateTime,rft.dwLowDateTime)+
30 INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime);
31 lft.dwLowDateTime=(DWORD)Corrected;
32 lft.dwHighDateTime=(DWORD)(Corrected>>32);
33 }
34
35 SYSTEMTIME st;
36 FileTimeToSystemTime(&lft,&st);
37 lt->Year=st.wYear;
38 lt->Month=st.wMonth;
39 lt->Day=st.wDay;
40 lt->Hour=st.wHour;
41 lt->Minute=st.wMinute;
42 lt->Second=st.wSecond;
43 lt->wDay=st.wDayOfWeek;
44 lt->yDay=lt->Day-1;
45
46 static int mdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};
47 for (uint I=1;I<lt->Month && I<=ASIZE(mdays);I++)
48 lt->yDay+=mdays[I-1];
49
50 if (lt->Month>2 && IsLeapYear(lt->Year))
51 lt->yDay++;
52#else
53 time_t ut=GetUnix();
54 struct tm *t;
55 t=localtime(&ut);
56
57 lt->Year=t->tm_year+1900;
58 lt->Month=t->tm_mon+1;
59 lt->Day=t->tm_mday;
60 lt->Hour=t->tm_hour;
61 lt->Minute=t->tm_min;
62 lt->Second=t->tm_sec;
63 lt->wDay=t->tm_wday;
64 lt->yDay=t->tm_yday;
65#endif
67}
68
69
71{
72#ifdef _WIN_ALL
73 SYSTEMTIME st;
74 st.wYear=lt->Year;
75 st.wMonth=lt->Month;
76 st.wDay=lt->Day;
77 st.wHour=lt->Hour;
78 st.wMinute=lt->Minute;
79 st.wSecond=lt->Second;
80 st.wMilliseconds=0;
81 st.wDayOfWeek=0;
82 FILETIME lft;
83 if (SystemTimeToFileTime(&st,&lft))
84 {
85 FILETIME ft;
86
87 if (WinNT() < WNT_VISTA)
88 {
89 // TzSpecificLocalTimeToSystemTime based code produces 1 hour error on XP.
90 LocalFileTimeToFileTime(&lft,&ft);
91 }
92 else
93 {
94 // Reverse procedure which we do in GetLocal.
95 SYSTEMTIME st1,st2;
96 FileTimeToSystemTime(&lft,&st2); // st2 might be unequal to st, because we added lt->Reminder to lft.
97 TzSpecificLocalTimeToSystemTime(NULL,&st2,&st1);
98 SystemTimeToFileTime(&st1,&ft);
99
100 // Correct precision loss (low 4 decimal digits) in FileTimeToSystemTime.
101 FILETIME rft;
102 SystemTimeToFileTime(&st2,&rft);
103 uint64 Corrected=INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime)-
104 INT32TO64(rft.dwHighDateTime,rft.dwLowDateTime)+
105 INT32TO64(ft.dwHighDateTime,ft.dwLowDateTime);
106 ft.dwLowDateTime=(DWORD)Corrected;
107 ft.dwHighDateTime=(DWORD)(Corrected>>32);
108 }
109
110 SetWinFT(&ft);
111 }
112 else
113 Reset();
114#else
115 struct tm t;
116
117 t.tm_sec=lt->Second;
118 t.tm_min=lt->Minute;
119 t.tm_hour=lt->Hour;
120 t.tm_mday=lt->Day;
121 t.tm_mon=lt->Month-1;
122 t.tm_year=lt->Year-1900;
123 t.tm_isdst=-1;
124 SetUnix(mktime(&t));
125#endif
126 itime+=lt->Reminder;
127}
128
129
130
131
132#ifdef _WIN_ALL
133void RarTime::GetWinFT(FILETIME *ft)
134{
135 _ULARGE_INTEGER ul;
136 ul.QuadPart=GetWin();
137 ft->dwLowDateTime=ul.LowPart;
138 ft->dwHighDateTime=ul.HighPart;
139}
140
141
142void RarTime::SetWinFT(FILETIME *ft)
143{
144 _ULARGE_INTEGER ul = {ft->dwLowDateTime, ft->dwHighDateTime};
145 SetWin(ul.QuadPart);
146}
147#endif
148
149
150// Get 64-bit representation of Windows FILETIME (100ns since 01.01.1601).
152{
153 return itime/(TICKS_PER_SECOND/10000000);
154}
155
156
157// Set 64-bit representation of Windows FILETIME (100ns since 01.01.1601).
159{
160 itime=WinTime*(TICKS_PER_SECOND/10000000);
161}
162
163
165{
166 return time_t(GetUnixNS()/1000000000);
167}
168
169
170void RarTime::SetUnix(time_t ut)
171{
172 if (sizeof(ut)>4)
173 SetUnixNS(uint64(ut)*1000000000);
174 else
175 {
176 // Convert 32-bit and possibly signed time_t to uint32 first,
177 // uint64 cast is not enough. Otherwise sign can expand to 64 bits.
178 SetUnixNS(uint64(uint32(ut))*1000000000);
179 }
180}
181
182
183// Get the high precision Unix time in nanoseconds since 01-01-1970.
185{
186 // 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970.
187 uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
188 return itime*(1000000000/TICKS_PER_SECOND)-ushift;
189}
190
191
192// Set the high precision Unix time in nanoseconds since 01-01-1970.
194{
195 // 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970.
196 uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
197 itime=(ns+ushift)/(1000000000/TICKS_PER_SECOND);
198}
199
200
202{
203 RarLocalTime lt;
204 GetLocal(&lt);
205 uint DosTime=(lt.Second/2)|(lt.Minute<<5)|(lt.Hour<<11)|
206 (lt.Day<<16)|(lt.Month<<21)|((lt.Year-1980)<<25);
207 return DosTime;
208}
209
210
212{
213 RarLocalTime lt;
214 lt.Second=(DosTime & 0x1f)*2;
215 lt.Minute=(DosTime>>5) & 0x3f;
216 lt.Hour=(DosTime>>11) & 0x1f;
217 lt.Day=(DosTime>>16) & 0x1f;
218 lt.Month=(DosTime>>21) & 0x0f;
219 lt.Year=(DosTime>>25)+1980;
220 lt.Reminder=0;
221 SetLocal(&lt);
222}
223
224
225void RarTime::GetText(wchar *DateStr,size_t MaxSize,bool FullMS)
226{
227 if (IsSet())
228 {
229 RarLocalTime lt;
230 GetLocal(&lt);
231 if (FullMS)
232 swprintf(DateStr,MaxSize,L"%u-%02u-%02u %02u:%02u:%02u,%09u",lt.Year,lt.Month,lt.Day,lt.Hour,lt.Minute,lt.Second,lt.Reminder*(1000000000/TICKS_PER_SECOND));
233 else
234 swprintf(DateStr,MaxSize,L"%u-%02u-%02u %02u:%02u",lt.Year,lt.Month,lt.Day,lt.Hour,lt.Minute);
235 }
236 else
237 {
238 // We use escape before '?' to avoid weird C trigraph characters.
239 wcsncpyz(DateStr,L"\?\?\?\?-\?\?-\?\? \?\?:\?\?",MaxSize);
240 }
241}
242
243
244#ifndef SFX_MODULE
245void RarTime::SetIsoText(const wchar *TimeText)
246{
247 int Field[6];
248 memset(Field,0,sizeof(Field));
249 for (uint DigitCount=0;*TimeText!=0;TimeText++)
250 if (IsDigit(*TimeText))
251 {
252 int FieldPos=DigitCount<4 ? 0:(DigitCount-4)/2+1;
253 if (FieldPos<ASIZE(Field))
254 Field[FieldPos]=Field[FieldPos]*10+*TimeText-'0';
255 DigitCount++;
256 }
257 RarLocalTime lt;
258 lt.Second=Field[5];
259 lt.Minute=Field[4];
260 lt.Hour=Field[3];
261 lt.Day=Field[2]==0 ? 1:Field[2];
262 lt.Month=Field[1]==0 ? 1:Field[1];
263 lt.Year=Field[0];
264 lt.Reminder=0;
265 SetLocal(&lt);
266}
267#endif
268
269
270#ifndef SFX_MODULE
271void RarTime::SetAgeText(const wchar *TimeText)
272{
273 uint Seconds=0,Value=0;
274 for (uint I=0;TimeText[I]!=0;I++)
275 {
276 wchar Ch=TimeText[I];
277 if (IsDigit(Ch))
278 Value=Value*10+Ch-'0';
279 else
280 {
281 switch(etoupperw(Ch))
282 {
283 case 'D':
284 Seconds+=Value*24*3600;
285 break;
286 case 'H':
287 Seconds+=Value*3600;
288 break;
289 case 'M':
290 Seconds+=Value*60;
291 break;
292 case 'S':
293 Seconds+=Value;
294 break;
295 }
296 Value=0;
297 }
298 }
300 itime-=uint64(Seconds)*TICKS_PER_SECOND;
301}
302#endif
303
304
306{
307#ifdef _WIN_ALL
308 FILETIME ft;
309 SYSTEMTIME st;
310 GetSystemTime(&st);
311 SystemTimeToFileTime(&st,&ft);
312 SetWinFT(&ft);
313#else
314 time_t st;
315 time(&st);
316 SetUnix(st);
317#endif
318}
319
320
321// Add the specified signed number of nanoseconds.
323{
324 ns/=1000000000/TICKS_PER_SECOND; // Convert ns to internal ticks.
325 itime+=(uint64)ns;
326}
327
328
329#ifndef SFX_MODULE
330const wchar *GetMonthName(int Month)
331{
332 return uiGetMonthName(Month);
333}
334#endif
335
336
337bool IsLeapYear(int Year)
338{
339 return (Year&3)==0 && (Year%100!=0 || Year%400==0);
340}
void SetDos(uint DosTime)
Definition: timefn.cpp:211
uint GetDos()
Definition: timefn.cpp:201
void GetLocal(RarLocalTime *lt)
Definition: timefn.cpp:3
void SetWin(uint64 WinTime)
Definition: timefn.cpp:158
void SetUnix(time_t ut)
Definition: timefn.cpp:170
time_t GetUnix()
Definition: timefn.cpp:164
static const uint TICKS_PER_SECOND
Definition: timefn.hpp:21
void SetAgeText(const wchar *TimeText)
Definition: timefn.cpp:271
void Adjust(int64 ns)
Definition: timefn.cpp:322
void SetUnixNS(uint64 ns)
Definition: timefn.cpp:193
uint64 GetWin()
Definition: timefn.cpp:151
void GetText(wchar *DateStr, size_t MaxSize, bool FullMS)
Definition: timefn.cpp:225
void SetCurrentTime()
Definition: timefn.cpp:305
void SetIsoText(const wchar *TimeText)
Definition: timefn.cpp:245
bool IsSet()
Definition: timefn.hpp:58
uint64 itime
Definition: timefn.hpp:25
uint64 GetUnixNS()
Definition: timefn.cpp:184
void SetLocal(RarLocalTime *lt)
Definition: timefn.cpp:70
void Reset()
Definition: timefn.hpp:57
DWORD WinNT()
Definition: isnt.cpp:3
@ WNT_VISTA
Definition: isnt.hpp:6
#define ASIZE(x)
Definition: rardefs.hpp:10
wchar_t wchar
Definition: rartypes.hpp:13
int64_t int64
Definition: rartypes.hpp:12
unsigned int uint
Definition: rartypes.hpp:8
uint64_t uint64
Definition: rartypes.hpp:11
uint32_t uint32
Definition: rartypes.hpp:9
#define INT32TO64(high, low)
Definition: rartypes.hpp:19
#define Ch(x, y, z)
Definition: sha256.cpp:26
void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:275
bool IsDigit(int ch)
Definition: strfn.cpp:151
wchar etoupperw(wchar c)
Definition: strfn.cpp:141
uint Year
Definition: timefn.hpp:6
uint Minute
Definition: timefn.hpp:10
uint Reminder
Definition: timefn.hpp:12
uint yDay
Definition: timefn.hpp:14
uint wDay
Definition: timefn.hpp:13
uint Second
Definition: timefn.hpp:11
uint Hour
Definition: timefn.hpp:9
uint Day
Definition: timefn.hpp:8
uint Month
Definition: timefn.hpp:7
const wchar * GetMonthName(int Month)
Definition: timefn.cpp:330
bool IsLeapYear(int Year)
Definition: timefn.cpp:337
const wchar * uiGetMonthName(int Month)
Definition: uiconsole.cpp:461