times.nim: don't rely on zero terminator
This commit is contained in:
parent
16b0bf6cca
commit
fb15a265c5
1 changed files with 50 additions and 47 deletions
|
|
@ -1318,24 +1318,23 @@ proc format*(dt: DateTime, f: string): string {.tags: [].}=
|
||||||
result = ""
|
result = ""
|
||||||
var i = 0
|
var i = 0
|
||||||
var currentF = ""
|
var currentF = ""
|
||||||
while true:
|
while i < f.len:
|
||||||
case f[i]
|
case f[i]
|
||||||
of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',':
|
of ' ', '-', '/', ':', '\'', '(', ')', '[', ']', ',':
|
||||||
formatToken(dt, currentF, result)
|
formatToken(dt, currentF, result)
|
||||||
|
|
||||||
currentF = ""
|
currentF = ""
|
||||||
if f[i] == '\0': break
|
|
||||||
|
|
||||||
if f[i] == '\'':
|
if f[i] == '\'':
|
||||||
inc(i) # Skip '
|
inc(i) # Skip '
|
||||||
while f[i] != '\'' and f.len-1 > i:
|
while i < f.len-1 and f[i] != '\'':
|
||||||
result.add(f[i])
|
result.add(f[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
else: result.add(f[i])
|
else: result.add(f[i])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Check if the letter being added matches previous accumulated buffer.
|
# Check if the letter being added matches previous accumulated buffer.
|
||||||
if currentF.len < 1 or currentF[high(currentF)] == f[i]:
|
if currentF.len == 0 or currentF[high(currentF)] == f[i]:
|
||||||
currentF.add(f[i])
|
currentF.add(f[i])
|
||||||
else:
|
else:
|
||||||
formatToken(dt, currentF, result)
|
formatToken(dt, currentF, result)
|
||||||
|
|
@ -1343,6 +1342,7 @@ proc format*(dt: DateTime, f: string): string {.tags: [].}=
|
||||||
currentF = ""
|
currentF = ""
|
||||||
|
|
||||||
inc(i)
|
inc(i)
|
||||||
|
formatToken(dt, currentF, result)
|
||||||
|
|
||||||
proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} =
|
proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} =
|
||||||
## Converts a `DateTime` object to a string representation.
|
## Converts a `DateTime` object to a string representation.
|
||||||
|
|
@ -1521,44 +1521,47 @@ proc parseToken(dt: var DateTime; token, value: string; j: var int) =
|
||||||
j += 4
|
j += 4
|
||||||
of "z":
|
of "z":
|
||||||
dt.isDst = false
|
dt.isDst = false
|
||||||
if value[j] == '+':
|
let ch = if j < value.len: value[j] else: '\0'
|
||||||
|
if ch == '+':
|
||||||
dt.utcOffset = 0 - parseInt($value[j+1]) * secondsInHour
|
dt.utcOffset = 0 - parseInt($value[j+1]) * secondsInHour
|
||||||
elif value[j] == '-':
|
elif ch == '-':
|
||||||
dt.utcOffset = parseInt($value[j+1]) * secondsInHour
|
dt.utcOffset = parseInt($value[j+1]) * secondsInHour
|
||||||
elif value[j] == 'Z':
|
elif ch == 'Z':
|
||||||
dt.utcOffset = 0
|
dt.utcOffset = 0
|
||||||
j += 1
|
j += 1
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Couldn't parse timezone offset (z), got: " & value[j])
|
"Couldn't parse timezone offset (z), got: " & ch)
|
||||||
j += 2
|
j += 2
|
||||||
of "zz":
|
of "zz":
|
||||||
dt.isDst = false
|
dt.isDst = false
|
||||||
if value[j] == '+':
|
let ch = if j < value.len: value[j] else: '\0'
|
||||||
|
if ch == '+':
|
||||||
dt.utcOffset = 0 - value[j+1..j+2].parseInt() * secondsInHour
|
dt.utcOffset = 0 - value[j+1..j+2].parseInt() * secondsInHour
|
||||||
elif value[j] == '-':
|
elif ch == '-':
|
||||||
dt.utcOffset = value[j+1..j+2].parseInt() * secondsInHour
|
dt.utcOffset = value[j+1..j+2].parseInt() * secondsInHour
|
||||||
elif value[j] == 'Z':
|
elif ch == 'Z':
|
||||||
dt.utcOffset = 0
|
dt.utcOffset = 0
|
||||||
j += 1
|
j += 1
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Couldn't parse timezone offset (zz), got: " & value[j])
|
"Couldn't parse timezone offset (zz), got: " & ch)
|
||||||
j += 3
|
j += 3
|
||||||
of "zzz":
|
of "zzz":
|
||||||
dt.isDst = false
|
dt.isDst = false
|
||||||
var factor = 0
|
var factor = 0
|
||||||
if value[j] == '+': factor = -1
|
let ch = if j < value.len: value[j] else: '\0'
|
||||||
elif value[j] == '-': factor = 1
|
if ch == '+': factor = -1
|
||||||
elif value[j] == 'Z':
|
elif ch == '-': factor = 1
|
||||||
|
elif ch == 'Z':
|
||||||
dt.utcOffset = 0
|
dt.utcOffset = 0
|
||||||
j += 1
|
j += 1
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Couldn't parse timezone offset (zzz), got: " & value[j])
|
"Couldn't parse timezone offset (zzz), got: " & ch)
|
||||||
dt.utcOffset = factor * value[j+1..j+2].parseInt() * secondsInHour
|
dt.utcOffset = factor * value[j+1..j+2].parseInt() * secondsInHour
|
||||||
j += 4
|
j += 4
|
||||||
dt.utcOffset += factor * value[j..j+1].parseInt() * 60
|
dt.utcOffset += factor * value[j..j+1].parseInt() * 60
|
||||||
|
|
@ -1620,20 +1623,18 @@ proc parse*(value, layout: string, zone: Timezone = local()): DateTime =
|
||||||
dt.nanosecond = 0
|
dt.nanosecond = 0
|
||||||
dt.isDst = true # using this is flag for checking whether a timezone has \
|
dt.isDst = true # using this is flag for checking whether a timezone has \
|
||||||
# been read (because DST is always false when a tz is parsed)
|
# been read (because DST is always false when a tz is parsed)
|
||||||
while true:
|
while i < layout.len:
|
||||||
case layout[i]
|
case layout[i]
|
||||||
of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',':
|
of ' ', '-', '/', ':', '\'', '(', ')', '[', ']', ',':
|
||||||
if token.len > 0:
|
if token.len > 0:
|
||||||
parseToken(dt, token, value, j)
|
parseToken(dt, token, value, j)
|
||||||
# Reset token
|
# Reset token
|
||||||
token = ""
|
token = ""
|
||||||
# Break if at end of line
|
|
||||||
if layout[i] == '\0': break
|
|
||||||
# Skip separator and everything between single quotes
|
# Skip separator and everything between single quotes
|
||||||
# These are literals in both the layout and the value string
|
# These are literals in both the layout and the value string
|
||||||
if layout[i] == '\'':
|
if layout[i] == '\'':
|
||||||
inc(i)
|
inc(i)
|
||||||
while layout[i] != '\'' and layout.len-1 > i:
|
while i < layout.len-1 and layout[i] != '\'':
|
||||||
inc(i)
|
inc(i)
|
||||||
inc(j)
|
inc(j)
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
@ -1642,13 +1643,15 @@ proc parse*(value, layout: string, zone: Timezone = local()): DateTime =
|
||||||
inc(j)
|
inc(j)
|
||||||
else:
|
else:
|
||||||
# Check if the letter being added matches previous accumulated buffer.
|
# Check if the letter being added matches previous accumulated buffer.
|
||||||
if token.len < 1 or token[high(token)] == layout[i]:
|
if token.len == 0 or token[high(token)] == layout[i]:
|
||||||
token.add(layout[i])
|
token.add(layout[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
else:
|
else:
|
||||||
parseToken(dt, token, value, j)
|
parseToken(dt, token, value, j)
|
||||||
token = ""
|
token = ""
|
||||||
|
|
||||||
|
if i >= layout.len and token.len > 0:
|
||||||
|
parseToken(dt, token, value, j)
|
||||||
if dt.isDst:
|
if dt.isDst:
|
||||||
# No timezone parsed - assume timezone is `zone`
|
# No timezone parsed - assume timezone is `zone`
|
||||||
result = initDateTime(zone.zoneInfoFromTz(dt.toAdjTime), zone)
|
result = initDateTime(zone.zoneInfoFromTz(dt.toAdjTime), zone)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue