mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 17:34:43 +00:00
@@ -29,7 +29,7 @@ var
|
||||
timezone {.importc, header: "<time.h>".}: int
|
||||
tzname {.importc, header: "<time.h>" .}: array[0..1, cstring]
|
||||
|
||||
when defined(posix):
|
||||
when defined(posix) and not defined(JS):
|
||||
type
|
||||
TTimeImpl {.importc: "time_t", header: "<sys/time.h>".} = int
|
||||
TTime* = distinct TTimeImpl ## distinct type that represents a time
|
||||
@@ -62,45 +62,44 @@ elif defined(windows):
|
||||
elif defined(JS):
|
||||
type
|
||||
TTime* {.final, importc.} = object
|
||||
getDay: proc (): int
|
||||
getFullYear: proc (): int
|
||||
getHours: proc (): int
|
||||
getMilliseconds: proc (): int
|
||||
getMinutes: proc (): int
|
||||
getMonth: proc (): int
|
||||
getSeconds: proc (): int
|
||||
getTime: proc (): int
|
||||
getTimezoneOffset: proc (): int
|
||||
getDate: proc (): int
|
||||
getUTCDate: proc (): int
|
||||
getUTCFullYear: proc (): int
|
||||
getUTCHours: proc (): int
|
||||
getUTCMilliseconds: proc (): int
|
||||
getUTCMinutes: proc (): int
|
||||
getUTCMonth: proc (): int
|
||||
getUTCSeconds: proc (): int
|
||||
getUTCDay: proc (): int
|
||||
getYear: proc (): int
|
||||
parse: proc (s: cstring): TTime
|
||||
setDate: proc (x: int)
|
||||
setFullYear: proc (x: int)
|
||||
setHours: proc (x: int)
|
||||
setMilliseconds: proc (x: int)
|
||||
setMinutes: proc (x: int)
|
||||
setMonth: proc (x: int)
|
||||
setSeconds: proc (x: int)
|
||||
setTime: proc (x: int)
|
||||
setUTCDate: proc (x: int)
|
||||
setUTCFullYear: proc (x: int)
|
||||
setUTCHours: proc (x: int)
|
||||
setUTCMilliseconds: proc (x: int)
|
||||
setUTCMinutes: proc (x: int)
|
||||
setUTCMonth: proc (x: int)
|
||||
setUTCSeconds: proc (x: int)
|
||||
setYear: proc (x: int)
|
||||
toGMTString: proc (): cstring
|
||||
toLocaleString: proc (): cstring
|
||||
UTC: proc (): int
|
||||
getDay: proc (): int {.tags: [].}
|
||||
getFullYear: proc (): int {.tags: [].}
|
||||
getHours: proc (): int {.tags: [].}
|
||||
getMilliseconds: proc (): int {.tags: [].}
|
||||
getMinutes: proc (): int {.tags: [].}
|
||||
getMonth: proc (): int {.tags: [].}
|
||||
getSeconds: proc (): int {.tags: [].}
|
||||
getTime: proc (): int {.tags: [].}
|
||||
getTimezoneOffset: proc (): int {.tags: [].}
|
||||
getDate: proc (): int {.tags: [].}
|
||||
getUTCDate: proc (): int {.tags: [].}
|
||||
getUTCFullYear: proc (): int {.tags: [].}
|
||||
getUTCHours: proc (): int {.tags: [].}
|
||||
getUTCMilliseconds: proc (): int {.tags: [].}
|
||||
getUTCMinutes: proc (): int {.tags: [].}
|
||||
getUTCMonth: proc (): int {.tags: [].}
|
||||
getUTCSeconds: proc (): int {.tags: [].}
|
||||
getUTCDay: proc (): int {.tags: [].}
|
||||
getYear: proc (): int {.tags: [].}
|
||||
parse: proc (s: cstring): TTime {.tags: [].}
|
||||
setDate: proc (x: int) {.tags: [].}
|
||||
setFullYear: proc (x: int) {.tags: [].}
|
||||
setHours: proc (x: int) {.tags: [].}
|
||||
setMilliseconds: proc (x: int) {.tags: [].}
|
||||
setMinutes: proc (x: int) {.tags: [].}
|
||||
setMonth: proc (x: int) {.tags: [].}
|
||||
setSeconds: proc (x: int) {.tags: [].}
|
||||
setTime: proc (x: int) {.tags: [].}
|
||||
setUTCDate: proc (x: int) {.tags: [].}
|
||||
setUTCFullYear: proc (x: int) {.tags: [].}
|
||||
setUTCHours: proc (x: int) {.tags: [].}
|
||||
setUTCMilliseconds: proc (x: int) {.tags: [].}
|
||||
setUTCMinutes: proc (x: int) {.tags: [].}
|
||||
setUTCMonth: proc (x: int) {.tags: [].}
|
||||
setUTCSeconds: proc (x: int) {.tags: [].}
|
||||
setYear: proc (x: int) {.tags: [].}
|
||||
toGMTString: proc (): cstring {.tags: [].}
|
||||
toLocaleString: proc (): cstring {.tags: [].}
|
||||
|
||||
type
|
||||
TTimeInfo* = object of TObject ## represents a time in different parts
|
||||
@@ -124,6 +123,9 @@ type
|
||||
timezone*: int ## The offset of the (non-DST) timezone in seconds
|
||||
## west of UTC.
|
||||
|
||||
## I make some assumptions about the data in here. Either
|
||||
## everything should be positive or everything negative. Zero is
|
||||
## fine too. Mixed signs will lead to unexpected results.
|
||||
TTimeInterval* {.pure.} = object ## a time interval
|
||||
miliseconds*: int ## The number of miliseconds
|
||||
seconds*: int ## The number of seconds
|
||||
@@ -150,6 +152,17 @@ proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime
|
||||
## contents of the structure members `weekday` and `yearday` and recomputes
|
||||
## them from the other information in the broken-down time structure.
|
||||
|
||||
proc fromSeconds*(since1970: float): TTime
|
||||
## Takes a float which contains the number of seconds since 1970 and
|
||||
## returns a time object.
|
||||
|
||||
proc fromSeconds*(since1970: int|int64): TTime = fromSeconds(float(since1970))
|
||||
## Takes an in which contains the number of seconds since 1970 and
|
||||
## returns a time object.
|
||||
|
||||
proc toSeconds*(time: TTime): float
|
||||
## Returns the time in seconds since 1970.
|
||||
|
||||
proc `$` *(timeInfo: TTimeInfo): string
|
||||
## converts a `TTimeInfo` object to a string representation.
|
||||
proc `$` *(time: TTime): string
|
||||
@@ -173,9 +186,10 @@ proc `==`*(a, b: TTime): bool {.rtl, extern: "ntEqTime".} =
|
||||
## returns true if ``a == b``, that is if both times represent the same value
|
||||
result = a - b == 0
|
||||
|
||||
proc getTzname*(): tuple[nonDST, DST: string] {.tags: [FTime].}
|
||||
## returns the local timezone; ``nonDST`` is the name of the local non-DST
|
||||
## timezone, ``DST`` is the name of the local DST timezone.
|
||||
when not defined(JS):
|
||||
proc getTzname*(): tuple[nonDST, DST: string] {.tags: [FTime].}
|
||||
## returns the local timezone; ``nonDST`` is the name of the local non-DST
|
||||
## timezone, ``DST`` is the name of the local DST timezone.
|
||||
|
||||
proc getTimezone*(): int {.tags: [FTime].}
|
||||
## returns the offset of the local (non-DST) timezone in seconds west of UTC.
|
||||
@@ -212,10 +226,18 @@ proc getDaysInMonth(month: TMonth, year: int): int =
|
||||
of mApr, mJun, mSep, mNov: result = 30
|
||||
else: result = 31
|
||||
|
||||
proc calculateSeconds(a: TTimeInfo, interval: TTimeInterval): float =
|
||||
proc `-`*(interval: TTimeInterval): TTimeInterval =
|
||||
for a, b in fields(result, interval):
|
||||
a = -b
|
||||
|
||||
proc toSeconds*(a: TTimeInfo, interval: TTimeInterval): float =
|
||||
## Returns the time the interval will be at that point in time. This
|
||||
## needs a time as well, because e.g. a month is not always the same
|
||||
## length.
|
||||
|
||||
var anew = a
|
||||
var newinterv = interval
|
||||
result = 0.0
|
||||
result = 0
|
||||
|
||||
newinterv.months += interval.years * 12
|
||||
var curMonth = anew.month
|
||||
@@ -228,32 +250,30 @@ proc calculateSeconds(a: TTimeInfo, interval: TTimeInterval): float =
|
||||
curMonth.inc()
|
||||
result += float(newinterv.days * 24 * 60 * 60)
|
||||
result += float(newinterv.minutes * 60 * 60)
|
||||
result += newinterv.seconds.float
|
||||
result += float(newinterv.seconds)
|
||||
result += newinterv.miliseconds / 1000
|
||||
|
||||
proc toSeconds*(a: TTime, interval: TTimeInterval): float =
|
||||
result = toSeconds(getGMTime(a), interval)
|
||||
|
||||
proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo =
|
||||
## adds ``interval`` time.
|
||||
##
|
||||
## **Note:** This has been only briefly tested and it may not be
|
||||
## very accurate.
|
||||
let t = timeInfoToTime(a)
|
||||
let secs = calculateSeconds(a, interval)
|
||||
let t = toSeconds(TimeInfoToTime(a))
|
||||
let secs = toSeconds(a, interval)
|
||||
if a.tzname == "UTC":
|
||||
result = getGMTime(TTime(float(t) + secs))
|
||||
result = getGMTime(fromSeconds(t + secs))
|
||||
else:
|
||||
result = getLocalTime(TTime(float(t) + secs))
|
||||
result = getLocalTime(fromSeconds(t + secs))
|
||||
|
||||
proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo =
|
||||
## subtracts ``interval`` time.
|
||||
##
|
||||
## **Note:** This has been only briefly tested, it is inaccurate especially
|
||||
## when you subtract so much that you reach the Julian calendar.
|
||||
let t = timeInfoToTime(a)
|
||||
let secs = calculateSeconds(a, interval)
|
||||
if a.tzname == "UTC":
|
||||
result = getGMTime(TTime(float(t) - secs))
|
||||
else:
|
||||
result = getLocalTime(TTime(float(t) - secs))
|
||||
result = a + -interval
|
||||
|
||||
when not defined(JS):
|
||||
proc epochTime*(): float {.rtl, extern: "nt$1", tags: [FTime].}
|
||||
@@ -274,8 +294,7 @@ when not defined(JS):
|
||||
## doWork()
|
||||
## echo "CPU time [s] ", cpuTime() - t0
|
||||
|
||||
when not defined(JS):
|
||||
|
||||
when not defined(JS) and defined(POSIX):
|
||||
# C wrapper:
|
||||
type
|
||||
structTM {.importc: "struct tm", final.} = object
|
||||
@@ -416,7 +435,11 @@ when not defined(JS):
|
||||
|
||||
proc getTimezone(): int =
|
||||
return timezone
|
||||
|
||||
|
||||
proc fromSeconds(since1970: float): TTime = TTime(since1970)
|
||||
|
||||
proc toSeconds(time: TTime): float = float(time)
|
||||
|
||||
when not defined(useNimRtl):
|
||||
proc epochTime(): float =
|
||||
when defined(posix):
|
||||
@@ -437,8 +460,12 @@ when not defined(JS):
|
||||
result = toFloat(int(clock())) / toFloat(clocksPerSec)
|
||||
|
||||
elif defined(JS):
|
||||
proc newDate(): TTime {.importc: "new Date", nodecl.}
|
||||
proc getTime(): TTime = return newDate()
|
||||
proc newDate(): TTime {.importc: "new Date".}
|
||||
proc newDate(value: float): TTime {.importc: "new Date".}
|
||||
proc newDate(value: string): TTime {.importc: "new Date".}
|
||||
proc getTime(): TTime =
|
||||
# Warning: This is something different in JS.
|
||||
return newDate()
|
||||
|
||||
const
|
||||
weekDays: array [0..6, TWeekDay] = [
|
||||
@@ -486,6 +513,13 @@ elif defined(JS):
|
||||
## get the miliseconds from the start of the program
|
||||
return int(getTime() - startMilsecs)
|
||||
|
||||
proc valueOf(time: TTime): float {.importcpp: "getTime", tags:[]}
|
||||
|
||||
proc fromSeconds(since1970: float): TTime = result = newDate(since1970)
|
||||
|
||||
proc toSeconds(time: TTime): float = result = time.valueOf() / 1000
|
||||
|
||||
proc getTimezone(): int = result = newDate().getTimezoneOffset()
|
||||
|
||||
proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [FTime].} =
|
||||
## gets the current date as a string of the format ``YYYY-MM-DD``.
|
||||
@@ -680,7 +714,7 @@ when isMainModule:
|
||||
# $ date --date='@2147483647'
|
||||
# Tue 19 Jan 03:14:07 GMT 2038
|
||||
|
||||
var t = getGMTime(TTime(2147483647))
|
||||
var t = getGMTime(fromSeconds(2147483647))
|
||||
echo t.format("ddd dd MMM hh:mm:ss ZZZ yyyy")
|
||||
assert t.format("ddd dd MMM hh:mm:ss ZZZ yyyy") == "Tue 19 Jan 03:14:07 UTC 2038"
|
||||
|
||||
@@ -688,19 +722,19 @@ when isMainModule:
|
||||
" ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") ==
|
||||
"19 19 Tue Tuesday 3 03 3 03 14 14 1 01 Jan January 7 07 A AM 8 38 038 2038 02038 0 00 00:00 UTC"
|
||||
|
||||
var t2 = getGMTime(TTime(160070789)) # Mon 27 Jan 16:06:29 GMT 1975
|
||||
var t2 = getGMTime(fromSeconds(160070789)) # Mon 27 Jan 16:06:29 GMT 1975
|
||||
assert t2.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
|
||||
" ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") ==
|
||||
"27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC"
|
||||
|
||||
when sizeof(TTime) == 8:
|
||||
var t3 = getGMTime(TTime(889067643645)) # Fri 7 Jun 19:20:45 BST 30143
|
||||
when not defined(JS) and sizeof(TTime) == 8:
|
||||
var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143
|
||||
assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
|
||||
" ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") ==
|
||||
"7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC"
|
||||
assert t3.format(":,[]()-/") == ":,[]()-/"
|
||||
|
||||
var t4 = getGMTime(TTime(876124714)) # Mon 6 Oct 08:58:34 BST 1997
|
||||
var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997
|
||||
assert t4.format("M MM MMM MMMM") == "10 10 Oct October"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user