2 Commits
0.3.1 ... 0.3.3

Author SHA1 Message Date
d90372127b Further fix for ISO8601 date parsing.
Recognize versions of timestamps with 'T' as the date/time separator.
For example, compare:

    '2021-08-01 23:14:00-05:00'
    '2021-08-01T23:14:00-05:00'

This commit adds support for the second flavor (and it's variations).
2021-08-01 23:14:18 -05:00
2b78727356 Fix for PostgreSQL timestamp with timezone fields.
The previous fix for PostgreSQL timestamp fields matched fields with and
without timezones, but did not properly parse values from fields that
included the timezone. Now we check for the presence of the timezone in
the date string and choose a format string to parse it correctly.
2021-07-05 11:24:06 -05:00
2 changed files with 20 additions and 16 deletions

View File

@ -1,6 +1,6 @@
# Package # Package
version = "0.3.1" version = "0.3.3"
author = "Jonathan Bernard" author = "Jonathan Bernard"
description = "Lightweight Postgres ORM for Nim." description = "Lightweight Postgres ORM for Nim."
license = "GPL-3.0" license = "GPL-3.0"

View File

@ -67,34 +67,38 @@ proc parsePGDatetime*(val: string): DateTime =
const PG_TIMESTAMP_FORMATS = [ const PG_TIMESTAMP_FORMATS = [
"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd HH:mm:sszz", "yyyy-MM-dd HH:mm:sszz",
"yyyy-MM-dd'T'HH:mm:sszz",
"yyyy-MM-dd HH:mm:ss'.'fff", "yyyy-MM-dd HH:mm:ss'.'fff",
"yyyy-MM-dd HH:mm:ss'.'fffzz" "yyyy-MM-dd'T'HH:mm:ss'.'fff",
"yyyy-MM-dd HH:mm:ss'.'fffzz",
"yyyy-MM-dd'T'HH:mm:ss'.'fffzz",
"yyyy-MM-dd HH:mm:ss'.'fffzzz",
"yyyy-MM-dd'T'HH:mm:ss'.'fffzzz",
] ]
let PG_PARTIAL_FORMAT_REGEX = re"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.)(\d{1,3})(\S+)?" var correctedVal = val;
var errStr = ""
# Try to parse directly using known format strings.
for df in PG_TIMESTAMP_FORMATS:
try: return val.parse(df)
except: errStr &= "\n\t" & getCurrentExceptionMsg()
# PostgreSQL will truncate any trailing 0's in the millisecond value leading # PostgreSQL will truncate any trailing 0's in the millisecond value leading
# to values like `2020-01-01 16:42.3+00`. This cannot currently be parsed by # to values like `2020-01-01 16:42.3+00`. This cannot currently be parsed by
# the standard times format as it expects exactly three digits for # the standard times format as it expects exactly three digits for
# millisecond values. So we have to detect this and pad out the millisecond # millisecond values. So we have to detect this and pad out the millisecond
# value to 3 digits. # value to 3 digits.
let PG_PARTIAL_FORMAT_REGEX = re"(\d{4}-\d{2}-\d{2}( |'T')\d{2}:\d{2}:\d{2}\.)(\d{1,2})(\S+)?"
let match = val.match(PG_PARTIAL_FORMAT_REGEX) let match = val.match(PG_PARTIAL_FORMAT_REGEX)
if match.isSome: if match.isSome:
let c = match.get.captures let c = match.get.captures
try: if c.toSeq.len == 2: correctedVal = c[0] & alignLeft(c[2], 3, '0')
let corrected = c[0] & alignLeft(c[1], 3, '0') & c[2] else: correctedVal = c[0] & alignLeft(c[2], 3, '0') & c[3]
return corrected.parse(PG_TIMESTAMP_FORMATS[1])
except: var errStr = ""
errStr &= "\n\t" & PG_TIMESTAMP_FORMATS[1] &
" after padding out milliseconds to full 3-digits" # Try to parse directly using known format strings.
for df in PG_TIMESTAMP_FORMATS:
try: return correctedVal.parse(df)
except: errStr &= "\n\t" & getCurrentExceptionMsg()
raise newException(ValueError, "Cannot parse PG date. Tried:" & errStr) raise newException(ValueError, "Cannot parse PG date. Tried:" & errStr)