timefn.cpp 7.6 KB

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