Jonathan Bernard c4717b4b00 Date types default to date-time as specified.
- `parseDateOrDateTime attempts to parse times starting from the most
  specific (date and time) to least specific.
- `set` and `add` functions allow adding multiple content items at once
  using varargs.
2023-04-15 07:03:24 -05:00

56 lines
1.4 KiB
Nim

import sequtils, strutils, times
const DATE_FMTS = [ "yyyy-MM-dd", "yyyyMMdd" ]
const DATE_TIME_FMTS = [
"yyyyMMdd'T'HHmmss",
"yyyyMMdd'T'HHmmssz",
"yyyyMMdd'T'HHmmsszzz",
"yyyyMMdd'T'HHmmss'.'fffzzz",
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd'T'HH:mm:ssz",
"yyyy-MM-dd'T'HH:mm:sszzz",
"yyyy-MM-dd'T'HH:mm:ss'.'fffzzz",
]
const ALL_FMTS = DATE_TIME_FMTS.toSeq & DATE_FMTS.toSeq
proc parseDateTimeStr(
dateStr: string,
dateFmts: openarray[string]
): DateTime {.inline, raises:[ValueError].} =
for fmt in dateFmts:
try: result = parse(dateStr, fmt)
except ValueError: discard
if not result.isInitialized:
raise newException(ValueError, "cannot parse date: " & dateStr )
proc parseDate*(dateStr: string): DateTime =
parseDateTimeStr(dateStr, DATE_FMTS)
proc parseDateTime*(dateStr: string): DateTime =
parseDateTimeStr(dateStr, DATE_TIME_FMTS)
proc parseDateOrDateTime*(dateStr: string): DateTime =
parseDateTimeStr(dateStr, ALL_FMTS)
func foldContentLine*(s: string): string =
result = ""
var rem = s
while rem.len > 75: # TODO: unicode multi-byte safe?
result &= rem[0..<75] & "\r\n "
rem = rem[75..^1]
result &= rem
func unfoldContentLine*(s: string): string =
return s.multiReplace([("\r\n ", "")])
template indexOfIt*(s, pred: untyped): int =
var result = -1
for idx, it {.inject.} in pairs(s):
if pred:
result = idx
break
result