Merge branch 'devel' into araq
This commit is contained in:
commit
0ccbc82344
5 changed files with 318 additions and 269 deletions
|
|
@ -385,260 +385,6 @@ proc `miliseconds=`*(t: var TimeInterval, milliseconds: int) {.deprecated.} =
|
||||||
## version.
|
## version.
|
||||||
t.milliseconds = milliseconds
|
t.milliseconds = milliseconds
|
||||||
|
|
||||||
when not defined(JS):
|
|
||||||
proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].}
|
|
||||||
## gets time after the UNIX epoch (1970) in seconds. It is a float
|
|
||||||
## because sub-second resolution is likely to be supported (depending
|
|
||||||
## on the hardware/OS).
|
|
||||||
|
|
||||||
proc cpuTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].}
|
|
||||||
## gets time spent that the CPU spent to run the current process in
|
|
||||||
## seconds. This may be more useful for benchmarking than ``epochTime``.
|
|
||||||
## However, it may measure the real time instead (depending on the OS).
|
|
||||||
## The value of the result has no meaning.
|
|
||||||
## To generate useful timing values, take the difference between
|
|
||||||
## the results of two ``cpuTime`` calls:
|
|
||||||
##
|
|
||||||
## .. code-block:: nim
|
|
||||||
## var t0 = cpuTime()
|
|
||||||
## doWork()
|
|
||||||
## echo "CPU time [s] ", cpuTime() - t0
|
|
||||||
|
|
||||||
when not defined(JS):
|
|
||||||
# C wrapper:
|
|
||||||
when defined(freebsd) or defined(netbsd) or defined(openbsd) or
|
|
||||||
defined(macosx):
|
|
||||||
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
|
|
||||||
TimeInfoPtr = ptr StructTM
|
|
||||||
Clock {.importc: "clock_t".} = distinct int
|
|
||||||
|
|
||||||
when not defined(windows):
|
|
||||||
# This is not ANSI C, but common enough
|
|
||||||
proc timegm(t: StructTM): Time {.
|
|
||||||
importc: "timegm", header: "<time.h>", tags: [].}
|
|
||||||
|
|
||||||
proc localtime(timer: ptr Time): TimeInfoPtr {.
|
|
||||||
importc: "localtime", header: "<time.h>", tags: [].}
|
|
||||||
proc gmtime(timer: ptr Time): TimeInfoPtr {.
|
|
||||||
importc: "gmtime", header: "<time.h>", tags: [].}
|
|
||||||
proc timec(timer: ptr Time): Time {.
|
|
||||||
importc: "time", header: "<time.h>", tags: [].}
|
|
||||||
proc mktime(t: StructTM): Time {.
|
|
||||||
importc: "mktime", header: "<time.h>", tags: [].}
|
|
||||||
proc getClock(): Clock {.importc: "clock", header: "<time.h>", tags: [TimeEffect].}
|
|
||||||
proc difftime(a, b: Time): float {.importc: "difftime", header: "<time.h>",
|
|
||||||
tags: [].}
|
|
||||||
|
|
||||||
var
|
|
||||||
clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int
|
|
||||||
|
|
||||||
# our own procs on top of that:
|
|
||||||
proc tmToTimeInfo(tm: StructTM, local: bool): TimeInfo =
|
|
||||||
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,
|
|
||||||
timezone: if local: getTimezone() else: 0
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
proc timeInfoToTM(t: TimeInfo): StructTM =
|
|
||||||
const
|
|
||||||
weekDays: array[WeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8]
|
|
||||||
result.second = t.second
|
|
||||||
result.minute = t.minute
|
|
||||||
result.hour = t.hour
|
|
||||||
result.monthday = t.monthday
|
|
||||||
result.month = ord(t.month)
|
|
||||||
result.year = cint(t.year - 1900)
|
|
||||||
result.weekday = weekDays[t.weekday]
|
|
||||||
result.yearday = t.yearday
|
|
||||||
result.isdst = if t.isDST: 1 else: 0
|
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
|
||||||
proc `-` (a, b: Time): int64 =
|
|
||||||
return toBiggestInt(difftime(a, b))
|
|
||||||
|
|
||||||
proc getStartMilsecs(): int =
|
|
||||||
#echo "clocks per sec: ", clocksPerSec, "clock: ", int(getClock())
|
|
||||||
#return getClock() div (clocksPerSec div 1000)
|
|
||||||
when defined(macosx):
|
|
||||||
result = toInt(toFloat(int(getClock())) / (toFloat(clocksPerSec) / 1000.0))
|
|
||||||
else:
|
|
||||||
result = int(getClock()) div (clocksPerSec div 1000)
|
|
||||||
when false:
|
|
||||||
var a: Timeval
|
|
||||||
posix_gettimeofday(a)
|
|
||||||
result = a.tv_sec * 1000'i64 + a.tv_usec div 1000'i64
|
|
||||||
#echo "result: ", result
|
|
||||||
|
|
||||||
proc getTime(): Time = return timec(nil)
|
|
||||||
proc getLocalTime(t: Time): TimeInfo =
|
|
||||||
var a = t
|
|
||||||
let lt = localtime(addr(a))
|
|
||||||
assert(not lt.isNil)
|
|
||||||
result = tmToTimeInfo(lt[], true)
|
|
||||||
# copying is needed anyway to provide reentrancity; thus
|
|
||||||
# the conversion is not expensive
|
|
||||||
|
|
||||||
proc getGMTime(t: Time): TimeInfo =
|
|
||||||
var a = t
|
|
||||||
result = tmToTimeInfo(gmtime(addr(a))[], false)
|
|
||||||
# copying is needed anyway to provide reentrancity; thus
|
|
||||||
# the conversion is not expensive
|
|
||||||
|
|
||||||
proc toTime(timeInfo: TimeInfo): Time =
|
|
||||||
var cTimeInfo = timeInfo # for C++ we have to make a copy
|
|
||||||
# because the header of mktime is broken in my version of libc
|
|
||||||
|
|
||||||
result = mktime(timeInfoToTM(cTimeInfo))
|
|
||||||
# mktime is defined to interpret the input as local time. As timeInfoToTM
|
|
||||||
# does ignore the timezone, we need to adjust this here.
|
|
||||||
result = Time(TimeImpl(result) - getTimezone() + timeInfo.timezone)
|
|
||||||
|
|
||||||
proc timeInfoToTime(timeInfo: TimeInfo): Time = toTime(timeInfo)
|
|
||||||
|
|
||||||
const
|
|
||||||
epochDiff = 116444736000000000'i64
|
|
||||||
rateDiff = 10000000'i64 # 100 nsecs
|
|
||||||
|
|
||||||
proc unixTimeToWinTime*(t: Time): int64 =
|
|
||||||
## converts a UNIX `Time` (``time_t``) to a Windows file time
|
|
||||||
result = int64(t) * rateDiff + epochDiff
|
|
||||||
|
|
||||||
proc winTimeToUnixTime*(t: int64): Time =
|
|
||||||
## converts a Windows time to a UNIX `Time` (``time_t``)
|
|
||||||
result = Time((t - epochDiff) div rateDiff)
|
|
||||||
|
|
||||||
proc getTimezone(): int =
|
|
||||||
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,
|
|
||||||
# but posix systems using west of UTC in seconds
|
|
||||||
return -(lt.gmtoff)
|
|
||||||
else:
|
|
||||||
return timezone
|
|
||||||
|
|
||||||
proc fromSeconds(since1970: float): Time = Time(since1970)
|
|
||||||
|
|
||||||
proc toSeconds(time: Time): float = float(time)
|
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
|
||||||
proc epochTime(): float =
|
|
||||||
when defined(posix):
|
|
||||||
var a: Timeval
|
|
||||||
posix_gettimeofday(a)
|
|
||||||
result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.00_0001
|
|
||||||
elif defined(windows):
|
|
||||||
var f: winlean.FILETIME
|
|
||||||
getSystemTimeAsFileTime(f)
|
|
||||||
var i64 = rdFileTime(f) - epochDiff
|
|
||||||
var secs = i64 div rateDiff
|
|
||||||
var subsecs = i64 mod rateDiff
|
|
||||||
result = toFloat(int(secs)) + toFloat(int(subsecs)) * 0.0000001
|
|
||||||
else:
|
|
||||||
{.error: "unknown OS".}
|
|
||||||
|
|
||||||
proc cpuTime(): float =
|
|
||||||
result = toFloat(int(getClock())) / toFloat(clocksPerSec)
|
|
||||||
|
|
||||||
elif defined(JS):
|
|
||||||
proc newDate(): Time {.importc: "new Date".}
|
|
||||||
proc internGetTime(): Time {.importc: "new Date", tags: [].}
|
|
||||||
|
|
||||||
proc newDate(value: float): Time {.importc: "new Date".}
|
|
||||||
proc newDate(value: string): Time {.importc: "new Date".}
|
|
||||||
proc getTime(): Time =
|
|
||||||
# Warning: This is something different in JS.
|
|
||||||
return newDate()
|
|
||||||
|
|
||||||
const
|
|
||||||
weekDays: array[0..6, WeekDay] = [
|
|
||||||
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
|
|
||||||
|
|
||||||
proc getLocalTime(t: Time): TimeInfo =
|
|
||||||
result.second = t.getSeconds()
|
|
||||||
result.minute = t.getMinutes()
|
|
||||||
result.hour = t.getHours()
|
|
||||||
result.monthday = t.getDate()
|
|
||||||
result.month = Month(t.getMonth())
|
|
||||||
result.year = t.getFullYear()
|
|
||||||
result.weekday = weekDays[t.getDay()]
|
|
||||||
result.yearday = 0
|
|
||||||
result.timezone = getTimezone()
|
|
||||||
|
|
||||||
proc getGMTime(t: Time): TimeInfo =
|
|
||||||
result.second = t.getUTCSeconds()
|
|
||||||
result.minute = t.getUTCMinutes()
|
|
||||||
result.hour = t.getUTCHours()
|
|
||||||
result.monthday = t.getUTCDate()
|
|
||||||
result.month = Month(t.getUTCMonth())
|
|
||||||
result.year = t.getUTCFullYear()
|
|
||||||
result.weekday = weekDays[t.getUTCDay()]
|
|
||||||
result.yearday = 0
|
|
||||||
|
|
||||||
proc timeInfoToTime(timeInfo: TimeInfo): Time = toTime(timeInfo)
|
|
||||||
|
|
||||||
proc toTime*(timeInfo: TimeInfo): Time =
|
|
||||||
result = internGetTime()
|
|
||||||
result.setMinutes(timeInfo.minute)
|
|
||||||
result.setHours(timeInfo.hour)
|
|
||||||
result.setMonth(ord(timeInfo.month))
|
|
||||||
result.setFullYear(timeInfo.year)
|
|
||||||
result.setDate(timeInfo.monthday)
|
|
||||||
result.setSeconds(timeInfo.second + timeInfo.timezone)
|
|
||||||
|
|
||||||
proc `-` (a, b: Time): int64 =
|
|
||||||
return a.getTime() - b.getTime()
|
|
||||||
|
|
||||||
var
|
|
||||||
startMilsecs = getTime()
|
|
||||||
|
|
||||||
proc getStartMilsecs(): int =
|
|
||||||
## get the milliseconds from the start of the program
|
|
||||||
return int(getTime() - startMilsecs)
|
|
||||||
|
|
||||||
proc fromSeconds(since1970: float): Time = result = newDate(since1970 * 1000)
|
|
||||||
|
|
||||||
proc toSeconds(time: Time): float = result = time.getTime() / 1000
|
|
||||||
|
|
||||||
proc getTimezone(): int = result = newDate().getTimezoneOffset() * 60
|
|
||||||
|
|
||||||
proc epochTime*(): float {.tags: [TimeEffect].} = newDate().toSeconds()
|
|
||||||
|
|
||||||
proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} =
|
proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} =
|
||||||
## gets the current date as a string of the format ``YYYY-MM-DD``.
|
## gets the current date as a string of the format ``YYYY-MM-DD``.
|
||||||
var ti = getLocalTime(getTime())
|
var ti = getLocalTime(getTime())
|
||||||
|
|
@ -1333,6 +1079,259 @@ proc toTimeInterval*(t: Time): TimeInterval =
|
||||||
var tInfo = t.getLocalTime()
|
var tInfo = t.getLocalTime()
|
||||||
initInterval(0, tInfo.second, tInfo.minute, tInfo.hour, tInfo.weekday.ord, tInfo.month.ord, tInfo.year)
|
initInterval(0, tInfo.second, tInfo.minute, tInfo.hour, tInfo.weekday.ord, tInfo.month.ord, tInfo.year)
|
||||||
|
|
||||||
|
when not defined(JS):
|
||||||
|
proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].}
|
||||||
|
## gets time after the UNIX epoch (1970) in seconds. It is a float
|
||||||
|
## because sub-second resolution is likely to be supported (depending
|
||||||
|
## on the hardware/OS).
|
||||||
|
|
||||||
|
proc cpuTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].}
|
||||||
|
## gets time spent that the CPU spent to run the current process in
|
||||||
|
## seconds. This may be more useful for benchmarking than ``epochTime``.
|
||||||
|
## However, it may measure the real time instead (depending on the OS).
|
||||||
|
## The value of the result has no meaning.
|
||||||
|
## To generate useful timing values, take the difference between
|
||||||
|
## the results of two ``cpuTime`` calls:
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
## var t0 = cpuTime()
|
||||||
|
## doWork()
|
||||||
|
## echo "CPU time [s] ", cpuTime() - t0
|
||||||
|
|
||||||
|
when not defined(JS):
|
||||||
|
# C wrapper:
|
||||||
|
when defined(freebsd) or defined(netbsd) or defined(openbsd) or
|
||||||
|
defined(macosx):
|
||||||
|
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
|
||||||
|
TimeInfoPtr = ptr StructTM
|
||||||
|
Clock {.importc: "clock_t".} = distinct int
|
||||||
|
|
||||||
|
when not defined(windows):
|
||||||
|
# This is not ANSI C, but common enough
|
||||||
|
proc timegm(t: StructTM): Time {.
|
||||||
|
importc: "timegm", header: "<time.h>", tags: [].}
|
||||||
|
|
||||||
|
proc localtime(timer: ptr Time): TimeInfoPtr {.
|
||||||
|
importc: "localtime", header: "<time.h>", tags: [].}
|
||||||
|
proc gmtime(timer: ptr Time): TimeInfoPtr {.
|
||||||
|
importc: "gmtime", header: "<time.h>", tags: [].}
|
||||||
|
proc timec(timer: ptr Time): Time {.
|
||||||
|
importc: "time", header: "<time.h>", tags: [].}
|
||||||
|
proc mktime(t: StructTM): Time {.
|
||||||
|
importc: "mktime", header: "<time.h>", tags: [].}
|
||||||
|
proc getClock(): Clock {.importc: "clock", header: "<time.h>", tags: [TimeEffect].}
|
||||||
|
proc difftime(a, b: Time): float {.importc: "difftime", header: "<time.h>",
|
||||||
|
tags: [].}
|
||||||
|
|
||||||
|
var
|
||||||
|
clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int
|
||||||
|
|
||||||
|
# our own procs on top of that:
|
||||||
|
proc tmToTimeInfo(tm: StructTM, local: bool): TimeInfo =
|
||||||
|
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,
|
||||||
|
timezone: if local: getTimezone() else: 0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
proc timeInfoToTM(t: TimeInfo): StructTM =
|
||||||
|
const
|
||||||
|
weekDays: array[WeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8]
|
||||||
|
result.second = t.second
|
||||||
|
result.minute = t.minute
|
||||||
|
result.hour = t.hour
|
||||||
|
result.monthday = t.monthday
|
||||||
|
result.month = ord(t.month)
|
||||||
|
result.year = cint(t.year - 1900)
|
||||||
|
result.weekday = weekDays[t.weekday]
|
||||||
|
result.yearday = t.yearday
|
||||||
|
result.isdst = if t.isDST: 1 else: 0
|
||||||
|
|
||||||
|
when not defined(useNimRtl):
|
||||||
|
proc `-` (a, b: Time): int64 =
|
||||||
|
return toBiggestInt(difftime(a, b))
|
||||||
|
|
||||||
|
proc getStartMilsecs(): int =
|
||||||
|
#echo "clocks per sec: ", clocksPerSec, "clock: ", int(getClock())
|
||||||
|
#return getClock() div (clocksPerSec div 1000)
|
||||||
|
when defined(macosx):
|
||||||
|
result = toInt(toFloat(int(getClock())) / (toFloat(clocksPerSec) / 1000.0))
|
||||||
|
else:
|
||||||
|
result = int(getClock()) div (clocksPerSec div 1000)
|
||||||
|
when false:
|
||||||
|
var a: Timeval
|
||||||
|
posix_gettimeofday(a)
|
||||||
|
result = a.tv_sec * 1000'i64 + a.tv_usec div 1000'i64
|
||||||
|
#echo "result: ", result
|
||||||
|
|
||||||
|
proc getTime(): Time = return timec(nil)
|
||||||
|
proc getLocalTime(t: Time): TimeInfo =
|
||||||
|
var a = t
|
||||||
|
let lt = localtime(addr(a))
|
||||||
|
assert(not lt.isNil)
|
||||||
|
result = tmToTimeInfo(lt[], true)
|
||||||
|
# copying is needed anyway to provide reentrancity; thus
|
||||||
|
# the conversion is not expensive
|
||||||
|
|
||||||
|
proc getGMTime(t: Time): TimeInfo =
|
||||||
|
var a = t
|
||||||
|
result = tmToTimeInfo(gmtime(addr(a))[], false)
|
||||||
|
# copying is needed anyway to provide reentrancity; thus
|
||||||
|
# the conversion is not expensive
|
||||||
|
|
||||||
|
proc toTime(timeInfo: TimeInfo): Time =
|
||||||
|
var cTimeInfo = timeInfo # for C++ we have to make a copy
|
||||||
|
# because the header of mktime is broken in my version of libc
|
||||||
|
|
||||||
|
result = mktime(timeInfoToTM(cTimeInfo))
|
||||||
|
# mktime is defined to interpret the input as local time. As timeInfoToTM
|
||||||
|
# does ignore the timezone, we need to adjust this here.
|
||||||
|
result = Time(TimeImpl(result) - getTimezone() + timeInfo.timezone)
|
||||||
|
|
||||||
|
proc timeInfoToTime(timeInfo: TimeInfo): Time = toTime(timeInfo)
|
||||||
|
|
||||||
|
const
|
||||||
|
epochDiff = 116444736000000000'i64
|
||||||
|
rateDiff = 10000000'i64 # 100 nsecs
|
||||||
|
|
||||||
|
proc unixTimeToWinTime*(t: Time): int64 =
|
||||||
|
## converts a UNIX `Time` (``time_t``) to a Windows file time
|
||||||
|
result = int64(t) * rateDiff + epochDiff
|
||||||
|
|
||||||
|
proc winTimeToUnixTime*(t: int64): Time =
|
||||||
|
## converts a Windows time to a UNIX `Time` (``time_t``)
|
||||||
|
result = Time((t - epochDiff) div rateDiff)
|
||||||
|
|
||||||
|
proc getTimezone(): int =
|
||||||
|
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,
|
||||||
|
# but posix systems using west of UTC in seconds
|
||||||
|
return -(lt.gmtoff)
|
||||||
|
else:
|
||||||
|
return timezone
|
||||||
|
|
||||||
|
proc fromSeconds(since1970: float): Time = Time(since1970)
|
||||||
|
|
||||||
|
proc toSeconds(time: Time): float = float(time)
|
||||||
|
|
||||||
|
when not defined(useNimRtl):
|
||||||
|
proc epochTime(): float =
|
||||||
|
when defined(posix):
|
||||||
|
var a: Timeval
|
||||||
|
posix_gettimeofday(a)
|
||||||
|
result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.00_0001
|
||||||
|
elif defined(windows):
|
||||||
|
var f: winlean.FILETIME
|
||||||
|
getSystemTimeAsFileTime(f)
|
||||||
|
var i64 = rdFileTime(f) - epochDiff
|
||||||
|
var secs = i64 div rateDiff
|
||||||
|
var subsecs = i64 mod rateDiff
|
||||||
|
result = toFloat(int(secs)) + toFloat(int(subsecs)) * 0.0000001
|
||||||
|
else:
|
||||||
|
{.error: "unknown OS".}
|
||||||
|
|
||||||
|
proc cpuTime(): float =
|
||||||
|
result = toFloat(int(getClock())) / toFloat(clocksPerSec)
|
||||||
|
|
||||||
|
elif defined(JS):
|
||||||
|
proc newDate(): Time {.importc: "new Date".}
|
||||||
|
proc internGetTime(): Time {.importc: "new Date", tags: [].}
|
||||||
|
|
||||||
|
proc newDate(value: float): Time {.importc: "new Date".}
|
||||||
|
proc newDate(value: cstring): Time {.importc: "new Date".}
|
||||||
|
proc getTime(): Time =
|
||||||
|
# Warning: This is something different in JS.
|
||||||
|
return newDate()
|
||||||
|
|
||||||
|
const
|
||||||
|
weekDays: array[0..6, WeekDay] = [
|
||||||
|
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
|
||||||
|
|
||||||
|
proc getLocalTime(t: Time): TimeInfo =
|
||||||
|
result.second = t.getSeconds()
|
||||||
|
result.minute = t.getMinutes()
|
||||||
|
result.hour = t.getHours()
|
||||||
|
result.monthday = t.getDate()
|
||||||
|
result.month = Month(t.getMonth())
|
||||||
|
result.year = t.getFullYear()
|
||||||
|
result.weekday = weekDays[t.getDay()]
|
||||||
|
result.timezone = getTimezone()
|
||||||
|
|
||||||
|
result.yearday = result.monthday - 1
|
||||||
|
for month in mJan..<result.month:
|
||||||
|
result.yearday += getDaysInMonth(month, result.year)
|
||||||
|
|
||||||
|
proc getGMTime(t: Time): TimeInfo =
|
||||||
|
result.second = t.getUTCSeconds()
|
||||||
|
result.minute = t.getUTCMinutes()
|
||||||
|
result.hour = t.getUTCHours()
|
||||||
|
result.monthday = t.getUTCDate()
|
||||||
|
result.month = Month(t.getUTCMonth())
|
||||||
|
result.year = t.getUTCFullYear()
|
||||||
|
result.weekday = weekDays[t.getUTCDay()]
|
||||||
|
|
||||||
|
result.yearday = result.monthday - 1
|
||||||
|
for month in mJan..<result.month:
|
||||||
|
result.yearday += getDaysInMonth(month, result.year)
|
||||||
|
|
||||||
|
proc timeInfoToTime(timeInfo: TimeInfo): Time = toTime(timeInfo)
|
||||||
|
|
||||||
|
proc toTime*(timeInfo: TimeInfo): Time = newDate($timeInfo)
|
||||||
|
|
||||||
|
proc `-` (a, b: Time): int64 =
|
||||||
|
return a.getTime() - b.getTime()
|
||||||
|
|
||||||
|
var
|
||||||
|
startMilsecs = getTime()
|
||||||
|
|
||||||
|
proc getStartMilsecs(): int =
|
||||||
|
## get the milliseconds from the start of the program
|
||||||
|
return int(getTime() - startMilsecs)
|
||||||
|
|
||||||
|
proc fromSeconds(since1970: float): Time = result = newDate(since1970 * 1000)
|
||||||
|
|
||||||
|
proc toSeconds(time: Time): float = result = time.getTime() / 1000
|
||||||
|
|
||||||
|
proc getTimezone(): int = result = newDate().getTimezoneOffset() * 60
|
||||||
|
|
||||||
|
proc epochTime*(): float {.tags: [TimeEffect].} = newDate().toSeconds()
|
||||||
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
# this is testing non-exported function
|
# this is testing non-exported function
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,8 @@ proc popSafePoint {.compilerRtl, inl.} =
|
||||||
excHandler = excHandler.prev
|
excHandler = excHandler.prev
|
||||||
|
|
||||||
proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} =
|
proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} =
|
||||||
e.parent = currException
|
#if e.parent.isNil:
|
||||||
|
# e.parent = currException
|
||||||
currException = e
|
currException = e
|
||||||
|
|
||||||
proc popCurrentException {.compilerRtl, inl.} =
|
proc popCurrentException {.compilerRtl, inl.} =
|
||||||
|
|
@ -279,7 +280,7 @@ proc raiseExceptionAux(e: ref Exception) =
|
||||||
quitOrDebug()
|
quitOrDebug()
|
||||||
|
|
||||||
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
|
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
|
||||||
e.name = ename
|
if e.name.isNil: e.name = ename
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
e.trace = ""
|
e.trace = ""
|
||||||
rawWriteStackTrace(e.trace)
|
rawWriteStackTrace(e.trace)
|
||||||
|
|
|
||||||
29
tests/exception/tdont_overwrite_typename.nim
Normal file
29
tests/exception/tdont_overwrite_typename.nim
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
discard """
|
||||||
|
output: '''Check passed
|
||||||
|
Check passed'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #5628
|
||||||
|
|
||||||
|
proc checkException(ex: ref Exception) =
|
||||||
|
doAssert(ex.name == "ValueError")
|
||||||
|
doAssert(ex.msg == "SecondException")
|
||||||
|
doAssert(ex.parent != nil)
|
||||||
|
doAssert(ex.parent.name == "KeyError")
|
||||||
|
doAssert(ex.parent.msg == "FirstException")
|
||||||
|
echo "Check passed"
|
||||||
|
|
||||||
|
var e: ref Exception
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
raise newException(KeyError, "FirstException")
|
||||||
|
except:
|
||||||
|
raise newException(ValueError, "SecondException", getCurrentException())
|
||||||
|
except:
|
||||||
|
e = getCurrentException()
|
||||||
|
|
||||||
|
try:
|
||||||
|
checkException(e) # passes here
|
||||||
|
raise e
|
||||||
|
except ValueError:
|
||||||
|
checkException(getCurrentException()) # fails here
|
||||||
26
tests/js/ttimes.nim
Normal file
26
tests/js/ttimes.nim
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# test times module with js
|
||||||
|
discard """
|
||||||
|
action: run
|
||||||
|
"""
|
||||||
|
|
||||||
|
import times
|
||||||
|
|
||||||
|
# $ date --date='@2147483647'
|
||||||
|
# Tue 19 Jan 03:14:07 GMT 2038
|
||||||
|
|
||||||
|
block yeardayTest:
|
||||||
|
# check if yearday attribute is properly set on TimeInfo creation
|
||||||
|
doAssert fromSeconds(2147483647).getGMTime().yearday == 18
|
||||||
|
|
||||||
|
block localTimezoneTest:
|
||||||
|
# check if timezone is properly set during Time to TimeInfo conversion
|
||||||
|
doAssert fromSeconds(2147483647).getLocalTime().timezone == getTimezone()
|
||||||
|
|
||||||
|
block timestampPersistenceTest:
|
||||||
|
# check if timestamp persists during TimeInfo to Time conversion
|
||||||
|
const
|
||||||
|
timeString = "2017-03-21T12:34:56+03:00"
|
||||||
|
timeStringGmt = "2017-03-21T09:34:56+00:00"
|
||||||
|
fmt = "yyyy-MM-dd'T'HH:mm:sszzz"
|
||||||
|
|
||||||
|
doAssert $timeString.parse(fmt).toTime().getGMTime() == timeStringGmt
|
||||||
|
|
@ -9,7 +9,8 @@ Windows
|
||||||
Zips
|
Zips
|
||||||
%%%%
|
%%%%
|
||||||
|
|
||||||
We now encourage you to install via the provided zipfiles:
|
Since the website moved to https, only installation via the provided zipfiles
|
||||||
|
is supported:
|
||||||
|
|
||||||
* | 32 bit: `nim-0.16.0_x32.zip <download/nim-0.16.0_x32.zip>`_
|
* | 32 bit: `nim-0.16.0_x32.zip <download/nim-0.16.0_x32.zip>`_
|
||||||
| SHA-256 69af94a6875a02543c1bf0fa03c665f126f8500a2c0e226c32571e64c6842e57
|
| SHA-256 69af94a6875a02543c1bf0fa03c665f126f8500a2c0e226c32571e64c6842e57
|
||||||
|
|
@ -25,21 +26,14 @@ You can find the required DLLs here, if you lack them for some reason:
|
||||||
| SHA-256 198112d3d6dc74d7964ba452158d44bfa57adef4dc47be8c39903f2a24e4a555
|
| SHA-256 198112d3d6dc74d7964ba452158d44bfa57adef4dc47be8c39903f2a24e4a555
|
||||||
|
|
||||||
|
|
||||||
Exes
|
These versions of mingw are known to work:
|
||||||
%%%%
|
|
||||||
|
|
||||||
You can download an installer for both 32 bit and 64 bit versions of
|
* | 32 bit: `mingw32-6.3.0 <download/mingw32-6.3.0.7z>`_
|
||||||
Windows below. Note that these installers have some known issues and
|
| SHA-256 1239a56d4c42e146b2cb25dc4d0871bd83f569d0a51a9198e84d010e0a75745a
|
||||||
so will unlikely to be provided further in the future. These
|
* | 64 bit: `mingw64-6.3.0 <download/mingw64-6.3.0.7z>`_
|
||||||
installers have everything you need to use Nim, including a C compiler.
|
| SHA-256 9a23d12d96a10e67093c1f2042275c6a7d29da9e2ead573d0f24f4a6d53761a1
|
||||||
|
|
||||||
* | 32 bit: `nim-0.16.0_x32.exe <download/nim-0.16.0_x32.exe>`_
|
|
||||||
| SHA-256 37c55d9f9b3a2947559901c8bbd10b6a16191b562ca2bebdc145a6c24f5d004e
|
|
||||||
* | 64 bit: `nim-0.16.0_x64.exe <download/nim-0.16.0_x64.exe>`_
|
|
||||||
| SHA-256 13934282b01cbcaf7ad7aecb67e954dd0ea2b576c6c8102016cb9a9a30cce744
|
|
||||||
|
|
||||||
These installers also include Aporia, Nimble and other useful Nim tools to get
|
|
||||||
you started with Nim development!
|
|
||||||
|
|
||||||
Installation based on generated C code
|
Installation based on generated C code
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue