Parses an ISO8601 (with designators) string. See the following links for examples: - http://www.postgresql.org/docs/9.1/static/datatype-datetime.html#DATATYPE-INTERVAL-INPUT-EXAMPLES - https://en.wikipedia.org/wiki/ISO_8601#Time_intervals - https://en.wikipedia.org/wiki/ISO_8601#Durations
(s string)
| 414 | // - https://en.wikipedia.org/wiki/ISO_8601#Time_intervals |
| 415 | // - https://en.wikipedia.org/wiki/ISO_8601#Durations |
| 416 | func iso8601ToDuration(s string) (duration.Duration, error) { |
| 417 | var d duration.Duration |
| 418 | if len(s) == 0 || s[0] != 'P' { |
| 419 | return d, newInvalidSQLDurationError(s) |
| 420 | } |
| 421 | |
| 422 | // Advance to offset 1, since we don't care about the leading P. |
| 423 | l := intervalLexer{str: s, offset: 1, err: nil} |
| 424 | unitMap := isoDateUnitMap |
| 425 | |
| 426 | for l.offset < len(s) { |
| 427 | // Check if we're in the time part yet. |
| 428 | if s[l.offset] == 'T' { |
| 429 | unitMap = isoTimeUnitMap |
| 430 | l.offset++ |
| 431 | } |
| 432 | |
| 433 | v := l.consumeInt() |
| 434 | u := l.consumeUnit('T') |
| 435 | if l.err != nil { |
| 436 | return d, l.err |
| 437 | } |
| 438 | |
| 439 | if unit, ok := unitMap[u]; ok { |
| 440 | d = d.Add(unit.Mul(v)) |
| 441 | } else { |
| 442 | return d, pgerror.Newf( |
| 443 | pgcode.InvalidDatetimeFormat, |
| 444 | "interval: unknown unit %s in ISO-8601 duration %s", u, s) |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | return d, nil |
| 449 | } |
| 450 | |
| 451 | // unitMap defines for each unit name what is the time duration for |
| 452 | // that unit. |
no test coverage detected
searching dependent graphs…