time: fix repetitive time.now().local().local().local() offsetting the time further and further (#13861)
parent
9c1981a309
commit
02c80bd445
|
@ -117,5 +117,9 @@ fn convert_ctime(t C.tm, microsecond int) Time {
|
||||||
second: t.tm_sec
|
second: t.tm_sec
|
||||||
microsecond: microsecond
|
microsecond: microsecond
|
||||||
unix: make_unix_time(t)
|
unix: make_unix_time(t)
|
||||||
|
// for the actual code base when we
|
||||||
|
// call convert_ctime, it is always
|
||||||
|
// when we manage the local time.
|
||||||
|
is_local: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ pub:
|
||||||
second int
|
second int
|
||||||
microsecond int
|
microsecond int
|
||||||
unix i64
|
unix i64
|
||||||
|
is_local bool // used to make time.now().local().local() == time.now().local()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatDelimiter contains different time formats.
|
// FormatDelimiter contains different time formats.
|
||||||
|
@ -348,7 +349,7 @@ pub fn (d Duration) str() string {
|
||||||
|
|
||||||
// offset returns time zone UTC offset in seconds.
|
// offset returns time zone UTC offset in seconds.
|
||||||
pub fn offset() int {
|
pub fn offset() int {
|
||||||
t := now()
|
t := utc()
|
||||||
local := t.local()
|
local := t.local()
|
||||||
return int(local.unix - t.unix)
|
return int(local.unix - t.unix)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ struct C.tm {
|
||||||
|
|
||||||
fn C.timegm(&C.tm) C.time_t
|
fn C.timegm(&C.tm) C.time_t
|
||||||
|
|
||||||
// fn C.gmtime_r(&tm, &gbuf)
|
// prefering localtime_r over the localtime because
|
||||||
|
// from docs localtime_r is thread safe,
|
||||||
fn C.localtime_r(t &C.time_t, tm &C.tm)
|
fn C.localtime_r(t &C.time_t, tm &C.tm)
|
||||||
|
|
||||||
fn make_unix_time(t C.tm) i64 {
|
fn make_unix_time(t C.tm) i64 {
|
||||||
|
@ -29,6 +30,9 @@ fn make_unix_time(t C.tm) i64 {
|
||||||
|
|
||||||
// local returns t with the location set to local time.
|
// local returns t with the location set to local time.
|
||||||
pub fn (t Time) local() Time {
|
pub fn (t Time) local() Time {
|
||||||
|
if t.is_local {
|
||||||
|
return t
|
||||||
|
}
|
||||||
loc_tm := C.tm{}
|
loc_tm := C.tm{}
|
||||||
C.localtime_r(voidptr(&t.unix), &loc_tm)
|
C.localtime_r(voidptr(&t.unix), &loc_tm)
|
||||||
return convert_ctime(loc_tm, t.microsecond)
|
return convert_ctime(loc_tm, t.microsecond)
|
||||||
|
|
|
@ -254,3 +254,12 @@ fn test_since() {
|
||||||
d2 := time.since(t1)
|
d2 := time.since(t1)
|
||||||
assert d2 >= 40_000_000
|
assert d2 >= 40_000_000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// issue relate https://github.com/vlang/v/issues/13828
|
||||||
|
// problem: the local method add 2h on the time in a Linux machine
|
||||||
|
// the other machine are not tested in a local env
|
||||||
|
fn test_recursive_local_call() {
|
||||||
|
now_tm := time.now()
|
||||||
|
assert now_tm.str() == now_tm.local().str()
|
||||||
|
assert now_tm.local().str() == now_tm.local().local().str()
|
||||||
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ pub fn (t Time) local() Time {
|
||||||
hour: u16(t.hour)
|
hour: u16(t.hour)
|
||||||
minute: u16(t.minute)
|
minute: u16(t.minute)
|
||||||
second: u16(t.second)
|
second: u16(t.second)
|
||||||
|
millisecond: u16(t.microsecond / 1000)
|
||||||
}
|
}
|
||||||
st_local := SystemTime{}
|
st_local := SystemTime{}
|
||||||
C.SystemTimeToTzSpecificLocalTime(voidptr(0), &st_utc, &st_local)
|
C.SystemTimeToTzSpecificLocalTime(voidptr(0), &st_utc, &st_local)
|
||||||
|
|
Loading…
Reference in New Issue