about summary refs log tree commit diff
path: root/src/rt/rust_builtin.cpp
diff options
context:
space:
mode:
authorChris Peterson <cpeterson@mozilla.com>2012-02-18 01:21:26 -0800
committerChris Peterson <cpeterson@mozilla.com>2012-02-18 01:21:26 -0800
commit123a920f598ddf1bbf07faace11cf9b9fadaa151 (patch)
tree053375142f4f2ebd4e7d9bd1510c68905a9a1509 /src/rt/rust_builtin.cpp
parentef6f6285893ca2546d740771b4c8046bfa68f668 (diff)
downloadrust-123a920f598ddf1bbf07faace11cf9b9fadaa151.tar.gz
rust-123a920f598ddf1bbf07faace11cf9b9fadaa151.zip
std: Fix Windows system time conversion for get_time()
Diffstat (limited to 'src/rt/rust_builtin.cpp')
-rw-r--r--src/rt/rust_builtin.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index ecc73204f29..d17741ac56b 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -393,18 +393,21 @@ rust_ptr_eq(type_desc *t, rust_box *a, rust_box *b) {
 #if defined(__WIN32__)
 extern "C" CDECL void
 get_time(uint32_t *sec, uint32_t *usec) {
-    rust_task *task = rust_task_thread::get_task();
-    SYSTEMTIME systemTime;
     FILETIME fileTime;
-    GetSystemTime(&systemTime);
-    if (!SystemTimeToFileTime(&systemTime, &fileTime)) {
-        task->fail();
-        return;
-    }
-
-    // FIXME: This is probably completely wrong.
-    *sec = fileTime.dwHighDateTime;
-    *usec = fileTime.dwLowDateTime;
+    GetSystemTimeAsFileTime(&fileTime);
+
+    // A FILETIME contains a 64-bit value representing the number of
+    // hectonanosecond (100-nanosecond) intervals since 1601-01-01T00:00:00Z.
+    // http://support.microsoft.com/kb/167296/en-us
+    ULARGE_INTEGER ul;
+    ul.LowPart = fileTime.dwLowDateTime;
+    ul.HighPart = fileTime.dwHighDateTime;
+    uint64_t ns_since_1601 = ul.QuadPart / 10;
+
+    const uint64_t NANOSECONDS_FROM_1601_TO_1970 = 11644473600000000u;
+    uint64_t ns_since_1970 = ns_since_1601 - NANOSECONDS_FROM_1601_TO_1970;
+    *sec = ns_since_1970 / 1000000;
+    *usec = ns_since_1970 % 1000000;
 }
 #else
 extern "C" CDECL void