From b7f20588336760d0968c323d34b0d07d323b8ec8 Mon Sep 17 00:00:00 2001 From: cheatfate Date: Mon, 30 May 2016 13:18:31 +0300 Subject: [PATCH 1/2] Resolve #3059 Make getTimezone() to work properly on FreeBSD and NetBSD. --- lib/pure/times.nim | 107 ++++++++++++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 31 deletions(-) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index e0ee884a80..6fafb12b37 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -64,8 +64,9 @@ when defined(posix) and not defined(JS): proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {. importc: "gettimeofday", header: "".} - var - timezone {.importc, header: "".}: int + when not defined(freebsd) and not defined(netbsd): + var timezone {.importc, header: "".}: int + var tzname {.importc, header: "" .}: array[0..1, cstring] # we also need tzset() to make sure that tzname is initialized proc tzset() {.importc, header: "".} @@ -416,18 +417,32 @@ when not defined(JS): when not defined(JS): # C wrapper: + when defined(freebsd) or defined(netbsd): + type + StructTM {.importc: "struct tm", final.} = object + second {.importc: "tm_sec".}, + minute {.importc: "tm_min".}, + hour {.importc: "tm_hour".}, + monthday {.importc: "tm_mday".}, + month {.importc: "tm_mon".}, + year {.importc: "tm_year".}, + weekday {.importc: "tm_wday".}, + yearday {.importc: "tm_yday".}, + isdst {.importc: "tm_isdst".}: cint + gmtoff {.importc: "tm_gmtoff".}: clong + else: + type + StructTM {.importc: "struct tm", final.} = object + second {.importc: "tm_sec".}, + minute {.importc: "tm_min".}, + hour {.importc: "tm_hour".}, + monthday {.importc: "tm_mday".}, + month {.importc: "tm_mon".}, + year {.importc: "tm_year".}, + weekday {.importc: "tm_wday".}, + yearday {.importc: "tm_yday".}, + isdst {.importc: "tm_isdst".}: cint type - StructTM {.importc: "struct tm", final.} = object - second {.importc: "tm_sec".}, - minute {.importc: "tm_min".}, - hour {.importc: "tm_hour".}, - monthday {.importc: "tm_mday".}, - month {.importc: "tm_mon".}, - year {.importc: "tm_year".}, - weekday {.importc: "tm_wday".}, - yearday {.importc: "tm_yday".}, - isdst {.importc: "tm_isdst".}: cint - TimeInfoPtr = ptr StructTM Clock {.importc: "clock_t".} = distinct int @@ -457,24 +472,47 @@ when not defined(JS): const weekDays: array [0..6, WeekDay] = [ dSun, dMon, dTue, dWed, dThu, dFri, dSat] - TimeInfo(second: int(tm.second), - minute: int(tm.minute), - hour: int(tm.hour), - monthday: int(tm.monthday), - month: Month(tm.month), - year: tm.year + 1900'i32, - weekday: weekDays[int(tm.weekday)], - yearday: int(tm.yearday), - isDST: tm.isdst > 0, - tzname: if local: - if tm.isdst > 0: - getTzname().DST + when defined(freebsd) or defined(netbsd): + TimeInfo(second: int(tm.second), + minute: int(tm.minute), + hour: int(tm.hour), + monthday: int(tm.monthday), + month: Month(tm.month), + year: tm.year + 1900'i32, + weekday: weekDays[int(tm.weekday)], + yearday: int(tm.yearday), + isDST: tm.isdst > 0, + tzname: if local: + if tm.isdst > 0: + getTzname().DST + else: + getTzname().nonDST else: - getTzname().nonDST - else: - "UTC", - timezone: if local: getTimezone() else: 0 - ) + "UTC", + # BSD stores in `gmtoff` offset east of UTC in seconds, + # but posix systems using west of UTC in seconds + timezone: if local: -(tm.gmtoff) else: 0 + ) + else: + TimeInfo(second: int(tm.second), + minute: int(tm.minute), + hour: int(tm.hour), + monthday: int(tm.monthday), + month: Month(tm.month), + year: tm.year + 1900'i32, + weekday: weekDays[int(tm.weekday)], + yearday: int(tm.yearday), + isDST: tm.isdst > 0, + tzname: if local: + if tm.isdst > 0: + getTzname().DST + else: + getTzname().nonDST + else: + "UTC", + timezone: if local: getTimezone() else: 0 + ) + proc timeInfoToTM(t: TimeInfo): StructTM = const @@ -564,7 +602,14 @@ when not defined(JS): return ($tzname[0], $tzname[1]) proc getTimezone(): int = - return timezone + when defined(freebsd) or defined(netbsd): + var a = timec(nil) + let lt = localtime(addr(a)) + # BSD stores in `gmtoff` offset east of UTC in seconds, + # but posix systems using west of UTC in seconds + return -(lt.gmtoff) + else: + return timezone proc fromSeconds(since1970: float): Time = Time(since1970) From 2264bd6097792ea0057b7c45cba28c418dc7f3aa Mon Sep 17 00:00:00 2001 From: cheatfate Date: Mon, 30 May 2016 14:39:29 +0300 Subject: [PATCH 2/2] Adding OpenBSD to defines --- lib/pure/times.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 6fafb12b37..f9d341e321 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -64,7 +64,7 @@ when defined(posix) and not defined(JS): proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {. importc: "gettimeofday", header: "".} - when not defined(freebsd) and not defined(netbsd): + when not defined(freebsd) and not defined(netbsd) and not defined(openbsd): var timezone {.importc, header: "".}: int var tzname {.importc, header: "" .}: array[0..1, cstring] @@ -417,7 +417,7 @@ when not defined(JS): when not defined(JS): # C wrapper: - when defined(freebsd) or defined(netbsd): + when defined(freebsd) or defined(netbsd) or defined(openbsd): type StructTM {.importc: "struct tm", final.} = object second {.importc: "tm_sec".}, @@ -472,7 +472,7 @@ when not defined(JS): const weekDays: array [0..6, WeekDay] = [ dSun, dMon, dTue, dWed, dThu, dFri, dSat] - when defined(freebsd) or defined(netbsd): + when defined(freebsd) or defined(netbsd) or defined(openbsd): TimeInfo(second: int(tm.second), minute: int(tm.minute), hour: int(tm.hour), @@ -602,7 +602,7 @@ when not defined(JS): return ($tzname[0], $tzname[1]) proc getTimezone(): int = - when defined(freebsd) or defined(netbsd): + when defined(freebsd) or defined(netbsd) or defined(openbsd): var a = timec(nil) let lt = localtime(addr(a)) # BSD stores in `gmtoff` offset east of UTC in seconds,