diff --git a/core/os/os.cpp b/core/os/os.cpp
index 7ba8c02e0c9..9b8c1e828fa 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -86,6 +86,9 @@ uint64_t OS::get_system_time_secs() const {
uint64_t OS::get_system_time_msecs() const {
return 0;
}
+double OS::get_subsecond_unix_time() const {
+ return 0.0;
+}
void OS::debug_break(){
// something
diff --git a/core/os/os.h b/core/os/os.h
index a728e6b7e11..db9915541f3 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -437,6 +437,7 @@ public:
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
virtual uint64_t get_system_time_msecs() const;
+ virtual double get_subsecond_unix_time() const; // For use in Time::get_unix_time().
virtual void delay_usec(uint32_t p_usec) const = 0;
virtual void add_frame_delay(bool p_can_draw);
diff --git a/core/os/time.cpp b/core/os/time.cpp
index c7d4b73c1c7..d726edbb118 100644
--- a/core/os/time.cpp
+++ b/core/os/time.cpp
@@ -392,7 +392,7 @@ Dictionary Time::get_time_zone_from_system() const {
}
double Time::get_unix_time_from_system() const {
- return OS::get_singleton()->get_unix_time();
+ return OS::get_singleton()->get_subsecond_unix_time();
}
uint64_t Time::get_ticks_msec() const {
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index ef081a9d4b2..7a22fdc168a 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -552,6 +552,7 @@
Returns the current UNIX epoch timestamp in seconds.
[b]Important:[/b] This is the system clock that the user can manually set. [b]Never use[/b] this method for precise time calculation since its results are also subject to automatic adjustments by the operating system. [b]Always use[/b] [method get_ticks_usec] or [method get_ticks_msec] for precise time calculation instead, since they are guaranteed to be monotonic (i.e. never decrease).
+ [b]Note:[/b] To get a floating point timestamp with sub-second precision, use [method Time.get_unix_time_from_system].
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 22bcdc35dae..90e16506a2f 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -172,6 +172,12 @@ uint64_t OS_Unix::get_system_time_msecs() const {
return uint64_t(tv_now.tv_sec) * 1000 + uint64_t(tv_now.tv_usec) / 1000;
}
+double OS_Unix::get_subsecond_unix_time() const {
+ struct timeval tv_now;
+ gettimeofday(&tv_now, nullptr);
+ return (double)tv_now.tv_sec + double(tv_now.tv_usec) / 1000000;
+}
+
OS::Date OS_Unix::get_date(bool utc) const {
time_t t = time(nullptr);
struct tm lt;
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index f277bbbfc88..33596fa014e 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -80,6 +80,7 @@ public:
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
virtual uint64_t get_system_time_msecs() const;
+ virtual double get_subsecond_unix_time() const;
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index a1a14c7f319..f53a39c4392 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -547,6 +547,23 @@ uint64_t OS_UWP::get_unix_time() const {
return (*(uint64_t *)&ft - *(uint64_t *)&fep) / 10000000;
};
+double OS_UWP::get_subsecond_unix_time() const {
+ // 1 Windows tick is 100ns
+ const uint64_t WINDOWS_TICKS_PER_SECOND = 10000000;
+ const uint64_t TICKS_TO_UNIX_EPOCH = 116444736000000000LL;
+
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ FILETIME ft;
+ SystemTimeToFileTime(&st, &ft);
+ uint64_t ticks_time;
+ ticks_time = ft.dwHighDateTime;
+ ticks_time <<= 32;
+ ticks_time |= ft.dwLowDateTime;
+
+ return (double)(ticks_time - TICKS_TO_UNIX_EPOCH) / WINDOWS_TICKS_PER_SECOND;
+}
+
void OS_UWP::delay_usec(uint32_t p_usec) const {
int msec = p_usec < 1000 ? 1 : p_usec / 1000;
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 04aa55d5f01..68e99da7350 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -193,6 +193,7 @@ public:
virtual Time get_time(bool utc) const;
virtual TimeZoneInfo get_time_zone_info() const;
virtual uint64_t get_unix_time() const;
+ virtual double get_subsecond_unix_time() const;
virtual bool can_draw() const;
virtual Error set_cwd(const String &p_cwd);
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index aac901c97ba..c1e51b8ebdf 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -2584,6 +2584,23 @@ uint64_t OS_Windows::get_system_time_msecs() const {
return (uint64_t)(ret / WINDOWS_TICK - MSEC_TO_UNIX_EPOCH);
}
+double OS_Windows::get_subsecond_unix_time() const {
+ // 1 Windows tick is 100ns
+ const uint64_t WINDOWS_TICKS_PER_SECOND = 10000000;
+ const uint64_t TICKS_TO_UNIX_EPOCH = 116444736000000000LL;
+
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ FILETIME ft;
+ SystemTimeToFileTime(&st, &ft);
+ uint64_t ticks_time;
+ ticks_time = ft.dwHighDateTime;
+ ticks_time <<= 32;
+ ticks_time |= ft.dwLowDateTime;
+
+ return (double)(ticks_time - TICKS_TO_UNIX_EPOCH) / WINDOWS_TICKS_PER_SECOND;
+}
+
void OS_Windows::delay_usec(uint32_t p_usec) const {
if (p_usec < 1000)
Sleep(1);
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 451d463469e..abc369d27f9 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -520,6 +520,7 @@ public:
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
virtual uint64_t get_system_time_msecs() const;
+ virtual double get_subsecond_unix_time() const;
virtual bool can_draw() const;
virtual Error set_cwd(const String &p_cwd);