mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
times.Timezone changes (#8527)
* Use floorDiv in times.nim * New implementation of times.Timezone * Tweak doc comments * Fix typo
This commit is contained in:
committed by
Andreas Rumpf
parent
b77d910e4e
commit
33ed8f7e73
@@ -40,6 +40,10 @@
|
||||
- ``proc `-`*(a, b: Time): int64`` in the ``times`` module has changed return type
|
||||
to ``times.Duration`` in order to support higher time resolutions.
|
||||
The proc is no longer deprecated.
|
||||
|
||||
- The ``times.Timezone`` is now an immutable ref-type that must be initialized
|
||||
with an explicit constructor (``newTimezone``).
|
||||
|
||||
- ``posix.Timeval.tv_sec`` has changed type to ``posix.Time``.
|
||||
|
||||
- ``math.`mod` `` for floats now behaves the same as ``mod`` for integers
|
||||
|
||||
@@ -276,20 +276,22 @@ type
|
||||
FixedTimeUnit* = range[Nanoseconds..Weeks] ## Subrange of ``TimeUnit`` that only includes units of fixed duration.
|
||||
## These are the units that can be represented by a ``Duration``.
|
||||
|
||||
Timezone* = object ## Timezone interface for supporting ``DateTime``'s of arbritary timezones.
|
||||
## The ``times`` module only supplies implementations for the systems local time and UTC.
|
||||
## The members ``zoneInfoFromUtc`` and ``zoneInfoFromTz`` should not be accessed directly
|
||||
## and are only exported so that ``Timezone`` can be implemented by other modules.
|
||||
zoneInfoFromUtc*: proc (time: Time): ZonedTime {.tags: [], raises: [], benign.}
|
||||
zoneInfoFromTz*: proc (adjTime: Time): ZonedTime {.tags: [], raises: [], benign.}
|
||||
name*: string ## The name of the timezone, f.ex 'Europe/Stockholm' or 'Etc/UTC'. Used for checking equality.
|
||||
## Se also: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
Timezone* = ref object ## \
|
||||
## Timezone interface for supporting ``DateTime``'s of arbritary
|
||||
## timezones. The ``times`` module only supplies implementations for the
|
||||
## systems local time and UTC.
|
||||
zonedTimeFromTimeImpl: proc (x: Time): ZonedTime
|
||||
{.tags: [], raises: [], benign.}
|
||||
zonedTimeFromAdjTimeImpl: proc (x: Time): ZonedTime
|
||||
{.tags: [], raises: [], benign.}
|
||||
name: string
|
||||
|
||||
ZonedTime* = object ## Represents a zoned instant in time that is not associated with any calendar.
|
||||
## This type is only used for implementing timezones.
|
||||
adjTime*: Time ## Time adjusted to a timezone.
|
||||
utcOffset*: int ## Offset from UTC in seconds.
|
||||
## The point in time represented by ``ZonedTime`` is ``adjTime + utcOffset.seconds``.
|
||||
ZonedTime* = object ## Represents a point in time with an associated
|
||||
## UTC offset and DST flag. This type is only used for
|
||||
## implementing timezones.
|
||||
time*: Time ## The point in time being represented.
|
||||
utcOffset*: int ## The offset in seconds west of UTC,
|
||||
## including any offset due to DST.
|
||||
isDst*: bool ## Determines whether DST is in effect.
|
||||
|
||||
DurationParts* = array[FixedTimeUnit, int64] # Array of Duration parts starts
|
||||
@@ -343,10 +345,9 @@ proc normalize[T: Duration|Time](seconds, nanoseconds: int64): T =
|
||||
result.nanosecond = nanosecond.int
|
||||
|
||||
# Forward declarations
|
||||
proc utcZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .}
|
||||
proc utcZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .}
|
||||
proc localZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .}
|
||||
proc localZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .}
|
||||
proc utcTzInfo(time: Time): ZonedTime {.tags: [], raises: [], benign .}
|
||||
proc localZonedTimeFromTime(time: Time): ZonedTime {.tags: [], raises: [], benign .}
|
||||
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .}
|
||||
proc initTime*(unix: int64, nanosecond: NanosecondRange): Time
|
||||
{.tags: [], raises: [], benign noSideEffect.}
|
||||
|
||||
@@ -493,7 +494,7 @@ proc fromEpochDay(epochday: int64): tuple[monthday: MonthdayRange, month: Month,
|
||||
|
||||
proc getDayOfYear*(monthday: MonthdayRange, month: Month, year: int): YeardayRange {.tags: [], raises: [], benign .} =
|
||||
## Returns the day of the year.
|
||||
## Equivalent with ``initDateTime(day, month, year).yearday``.
|
||||
## Equivalent with ``initDateTime(monthday, month, year, 0, 0, 0).yearday``.
|
||||
assertValidDate monthday, month, year
|
||||
const daysUntilMonth: array[Month, int] = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
|
||||
const daysUntilMonthLeap: array[Month, int] = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
|
||||
@@ -505,11 +506,11 @@ proc getDayOfYear*(monthday: MonthdayRange, month: Month, year: int): YeardayRan
|
||||
|
||||
proc getDayOfWeek*(monthday: MonthdayRange, month: Month, year: int): WeekDay {.tags: [], raises: [], benign .} =
|
||||
## Returns the day of the week enum from day, month and year.
|
||||
## Equivalent with ``initDateTime(day, month, year).weekday``.
|
||||
## Equivalent with ``initDateTime(monthday, month, year, 0, 0, 0).weekday``.
|
||||
assertValidDate monthday, month, year
|
||||
# 1970-01-01 is a Thursday, we adjust to the previous Monday
|
||||
let days = toEpochday(monthday, month, year) - 3
|
||||
let weeks = (if days >= 0: days else: days - 6) div 7
|
||||
let weeks = floorDiv(days, 7)
|
||||
let wd = days - weeks * 7
|
||||
# The value of d is 0 for a Sunday, 1 for a Monday, 2 for a Tuesday, etc.
|
||||
# so we must correct for the WeekDay type.
|
||||
@@ -759,15 +760,14 @@ proc toTime*(dt: DateTime): Time {.tags: [], raises: [], benign.} =
|
||||
seconds.inc dt.hour * secondsInHour
|
||||
seconds.inc dt.minute * 60
|
||||
seconds.inc dt.second
|
||||
# The code above ignores the UTC offset of `timeInfo`,
|
||||
# so we need to compensate for that here.
|
||||
seconds.inc dt.utcOffset
|
||||
result = initTime(seconds, dt.nanosecond)
|
||||
|
||||
proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime =
|
||||
## Create a new ``DateTime`` using ``ZonedTime`` in the specified timezone.
|
||||
let s = zt.adjTime.seconds
|
||||
let epochday = (if s >= 0: s else: s - (secondsInDay - 1)) div secondsInDay
|
||||
let adjTime = zt.time - initDuration(seconds = zt.utcOffset)
|
||||
let s = adjTime.seconds
|
||||
let epochday = floorDiv(s, secondsInDay)
|
||||
var rem = s - epochday * secondsInDay
|
||||
let hour = rem div secondsInHour
|
||||
rem = rem - hour * secondsInHour
|
||||
@@ -784,7 +784,7 @@ proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime =
|
||||
hour: hour,
|
||||
minute: minute,
|
||||
second: second,
|
||||
nanosecond: zt.adjTime.nanosecond,
|
||||
nanosecond: zt.time.nanosecond,
|
||||
weekday: getDayOfWeek(d, m, y),
|
||||
yearday: getDayOfYear(d, m, y),
|
||||
isDst: zt.isDst,
|
||||
@@ -792,14 +792,55 @@ proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime =
|
||||
utcOffset: zt.utcOffset
|
||||
)
|
||||
|
||||
proc inZone*(time: Time, zone: Timezone): DateTime {.tags: [], raises: [], benign.} =
|
||||
## Break down ``time`` into a ``DateTime`` using ``zone`` as the timezone.
|
||||
let zoneInfo = zone.zoneInfoFromUtc(time)
|
||||
result = initDateTime(zoneInfo, zone)
|
||||
proc newTimezone*(
|
||||
name: string,
|
||||
zonedTimeFromTimeImpl: proc (time: Time): ZonedTime {.tags: [], raises: [], benign.},
|
||||
zonedTimeFromAdjTimeImpl: proc (adjTime: Time): ZonedTime {.tags: [], raises: [], benign.}
|
||||
): Timezone =
|
||||
## Create a new ``Timezone``.
|
||||
##
|
||||
## ``zonedTimeFromTimeImpl`` and ``zonedTimeFromAdjTimeImpl`` is used
|
||||
## as the underlying implementations for ``zonedTimeFromTime`` and
|
||||
## ``zonedTimeFromAdjTime``.
|
||||
##
|
||||
## If possible, the name parameter should match the name used in the
|
||||
## tz database. If the timezone doesn't exist in the tz database, or if the
|
||||
## timezone name is unknown, then any string that describes the timezone
|
||||
## unambiguously can be used. Note that the timezones name is used for
|
||||
## checking equality!
|
||||
runnableExamples:
|
||||
proc utcTzInfo(time: Time): ZonedTime =
|
||||
ZonedTime(utcOffset: 0, isDst: false, time: time)
|
||||
let utc = newTimezone("Etc/UTC", utcTzInfo, utcTzInfo)
|
||||
Timezone(
|
||||
name: name,
|
||||
zonedTimeFromTimeImpl: zonedTimeFromTimeImpl,
|
||||
zonedTimeFromAdjTimeImpl: zonedTimeFromAdjTimeImpl
|
||||
)
|
||||
|
||||
proc inZone*(dt: DateTime, zone: Timezone): DateTime {.tags: [], raises: [], benign.} =
|
||||
## Convert ``dt`` into a ``DateTime`` using ``zone`` as the timezone.
|
||||
dt.toTime.inZone(zone)
|
||||
proc name*(zone: Timezone): string =
|
||||
## The name of the timezone.
|
||||
##
|
||||
## If possible, the name will be the name used in the tz database.
|
||||
## If the timezone doesn't exist in the tz database, or if the timezone
|
||||
## name is unknown, then any string that describes the timezone
|
||||
## unambiguously might be used. For example, the string "LOCAL" is used
|
||||
## for the systems local timezone.
|
||||
##
|
||||
## See also: https://en.wikipedia.org/wiki/Tz_database
|
||||
zone.name
|
||||
|
||||
proc zonedTimeFromTime*(zone: Timezone, time: Time): ZonedTime =
|
||||
## Returns the ``ZonedTime`` for some point in time.
|
||||
zone.zonedTimeFromTimeImpl(time)
|
||||
|
||||
proc zonedTimeFromAdjTime*(zone: TimeZone, adjTime: Time): ZonedTime =
|
||||
## Returns the ``ZonedTime`` for some local time.
|
||||
##
|
||||
## Note that the ``Time`` argument does not represent a point in time, it
|
||||
## represent a local time! E.g if ``adjTime`` is ``fromUnix(0)``, it should be
|
||||
## interpreted as 1970-01-01T00:00:00 in the ``zone`` timezone, not in UTC.
|
||||
zone.zonedTimeFromAdjTimeImpl(adjTime)
|
||||
|
||||
proc `$`*(zone: Timezone): string =
|
||||
## Returns the name of the timezone.
|
||||
@@ -807,8 +848,20 @@ proc `$`*(zone: Timezone): string =
|
||||
|
||||
proc `==`*(zone1, zone2: Timezone): bool =
|
||||
## Two ``Timezone``'s are considered equal if their name is equal.
|
||||
runnableExamples:
|
||||
doAssert local() == local()
|
||||
doAssert local() != utc()
|
||||
zone1.name == zone2.name
|
||||
|
||||
proc inZone*(time: Time, zone: Timezone): DateTime {.tags: [], raises: [], benign.} =
|
||||
## Convert ``time`` into a ``DateTime`` using ``zone`` as the timezone.
|
||||
result = initDateTime(zone.zonedTimeFromTime(time), zone)
|
||||
|
||||
proc inZone*(dt: DateTime, zone: Timezone): DateTime {.tags: [], raises: [], benign.} =
|
||||
## Returns a ``DateTime`` representing the same point in time as ``dt`` but
|
||||
## using ``zone`` as the timezone.
|
||||
dt.toTime.inZone(zone)
|
||||
|
||||
proc toAdjTime(dt: DateTime): Time =
|
||||
let epochDay = toEpochday(dt.monthday, dt.month, dt.year)
|
||||
var seconds = epochDay * secondsInDay
|
||||
@@ -843,14 +896,14 @@ when defined(JS):
|
||||
proc getYear(js: JsDate): int {.tags: [], raises: [], benign, importcpp.}
|
||||
proc setFullYear(js: JsDate, year: int): void {.tags: [], raises: [], benign, importcpp.}
|
||||
|
||||
proc localZoneInfoFromUtc(time: Time): ZonedTime =
|
||||
proc localZonedTimeFromTime(time: Time): ZonedTime =
|
||||
let jsDate = newDate(time.seconds.float * 1000)
|
||||
let offset = jsDate.getTimezoneOffset() * secondsInMin
|
||||
result.adjTime = time - initDuration(seconds = offset)
|
||||
result.time = time
|
||||
result.utcOffset = offset
|
||||
result.isDst = false
|
||||
|
||||
proc localZoneInfoFromTz(adjTime: Time): ZonedTime =
|
||||
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime =
|
||||
let utcDate = newDate(adjTime.seconds.float * 1000)
|
||||
let localDate = newDate(utcDate.getUTCFullYear(), utcDate.getUTCMonth(), utcDate.getUTCDate(),
|
||||
utcDate.getUTCHours(), utcDate.getUTCMinutes(), utcDate.getUTCSeconds(), 0)
|
||||
@@ -861,8 +914,8 @@ when defined(JS):
|
||||
if utcDate.getUTCFullYear() in 0 .. 99:
|
||||
localDate.setFullYear(utcDate.getUTCFullYear())
|
||||
|
||||
result.adjTime = adjTime
|
||||
result.utcOffset = localDate.getTimezoneOffset() * secondsInMin
|
||||
result.time = adjTime + initDuration(seconds = result.utcOffset)
|
||||
result.isDst = false
|
||||
|
||||
else:
|
||||
@@ -915,13 +968,13 @@ else:
|
||||
return ((unix - tm.toAdjUnix).int, tm.isdst > 0)
|
||||
return (0, false)
|
||||
|
||||
proc localZoneInfoFromUtc(time: Time): ZonedTime =
|
||||
proc localZonedTimeFromTime(time: Time): ZonedTime =
|
||||
let (offset, dst) = getLocalOffsetAndDst(time.seconds)
|
||||
result.adjTime = time - initDuration(seconds = offset)
|
||||
result.time = time
|
||||
result.utcOffset = offset
|
||||
result.isDst = dst
|
||||
|
||||
proc localZoneInfoFromTz(adjTime: Time): ZonedTime =
|
||||
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime =
|
||||
var adjUnix = adjTime.seconds
|
||||
let past = adjUnix - secondsInDay
|
||||
let (pastOffset, _) = getLocalOffsetAndDst(past)
|
||||
@@ -943,31 +996,34 @@ else:
|
||||
# as a result of offset changes (normally due to dst)
|
||||
let utcUnix = adjTime.seconds + utcOffset
|
||||
let (finalOffset, dst) = getLocalOffsetAndDst(utcUnix)
|
||||
result.adjTime = initTime(utcUnix - finalOffset, adjTime.nanosecond)
|
||||
result.time = initTime(utcUnix, adjTime.nanosecond)
|
||||
result.utcOffset = finalOffset
|
||||
result.isDst = dst
|
||||
|
||||
proc utcZoneInfoFromUtc(time: Time): ZonedTime =
|
||||
result.adjTime = time
|
||||
result.utcOffset = 0
|
||||
result.isDst = false
|
||||
proc utcTzInfo(time: Time): ZonedTime =
|
||||
ZonedTime(utcOffset: 0, isDst: false, time: time)
|
||||
|
||||
proc utcZoneInfoFromTz(adjTime: Time): ZonedTime =
|
||||
utcZoneInfoFromUtc(adjTime) # adjTime == time since we are in UTC
|
||||
var utcInstance {.threadvar.}: Timezone
|
||||
var localInstance {.threadvar.}: Timezone
|
||||
|
||||
proc utc*(): TimeZone =
|
||||
## Get the ``Timezone`` implementation for the UTC timezone.
|
||||
runnableExamples:
|
||||
doAssert now().utc.timezone == utc()
|
||||
doAssert utc().name == "Etc/UTC"
|
||||
Timezone(zoneInfoFromUtc: utcZoneInfoFromUtc, zoneInfoFromTz: utcZoneInfoFromTz, name: "Etc/UTC")
|
||||
if utcInstance.isNil:
|
||||
utcInstance = newTimezone("Etc/UTC", utcTzInfo, utcTzInfo)
|
||||
result = utcInstance
|
||||
|
||||
proc local*(): TimeZone =
|
||||
## Get the ``Timezone`` implementation for the local timezone.
|
||||
runnableExamples:
|
||||
doAssert now().timezone == local()
|
||||
doAssert local().name == "LOCAL"
|
||||
Timezone(zoneInfoFromUtc: localZoneInfoFromUtc, zoneInfoFromTz: localZoneInfoFromTz, name: "LOCAL")
|
||||
if localInstance.isNil:
|
||||
localInstance = newTimezone("LOCAL", localZonedTimeFromTime,
|
||||
localZonedTimeFromAdjTime)
|
||||
result = localInstance
|
||||
|
||||
proc utc*(dt: DateTime): DateTime =
|
||||
## Shorthand for ``dt.inZone(utc())``.
|
||||
@@ -1233,7 +1289,7 @@ proc initDateTime*(monthday: MonthdayRange, month: Month, year: int,
|
||||
second: second,
|
||||
nanosecond: nanosecond
|
||||
)
|
||||
result = initDateTime(zone.zoneInfoFromTz(dt.toAdjTime), zone)
|
||||
result = initDateTime(zone.zonedTimeFromAdjTime(dt.toAdjTime), zone)
|
||||
|
||||
proc initDateTime*(monthday: MonthdayRange, month: Month, year: int,
|
||||
hour: HourRange, minute: MinuteRange, second: SecondRange,
|
||||
@@ -1263,16 +1319,15 @@ proc `+`*(dt: DateTime, interval: TimeInterval): DateTime =
|
||||
let (adjDur, absDur) = evaluateInterval(dt, interval)
|
||||
|
||||
if adjDur != DurationZero:
|
||||
var zInfo = dt.timezone.zoneInfoFromTz(dt.toAdjTime + adjDur)
|
||||
var zt = dt.timezone.zonedTimeFromAdjTime(dt.toAdjTime + adjDur)
|
||||
if absDur != DurationZero:
|
||||
let offsetDur = initDuration(seconds = zInfo.utcOffset)
|
||||
zInfo = dt.timezone.zoneInfoFromUtc(zInfo.adjTime + offsetDur + absDur)
|
||||
result = initDateTime(zInfo, dt.timezone)
|
||||
zt = dt.timezone.zonedTimeFromTime(zt.time + absDur)
|
||||
result = initDateTime(zt, dt.timezone)
|
||||
else:
|
||||
result = initDateTime(zInfo, dt.timezone)
|
||||
result = initDateTime(zt, dt.timezone)
|
||||
else:
|
||||
var zInfo = dt.timezone.zoneInfoFromUtc(dt.toTime + absDur)
|
||||
result = initDateTime(zInfo, dt.timezone)
|
||||
var zt = dt.timezone.zonedTimeFromTime(dt.toTime + absDur)
|
||||
result = initDateTime(zt, dt.timezone)
|
||||
|
||||
proc `-`*(dt: DateTime, interval: TimeInterval): DateTime =
|
||||
## Subtract ``interval`` from ``dt``. Components from ``interval`` are subtracted
|
||||
@@ -1319,7 +1374,7 @@ proc `<=` * (a, b: DateTime): bool =
|
||||
return a.toTime <= b.toTime
|
||||
|
||||
proc `==`*(a, b: DateTime): bool =
|
||||
## Returns true if ``a == b``, that is if both dates represent the same point in datetime.
|
||||
## Returns true if ``a == b``, that is if both dates represent the same point in time.
|
||||
return a.toTime == b.toTime
|
||||
|
||||
|
||||
@@ -2065,7 +2120,7 @@ proc toDateTime(p: ParsedTime, zone: Timezone, f: TimeFormat,
|
||||
|
||||
if p.utcOffset.isNone:
|
||||
# No timezone parsed - assume timezone is `zone`
|
||||
result = initDateTime(zone.zoneInfoFromTz(result.toAdjTime), zone)
|
||||
result = initDateTime(zone.zonedTimeFromAdjTime(result.toAdjTime), zone)
|
||||
else:
|
||||
# Otherwise convert to `zone`
|
||||
result.utcOffset = p.utcOffset.get()
|
||||
@@ -2347,7 +2402,7 @@ proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign, deprec
|
||||
proc toSeconds*(time: Time): float {.tags: [], raises: [], benign, deprecated.} =
|
||||
## Returns the time in seconds since the unix epoch.
|
||||
##
|
||||
## **Deprecated since v0.18.0:** use ``fromUnix`` instead
|
||||
## **Deprecated since v0.18.0:** use ``toUnix`` instead
|
||||
time.seconds.float + time.nanosecond / convert(Seconds, Nanoseconds, 1)
|
||||
|
||||
proc getLocalTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
|
||||
@@ -2390,13 +2445,14 @@ proc timeInfoToTime*(dt: DateTime): Time {.tags: [], benign, deprecated.} =
|
||||
when defined(JS):
|
||||
var start = getTime()
|
||||
proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} =
|
||||
## get the milliseconds from the start of the program.
|
||||
## **Deprecated since v0.8.10:** use ``epochTime`` or ``cpuTime`` instead.
|
||||
let dur = getTime() - start
|
||||
result = (convert(Seconds, Milliseconds, dur.seconds) +
|
||||
convert(Nanoseconds, Milliseconds, dur.nanosecond)).int
|
||||
else:
|
||||
proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} =
|
||||
## get the milliseconds from the start of the program.
|
||||
##
|
||||
## **Deprecated since v0.8.10:** use ``epochTime`` or ``cpuTime`` instead.
|
||||
when defined(macosx):
|
||||
result = toInt(toFloat(int(getClock())) / (toFloat(clocksPerSec) / 1000.0))
|
||||
else:
|
||||
@@ -2417,7 +2473,7 @@ proc getDayOfWeek*(day, month, year: int): WeekDay {.tags: [], raises: [], beni
|
||||
proc getDayOfWeekJulian*(day, month, year: int): WeekDay {.deprecated.} =
|
||||
## Returns the day of the week enum from day, month and year,
|
||||
## according to the Julian calendar.
|
||||
## **Deprecated since v0.18.0:**
|
||||
## **Deprecated since v0.18.0**
|
||||
# Day & month start from one.
|
||||
let
|
||||
a = (14 - month) div 12
|
||||
@@ -2425,3 +2481,23 @@ proc getDayOfWeekJulian*(day, month, year: int): WeekDay {.deprecated.} =
|
||||
m = month + (12*a) - 2
|
||||
d = (5 + day + y + (y div 4) + (31*m) div 12) mod 7
|
||||
result = d.WeekDay
|
||||
|
||||
proc adjTime*(zt: ZonedTime): Time
|
||||
{.deprecated: "Use zt.time instead".} =
|
||||
## **Deprecated since v0.19.0:** use the ``time`` field instead.
|
||||
zt.time - initDuration(seconds = zt.utcOffset)
|
||||
|
||||
proc `adjTime=`*(zt: var ZonedTime, adjTime: Time)
|
||||
{.deprecated: "Use zt.time instead".} =
|
||||
## **Deprecated since v0.19.0:** use the ``time`` field instead.
|
||||
zt.time = adjTime + initDuration(seconds = zt.utcOffset)
|
||||
|
||||
proc zoneInfoFromUtc*(zone: Timezone, time: Time): ZonedTime
|
||||
{.deprecated: "Use zonedTimeFromTime instead".} =
|
||||
## **Deprecated since v0.19.0:** use ``zonedTimeFromTime`` instead.
|
||||
zone.zonedTimeFromTime(time)
|
||||
|
||||
proc zoneInfoFromTz*(zone: Timezone, adjTime: Time): ZonedTime
|
||||
{.deprecated: "Use zonedTimeFromAdjTime instead".} =
|
||||
## **Deprecated since v0.19.0:** use the ``zonedTimeFromAdjTime`` instead.
|
||||
zone.zonedTimeFromAdjTime(adjTime)
|
||||
@@ -21,17 +21,17 @@ doAssert b - a == initDuration(seconds = 500_000_000)
|
||||
|
||||
# Because we can't change the timezone JS uses, we define a simple static timezone for testing.
|
||||
|
||||
proc staticZoneInfoFromUtc(time: Time): ZonedTime =
|
||||
proc zonedTimeFromTime(time: Time): ZonedTime =
|
||||
result.utcOffset = -7200
|
||||
result.isDst = false
|
||||
result.adjTime = time + 7200.seconds
|
||||
result.time = time
|
||||
|
||||
proc staticZoneInfoFromTz(adjTime: Time): ZonedTIme =
|
||||
proc zonedTimeFromAdjTime(adjTime: Time): ZonedTIme =
|
||||
result.utcOffset = -7200
|
||||
result.isDst = false
|
||||
result.adjTime = adjTime
|
||||
result.time = adjTime + initDuration(seconds = -7200)
|
||||
|
||||
let utcPlus2 = Timezone(zoneInfoFromUtc: staticZoneInfoFromUtc, zoneInfoFromTz: staticZoneInfoFromTz, name: "")
|
||||
let utcPlus2 = newTimezone("", zonedTimeFromTime, zonedTimeFromAdjTime)
|
||||
|
||||
block timezoneTests:
|
||||
let dt = initDateTime(01, mJan, 2017, 12, 00, 00, utcPlus2)
|
||||
|
||||
@@ -11,20 +11,17 @@ import
|
||||
proc staticTz(hours, minutes, seconds: int = 0): Timezone {.noSideEffect.} =
|
||||
let offset = hours * 3600 + minutes * 60 + seconds
|
||||
|
||||
proc zoneInfoFromTz(adjTime: Time): ZonedTime {.locks: 0.} =
|
||||
proc zonedTimeFromAdjTime(adjTime: Time): ZonedTime {.locks: 0.} =
|
||||
result.isDst = false
|
||||
result.utcOffset = offset
|
||||
result.adjTime = adjTime
|
||||
result.time = adjTime + initDuration(seconds = offset)
|
||||
|
||||
proc zoneInfoFromUtc(time: Time): ZonedTime {.locks: 0.}=
|
||||
proc zonedTimeFromTime(time: Time): ZonedTime {.locks: 0.}=
|
||||
result.isDst = false
|
||||
result.utcOffset = offset
|
||||
result.adjTime = fromUnix(time.toUnix - offset)
|
||||
|
||||
result.name = ""
|
||||
result.zoneInfoFromTz = zoneInfoFromTz
|
||||
result.zoneInfoFromUtc = zoneInfoFromUtc
|
||||
result.time = time
|
||||
|
||||
newTimezone("", zonedTimeFromTime, zonedTImeFromAdjTime)
|
||||
|
||||
# $ date --date='@2147483647'
|
||||
# Tue 19 Jan 03:14:07 GMT 2038
|
||||
@@ -322,22 +319,7 @@ suite "ttimes":
|
||||
parseTestExcp("-1 BC", "UUUU g")
|
||||
|
||||
test "dynamic timezone":
|
||||
proc staticOffset(offset: int): Timezone =
|
||||
proc zoneInfoFromTz(adjTime: Time): ZonedTime =
|
||||
result.isDst = false
|
||||
result.utcOffset = offset
|
||||
result.adjTime = adjTime
|
||||
|
||||
proc zoneInfoFromUtc(time: Time): ZonedTime =
|
||||
result.isDst = false
|
||||
result.utcOffset = offset
|
||||
result.adjTime = fromUnix(time.toUnix - offset)
|
||||
|
||||
result.name = ""
|
||||
result.zoneInfoFromTz = zoneInfoFromTz
|
||||
result.zoneInfoFromUtc = zoneInfoFromUtc
|
||||
|
||||
let tz = staticOffset(-9000)
|
||||
let tz = staticTz(seconds = -9000)
|
||||
let dt = initDateTime(1, mJan, 2000, 12, 00, 00, tz)
|
||||
check dt.utcOffset == -9000
|
||||
check dt.isDst == false
|
||||
|
||||
Reference in New Issue
Block a user