From 5d979e313177cbe023e15a958a8dd7261f49402b Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 14 Apr 2026 12:45:23 +0300 Subject: [PATCH] =?UTF-8?q?time:=20Performance=20Issues=20with=20time.now?= =?UTF-8?q?=EF=BC=9F=20(fixes=20#19554)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vlib/time/time_darwin.c.v | 2 +- vlib/time/time_nix.c.v | 20 ++++++++++++++++++-- vlib/time/time_solaris.c.v | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/vlib/time/time_darwin.c.v b/vlib/time/time_darwin.c.v index 949c16623..14466e4b3 100644 --- a/vlib/time/time_darwin.c.v +++ b/vlib/time/time_darwin.c.v @@ -64,7 +64,7 @@ fn darwin_now() Time { nsec := int(epoch_ns % i64(second)) loc_tm := C.tm{} C.localtime_r(voidptr(&sec), &loc_tm) - return convert_ctime(loc_tm, nsec) + return convert_ctime_with_unix(loc_tm, nsec, sec + i64(loc_tm.tm_gmtoff)) } // darwin_utc returns a better precision current time for macos diff --git a/vlib/time/time_nix.c.v b/vlib/time/time_nix.c.v index ee1ed4058..73ef85531 100644 --- a/vlib/time/time_nix.c.v +++ b/vlib/time/time_nix.c.v @@ -31,6 +31,22 @@ fn make_unix_time(t C.tm) i64 { return unsafe { i64(C.timegm(&t)) } } +// localtime_r already resolves the local UTC offset, so callers can reuse it. +@[inline] +fn convert_ctime_with_unix(t C.tm, nanosecond int, unix i64) Time { + return Time{ + year: t.tm_year + 1900 + month: t.tm_mon + 1 + day: t.tm_mday + hour: t.tm_hour + minute: t.tm_min + second: t.tm_sec + nanosecond: nanosecond + unix: unix + is_local: true + } +} + // local returns t with the location set to local time. pub fn (t Time) local() Time { if t.is_local { @@ -39,7 +55,7 @@ pub fn (t Time) local() Time { loc_tm := C.tm{} t_ := t.unix() C.localtime_r(voidptr(&t_), &loc_tm) - return convert_ctime(loc_tm, t.nanosecond) + return convert_ctime_with_unix(loc_tm, t.nanosecond, t_ + i64(loc_tm.tm_gmtoff)) } // in most systems, these are __quad_t, which is an i64 @@ -86,7 +102,7 @@ fn linux_now() Time { C.clock_gettime(C.CLOCK_REALTIME, &ts) loc_tm := C.tm{} C.localtime_r(voidptr(&ts.tv_sec), &loc_tm) - return convert_ctime(loc_tm, int(ts.tv_nsec)) + return convert_ctime_with_unix(loc_tm, int(ts.tv_nsec), i64(ts.tv_sec) + i64(loc_tm.tm_gmtoff)) } fn linux_utc() Time { diff --git a/vlib/time/time_solaris.c.v b/vlib/time/time_solaris.c.v index c97735951..b07e35960 100644 --- a/vlib/time/time_solaris.c.v +++ b/vlib/time/time_solaris.c.v @@ -10,7 +10,7 @@ fn solaris_now() Time { C.clock_gettime(C.CLOCK_REALTIME, &ts) loc_tm := C.tm{} C.localtime_r(voidptr(&ts.tv_sec), &loc_tm) - return convert_ctime(loc_tm, int(ts.tv_nsec)) + return convert_ctime_with_unix(loc_tm, int(ts.tv_nsec), i64(ts.tv_sec) + i64(loc_tm.tm_gmtoff)) } fn solaris_utc() Time { -- 2.39.5