1 #include "rar.hpp"
2 
RarTime()3 RarTime::RarTime()
4 {
5   Reset();
6 }
7 
8 #ifdef _WIN_ALL
operator =(FILETIME & ft)9 RarTime& RarTime::operator =(FILETIME &ft)
10 {
11   FILETIME lft;
12   FileTimeToLocalFileTime(&ft,&lft);
13   SYSTEMTIME st;
14   FileTimeToSystemTime(&lft,&st);
15   rlt.Year=st.wYear;
16   rlt.Month=st.wMonth;
17   rlt.Day=st.wDay;
18   rlt.Hour=st.wHour;
19   rlt.Minute=st.wMinute;
20   rlt.Second=st.wSecond;
21   rlt.wDay=st.wDayOfWeek;
22   rlt.yDay=rlt.Day-1;
23   for (uint I=1;I<rlt.Month;I++)
24   {
25     static int mdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};
26     rlt.yDay+=mdays[I-1];
27   }
28   if (rlt.Month>2 && IsLeapYear(rlt.Year))
29     rlt.yDay++;
30 
31   st.wMilliseconds=0;
32   FILETIME zft;
33   SystemTimeToFileTime(&st,&zft);
34 
35   // Calculate the time reminder, which is the part of time smaller
36   // than 1 second, represented in 100-nanosecond intervals.
37   rlt.Reminder=INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime)-
38                INT32TO64(zft.dwHighDateTime,zft.dwLowDateTime);
39   return(*this);
40 }
41 
42 
GetWin32(FILETIME * ft)43 void RarTime::GetWin32(FILETIME *ft)
44 {
45   SYSTEMTIME st;
46   st.wYear=rlt.Year;
47   st.wMonth=rlt.Month;
48   st.wDay=rlt.Day;
49   st.wHour=rlt.Hour;
50   st.wMinute=rlt.Minute;
51   st.wSecond=rlt.Second;
52   st.wMilliseconds=0;
53   FILETIME lft;
54   SystemTimeToFileTime(&st,&lft);
55   lft.dwLowDateTime+=rlt.Reminder;
56   if (lft.dwLowDateTime<rlt.Reminder)
57     lft.dwHighDateTime++;
58   LocalFileTimeToFileTime(&lft,ft);
59 }
60 #endif
61 
62 
63 #if defined(_UNIX) || defined(_EMX)
operator =(time_t ut)64 RarTime& RarTime::operator =(time_t ut)
65 {
66   struct tm *t;
67   t=localtime(&ut);
68 
69   rlt.Year=t->tm_year+1900;
70   rlt.Month=t->tm_mon+1;
71   rlt.Day=t->tm_mday;
72   rlt.Hour=t->tm_hour;
73   rlt.Minute=t->tm_min;
74   rlt.Second=t->tm_sec;
75   rlt.Reminder=0;
76   rlt.wDay=t->tm_wday;
77   rlt.yDay=t->tm_yday;
78   return(*this);
79 }
80 
81 
GetUnix()82 time_t RarTime::GetUnix()
83 {
84   struct tm t;
85 
86   t.tm_sec=rlt.Second;
87   t.tm_min=rlt.Minute;
88   t.tm_hour=rlt.Hour;
89   t.tm_mday=rlt.Day;
90   t.tm_mon=rlt.Month-1;
91   t.tm_year=rlt.Year-1900;
92   t.tm_isdst=-1;
93   return(mktime(&t));
94 }
95 #endif
96 
97 // Return the stored time as 64-bit number of 100-nanosecond intervals
98 // since January 1, 1601 for Windows and since January 1, 1970 for Unix.
99 // Actually we do not care since which date this time starts from
100 // as long as this date is the same for GetRaw and SetRaw. We use the value
101 // returned by GetRaw() for time comparisons and for relative operations
102 // like SetRaw(GetRaw()-C).
GetRaw()103 int64 RarTime::GetRaw()
104 {
105   if (!IsSet())
106     return(0);
107 #ifdef _WIN_ALL
108   FILETIME ft;
109   GetWin32(&ft);
110   return(INT32TO64(ft.dwHighDateTime,ft.dwLowDateTime));
111 #elif defined(_UNIX) || defined(_EMX)
112   time_t ut=GetUnix();
113   return(INT32TO64(0,ut)*10000000+rlt.Reminder);
114 #else
115   // We should never be here. It is better to use standard time functions.
116 
117   // Days since 1970. We do not care about leap years for code simplicity.
118   // It should be acceptable for comprisons.
119   int64 r=(rlt.Year-1970)*365; // Days since 1970.
120 
121   // Cumulative day value for beginning of every month.
122   static int MonthToDay[12]={0,31,60,91,121,152,182,213,244,274,305,335};
123 
124   r+=MonthToDay[rlt.Month-1]+(rlt.Day-1); // Add days since beginning of year.
125   r=r*24+rlt.Hour;   // Hours.
126   r=r*60+rlt.Minute; // Minutes.
127   r=r*60+rlt.Second; // Seconds.
128   r=r*10000000+rlt.Reminder; // 100-nanosecond intervals.
129 
130   return(r);
131 #endif
132 }
133 
134 
135 #ifndef SFX_MODULE
SetRaw(int64 RawTime)136 void RarTime::SetRaw(int64 RawTime)
137 {
138 #ifdef _WIN_ALL
139   FILETIME ft;
140   ft.dwHighDateTime=(DWORD)(RawTime>>32);
141   ft.dwLowDateTime=(DWORD)RawTime;
142   *this=ft;
143 #elif defined(_UNIX) || defined(_EMX)
144   time_t ut=(time_t)(RawTime/10000000);
145   *this=ut;
146   rlt.Reminder=(uint)(RawTime%10000000);
147 #else
148   // We should never be here. It is better to use standard time functions.
149   rlt.Reminder=RawTime%10000000;
150   RawTime/=10000000; // Seconds.
151   rlt.Second=uint(RawTime%60);
152   RawTime/=60;       // Minutes.
153   rlt.Minute=uint(RawTime%60);
154   RawTime/=60;       // Hours.
155   rlt.Hour=uint(RawTime%24);
156   RawTime/=24;       // Days since 1970.
157   rlt.Year=uint(1970+RawTime/365);
158   RawTime%=365;      // Days since beginning of year.
159 
160   // Cumulative day value for beginning of every month.
161   static int MonthToDay[12]={0,31,60,91,121,152,182,213,244,274,305,335};
162 
163   for (int I=0;I<12;I++)
164     if (RawTime>=MonthToDay[I])
165     {
166       rlt.Day=uint(RawTime-MonthToDay[I]+1);
167       rlt.Month=I+1;
168     }
169 
170   rlt.wDay=0;
171   rlt.yDay=0;
172 #endif
173 }
174 #endif
175 
176 
operator ==(RarTime & rt)177 bool RarTime::operator == (RarTime &rt)
178 {
179   return(rlt.Year==rt.rlt.Year && rlt.Month==rt.rlt.Month &&
180          rlt.Day==rt.rlt.Day && rlt.Hour==rt.rlt.Hour &&
181          rlt.Minute==rt.rlt.Minute && rlt.Second==rt.rlt.Second &&
182          rlt.Reminder==rt.rlt.Reminder);
183 }
184 
185 
operator <(RarTime & rt)186 bool RarTime::operator < (RarTime &rt)
187 {
188   return(GetRaw()<rt.GetRaw());
189 }
190 
191 
operator <=(RarTime & rt)192 bool RarTime::operator <= (RarTime &rt)
193 {
194   return(*this<rt || *this==rt);
195 }
196 
197 
operator >(RarTime & rt)198 bool RarTime::operator > (RarTime &rt)
199 {
200   return(GetRaw()>rt.GetRaw());
201 }
202 
203 
operator >=(RarTime & rt)204 bool RarTime::operator >= (RarTime &rt)
205 {
206   return(*this>rt || *this==rt);
207 }
208 
209 
GetDos()210 uint RarTime::GetDos()
211 {
212   uint DosTime=(rlt.Second/2)|(rlt.Minute<<5)|(rlt.Hour<<11)|
213                (rlt.Day<<16)|(rlt.Month<<21)|((rlt.Year-1980)<<25);
214   return(DosTime);
215 }
216 
217 
SetDos(uint DosTime)218 void RarTime::SetDos(uint DosTime)
219 {
220   rlt.Second=(DosTime & 0x1f)*2;
221   rlt.Minute=(DosTime>>5) & 0x3f;
222   rlt.Hour=(DosTime>>11) & 0x1f;
223   rlt.Day=(DosTime>>16) & 0x1f;
224   rlt.Month=(DosTime>>21) & 0x0f;
225   rlt.Year=(DosTime>>25)+1980;
226   rlt.Reminder=0;
227 }
228 
229 
230 #if !defined(GUI) || !defined(SFX_MODULE)
GetText(char * DateStr,bool FullYear)231 void RarTime::GetText(char *DateStr,bool FullYear)
232 {
233   if (FullYear)
234     sprintf(DateStr,"%02u-%02u-%u %02u:%02u",rlt.Day,rlt.Month,rlt.Year,rlt.Hour,rlt.Minute);
235   else
236     sprintf(DateStr,"%02u-%02u-%02u %02u:%02u",rlt.Day,rlt.Month,rlt.Year%100,rlt.Hour,rlt.Minute);
237 }
238 #endif
239 
240 
241 #ifndef SFX_MODULE
SetIsoText(const char * TimeText)242 void RarTime::SetIsoText(const char *TimeText)
243 {
244   int Field[6];
245   memset(Field,0,sizeof(Field));
246   for (int DigitCount=0;*TimeText!=0;TimeText++)
247     if (IsDigit(*TimeText))
248     {
249       int FieldPos=DigitCount<4 ? 0:(DigitCount-4)/2+1;
250       if (FieldPos<sizeof(Field)/sizeof(Field[0]))
251         Field[FieldPos]=Field[FieldPos]*10+*TimeText-'0';
252       DigitCount++;
253     }
254   rlt.Second=Field[5];
255   rlt.Minute=Field[4];
256   rlt.Hour=Field[3];
257   rlt.Day=Field[2]==0 ? 1:Field[2];
258   rlt.Month=Field[1]==0 ? 1:Field[1];
259   rlt.Year=Field[0];
260   rlt.Reminder=0;
261 }
262 #endif
263 
264 
265 #ifndef SFX_MODULE
SetAgeText(const char * TimeText)266 void RarTime::SetAgeText(const char *TimeText)
267 {
268   uint Seconds=0,Value=0;
269   for (int I=0;TimeText[I]!=0;I++)
270   {
271     int Ch=TimeText[I];
272     if (IsDigit(Ch))
273       Value=Value*10+Ch-'0';
274     else
275     {
276       switch(etoupper(Ch))
277       {
278         case 'D':
279           Seconds+=Value*24*3600;
280           break;
281         case 'H':
282           Seconds+=Value*3600;
283           break;
284         case 'M':
285           Seconds+=Value*60;
286           break;
287         case 'S':
288           Seconds+=Value;
289           break;
290       }
291       Value=0;
292     }
293   }
294   SetCurrentTime();
295   int64 RawTime=GetRaw();
296   SetRaw(RawTime-INT32TO64(0,Seconds)*10000000);
297 }
298 #endif
299 
300 
SetCurrentTime()301 void RarTime::SetCurrentTime()
302 {
303 #ifdef _WIN_ALL
304   FILETIME ft;
305   SYSTEMTIME st;
306   GetSystemTime(&st);
307   SystemTimeToFileTime(&st,&ft);
308   *this=ft;
309 #else
310   time_t st;
311   time(&st);
312   *this=st;
313 #endif
314 }
315 
316 
317 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
GetMonthName(int Month)318 const char *GetMonthName(int Month)
319 {
320 #ifdef SILENT
321   return("");
322 #else
323   static MSGID MonthID[]={
324          MMonthJan,MMonthFeb,MMonthMar,MMonthApr,MMonthMay,MMonthJun,
325          MMonthJul,MMonthAug,MMonthSep,MMonthOct,MMonthNov,MMonthDec
326   };
327   return(St(MonthID[Month]));
328 #endif
329 }
330 #endif
331 
332 
IsLeapYear(int Year)333 bool IsLeapYear(int Year)
334 {
335   return((Year&3)==0 && (Year%100!=0 || Year%400==0));
336 }
337