parseDuration parses a time duration from a string.
(s string)
| 562 | |
| 563 | // parseDuration parses a time duration from a string. |
| 564 | func parseDuration(s string) (time.Duration, error) { |
| 565 | // Return an error if the string is blank or one character |
| 566 | if len(s) < 2 { |
| 567 | return 0, ErrInvalidDuration |
| 568 | } |
| 569 | |
| 570 | // Split string into individual runes. |
| 571 | a := []rune(s) |
| 572 | |
| 573 | // Start with a zero duration. |
| 574 | var d time.Duration |
| 575 | i := 0 |
| 576 | |
| 577 | // Check for a negative. |
| 578 | isNegative := false |
| 579 | if a[i] == '-' { |
| 580 | isNegative = true |
| 581 | i++ |
| 582 | } |
| 583 | |
| 584 | var measure int64 |
| 585 | var unit string |
| 586 | |
| 587 | // Parsing loop. |
| 588 | for i < len(a) { |
| 589 | // Find the number portion. |
| 590 | start := i |
| 591 | for ; i < len(a) && isDigit(a[i]); i++ { |
| 592 | // Scan for the digits. |
| 593 | } |
| 594 | |
| 595 | // Check if we reached the end of the string prematurely. |
| 596 | if i >= len(a) || i == start { |
| 597 | return 0, ErrInvalidDuration |
| 598 | } |
| 599 | |
| 600 | // Parse the numeric part. |
| 601 | n, err := strconv.ParseInt(string(a[start:i]), 10, 64) |
| 602 | if err != nil { |
| 603 | return 0, ErrInvalidDuration |
| 604 | } |
| 605 | measure = n |
| 606 | |
| 607 | // Extract the unit of measure. |
| 608 | // If the last two characters are "ms" then parse as milliseconds. |
| 609 | // Otherwise, just use the last character as the unit of measure. |
| 610 | unit = string(a[i]) |
| 611 | switch a[i] { |
| 612 | case 'n': |
| 613 | if i+1 < len(a) && a[i+1] == 's' { |
| 614 | unit = string(a[i : i+2]) |
| 615 | d += time.Duration(n) |
| 616 | i += 2 |
| 617 | continue |
| 618 | } |
| 619 | return 0, ErrInvalidDuration |
| 620 | case 'u', 'µ': |
| 621 | d += time.Duration(n) * time.Microsecond |
no test coverage detected