00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 module mango.sys.Epoch;
00041
00042
00043
00044
00045
00046
00047
00048 private import mango.sys.OS;
00049
00050 version (Posix)
00051 {
00052 extern (C) int mktime (tm *);
00053 extern (C) tm *gmtime (int *);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 abstract class Epoch
00068 {
00069 private static long beginTime;
00070
00071 const long InvalidEpoch = -1;
00072
00073
00074
00075
00076
00077
00078
00079
00080 struct Fields
00081 {
00082 int year,
00083 month,
00084 day,
00085 hour,
00086 min,
00087 sec,
00088 ms,
00089 dow;
00090
00091
00092
00093
00094
00095
00096 private static char[][] Days =
00097 [
00098 "Sunday",
00099 "Monday",
00100 "Tuesday",
00101 "Wednesday",
00102 "Thursday",
00103 "Friday",
00104 "Saturday",
00105 ];
00106
00107
00108
00109
00110
00111 private static char[][] Months =
00112 [
00113 "null",
00114 "January",
00115 "February",
00116 "March",
00117 "April",
00118 "May",
00119 "June",
00120 "July",
00121 "August",
00122 "September",
00123 "October",
00124 "November",
00125 "December",
00126 ];
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 void setDate (int year, int month, int day, int dow = 0)
00140 {
00141 this.year = year;
00142 this.month = month;
00143 this.day = day;
00144 this.dow = dow;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 void setTime (int hour, int min, int sec, int ms = 0)
00159 {
00160 this.hour = hour;
00161 this.min = min;
00162 this.sec = sec;
00163 this.ms = ms;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172 char[] toDowName ()
00173 {
00174 return Days[dow];
00175 }
00176
00177
00178
00179
00180
00181
00182
00183 char[] toMonthName ()
00184 {
00185 return Months[month];
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 version (Win32)
00195 {
00196
00197
00198
00199
00200
00201
00202
00203 long getUtcTime ()
00204 {
00205 SYSTEMTIME sTime;
00206 FILETIME fTime;
00207
00208 sTime.wYear = year;
00209 sTime.wMonth = month;
00210 sTime.wDayOfWeek = 0;
00211 sTime.wDay = day;
00212 sTime.wHour = hour;
00213 sTime.wMinute = min;
00214 sTime.wSecond = sec;
00215 sTime.wMilliseconds = ms;
00216
00217 SystemTimeToFileTime (&sTime, &fTime);
00218
00219 return fromFileTime (&fTime);
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229 void setUtcTime (long time)
00230 {
00231 SYSTEMTIME sTime;
00232 FILETIME fTime;
00233
00234 toFileTime (&fTime, time);
00235 FileTimeToSystemTime (&fTime, &sTime);
00236
00237 year = sTime.wYear;
00238 month = sTime.wMonth;
00239 day = sTime.wDay;
00240 hour = sTime.wHour;
00241 min = sTime.wMinute;
00242 sec = sTime.wSecond;
00243 ms = sTime.wMilliseconds;
00244 dow = sTime.wDayOfWeek;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254 void setLocalTime (long time)
00255 {
00256 FILETIME fTime,
00257 local;
00258
00259 toFileTime (&fTime, time);
00260 FileTimeToLocalFileTime (&fTime, &local);
00261 setUtcTime (fromFileTime (&local));
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272 version (Posix)
00273 {
00274
00275
00276
00277
00278
00279
00280
00281 long getUtcTime ()
00282 {
00283 tm t;
00284
00285 t.tm_year = year - 1900;
00286 t.tm_mon = month - 1;
00287 t.tm_mday = day;
00288 t.tm_hour = hour;
00289 t.tm_min = min;
00290 t.tm_sec = sec;
00291 return 1000L * cast(long) mktime(&t) + ms;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 void setUtcTime (long time)
00303 {
00304 ms = time % 1000;
00305 int utc = time / 1000;
00306
00307 synchronized (lock)
00308 {
00309 tm* t = gmtime (&utc);
00310 assert (t);
00311
00312 year = t.tm_year + 1900;
00313 month = t.tm_mon + 1;
00314 day = t.tm_mday;
00315 hour = t.tm_hour;
00316 min = t.tm_min;
00317 sec = t.tm_sec;
00318 dow = t.tm_wday;
00319 }
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329 void setLocalTime (long time)
00330 {
00331 ms = time % 1000;
00332 int utc = time / 1000;
00333
00334 synchronized (lock)
00335 {
00336 tm* t = localtime (&utc);
00337 year = t.tm_year + 1900;
00338 month = t.tm_mon + 1;
00339 day = t.tm_mday;
00340 hour = t.tm_hour;
00341 min = t.tm_min;
00342 sec = t.tm_sec;
00343 dow = t.tm_wday;
00344 }
00345 }
00346 }
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356 final static long startTime ()
00357 {
00358 return startTime;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368 version (Win32)
00369 {
00370 private static long epochOffset;
00371
00372
00373
00374
00375
00376
00377
00378
00379 static long utcMilli ()
00380 {
00381 FILETIME fTime;
00382
00383 GetSystemTimeAsFileTime (&fTime);
00384 return fromFileTime (&fTime);
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394 static long utcNano ()
00395 {
00396 FILETIME fTime;
00397
00398 GetSystemTimeAsFileTime (&fTime);
00399 long tmp = (cast(long) fTime.dwHighDateTime) << 32 |
00400 fTime.dwLowDateTime;
00401
00402
00403 return (tmp - epochOffset) * 100;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412 static int tzMinutes ()
00413 {
00414 TIME_ZONE_INFORMATION tz;
00415
00416 int ret = GetTimeZoneInformation (&tz);
00417 return -tz.Bias;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 static this ()
00427 {
00428 SYSTEMTIME sTime;
00429 FILETIME fTime;
00430
00431
00432 sTime.wYear = 1970;
00433 sTime.wMonth = 1;
00434 sTime.wDayOfWeek = 0;
00435 sTime.wDay = 1;
00436 sTime.wHour = 0;
00437 sTime.wMinute = 0;
00438 sTime.wSecond = 0;
00439 sTime.wMilliseconds = 0;
00440 SystemTimeToFileTime (&sTime, &fTime);
00441
00442 epochOffset = (cast(long) fTime.dwHighDateTime) << 32 |
00443 fTime.dwLowDateTime;
00444 beginTime = utcMilli();
00445 }
00446
00447
00448
00449
00450
00451
00452
00453 private static long fromFileTime (FILETIME* ft)
00454 {
00455 long tmp = (cast(long) ft.dwHighDateTime) << 32 |
00456 ft.dwLowDateTime;
00457
00458
00459 return (tmp - epochOffset) / 10_000;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468 private static void toFileTime (FILETIME* ft, long et)
00469 {
00470 et = et * 10_000 + epochOffset;
00471
00472 ft.dwHighDateTime = et >> 32;
00473 ft.dwLowDateTime = et & 0xFFFFFFFF;
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482 version (Posix)
00483 {
00484
00485 extern static int timezone;
00486 extern static int daylight;
00487
00488 private static Object lock;
00489
00490
00491
00492
00493
00494
00495
00496 static this()
00497 {
00498 lock = new Object;
00499 beginTime = utcMilli();
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509 static long utcMilli ()
00510 {
00511 timeval tv;
00512
00513 if (gettimeofday (&tv, null))
00514 throw new Exception ("linux timer is not available");
00515
00516 return 1000L * cast(long) tv.tv_sec + tv.tv_usec / 1000;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526 static long utcNano ()
00527 {
00528 timeval tv;
00529
00530 if (gettimeofday (&tv, null))
00531 throw new Exception ("linux timer is not available");
00532
00533 return 1_000_000_000L * cast(long) tv.tv_sec + tv.tv_usec * 1000;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542 static int tzMinutes ()
00543 {
00544
00545 return timezone / 60;
00546 }
00547 }
00548 }