diff --git a/private/models.nim b/private/models.nim index 2dd02ef..652d467 100644 --- a/private/models.nim +++ b/private/models.nim @@ -9,6 +9,8 @@ type Timeline* = tuple[name: string, marks: seq[Mark]] ## Representation of a timeline: a name and sequence of Marks. + OffsetFrom = enum Year, Month, Day, None + const STOP_MSG* = "STOP" let NO_MARK*: Mark = ( @@ -20,11 +22,18 @@ const ISO_TIME_FORMAT* = "yyyy-MM-dd'T'HH:mm:ss" ## The canonical time format used by PTK. const TIME_FORMATS* = @[ - "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd'T'HH:mm", "yyyy-MM-dd HH:mm", - "MM-dd'T'HH:mm:ss", "MM-dd HH:mm:ss", - "MM-dd'T'HH:mm", "MM-dd HH:mm", - "HH:mm:ss", "H:mm:ss", "H:mm", "HH:mm" ] + (fmtStr: "yyyy-MM-dd'T'HH:mm:ss", offsetFrom: OffsetFrom.None), + (fmtStr: "yyyy-MM-dd HH:mm:ss", offsetFrom: OffsetFrom.None), + (fmtStr: "yyyy-MM-dd'T'HH:mm", offsetFrom: OffsetFrom.None), + (fmtStr: "yyyy-MM-dd HH:mm", offsetFrom: OffsetFrom.None), + (fmtStr: "MM-dd'T'HH:mm:ss", offsetFrom: OffsetFrom.Year), + (fmtStr: "MM-dd HH:mm:ss", offsetFrom: OffsetFrom.Year), + (fmtStr: "MM-dd'T'HH:mm", offsetFrom: OffsetFrom.Year), + (fmtStr: "MM-dd HH:mm", offsetFrom: OffsetFrom.Year), + (fmtStr: "HH:mm:ss", offsetFrom: OffsetFrom.Day), + (fmtStr: "H:mm:ss", offsetFrom: OffsetFrom.Day), + (fmtStr: "H:mm", offsetFrom: OffsetFrom.Day), + (fmtStr: "HH:mm", offsetFrom: OffsetFrom.Day) ] ## Other time formats that PTK will accept as input. proc getOrFail*(n: JsonNode, key: string, objName: string = ""): JsonNode = @@ -40,7 +49,23 @@ proc getIfExists*(n: JsonNode, key: string): JsonNode = proc parseTime*(timeStr: string): DateTime = ## Helper to parse time strings trying multiple known formats. for fmt in TIME_FORMATS: - try: return parse(timeStr, fmt) + try: + let now = now() + let parsed = parse(timeStr, fmt.fmtStr) + case fmt.offsetFrom: + of OffsetFrom.None: + return parsed + of OffsetFrom.Year: + return initDateTime(parsed.monthday, parsed.month, now.year, + parsed.hour, parsed.minute, parsed.second, parsed.nanosecond, + now.timezone) + of OffsetFrom.Month: + return initDateTime(parsed.monthday, now.month, now.year, + parsed.hour, parsed.minute, parsed.second, parsed.nanosecond, + now.timezone) + of OffsetFrom.Day: + return initDateTime(now.monthday, now.month, now.year, parsed.hour, + parsed.minute, parsed.second, parsed.nanosecond, now.timezone) except: discard nil raise newException(Exception, "unable to interpret as a date: " & timeStr) @@ -112,5 +137,3 @@ proc getLastIndex*(marks: seq[Mark]): int = while idx >= 0 and marks[idx].summary == STOP_MSG: idx -= 1 if idx < 0: result = -1 else: result = idx - -