Created
March 28, 2023 08:09
-
-
Save kaimingguo/2593bcd9d09aeea0b2588eaaab8729cc to your computer and use it in GitHub Desktop.
ISO8601 duration format parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"regexp" | |
"strconv" | |
"time" | |
) | |
func main() { | |
durationString := "P2YT1H8.001S" | |
fmt.Println("duration: ", durationString) | |
re := regexp.MustCompile(`^(-?)P(?:T*|\d)(?:(-?\d+)Y)?(?:(-?\d+)M)?(?:(-?\d+)([DW]))?(?:T(?:(-?\d+)H)?(?:(-?\d+)M)?(?:(-?\d+(?:\.\d+)?)S)?)?$`) | |
matches := re.FindStringSubmatch(durationString) | |
if len(matches) == 0 { | |
panic(fmt.Errorf("your regular expression does not match the subject string")) | |
} | |
var ( | |
numOffset int | |
years int | |
months int | |
days int | |
hours int | |
minutes int | |
seconds float64 | |
) | |
if s := matches[1]; s != "" { | |
numOffset = -1 | |
} else { | |
numOffset = 1 | |
} | |
if i32, err := strconv.Atoi(matches[2]); err == nil { | |
years = numOffset * i32 | |
} | |
if i32, err := strconv.Atoi(matches[3]); err == nil { | |
months = numOffset * i32 | |
} | |
if i32, err := strconv.Atoi(matches[4]); err == nil { | |
switch matches[5] { | |
case "W": | |
days = numOffset * i32 * 7 | |
case "D": | |
days = numOffset * i32 | |
} | |
} | |
if i32, err := strconv.Atoi(matches[6]); err == nil { | |
hours = numOffset * i32 | |
} | |
if i32, err := strconv.Atoi(matches[7]); err == nil { | |
minutes = numOffset * i32 | |
} | |
if f64, err := strconv.ParseFloat(matches[8], 64); err == nil { | |
seconds = float64(numOffset) * f64 | |
} | |
fmt.Println("Group 1 (offset)", numOffset) | |
fmt.Println("Group 2 (year)", years) | |
fmt.Println("Group 3 (month)", months) | |
fmt.Println("Group 4 (day)", days) | |
fmt.Println("Group 6 (hour)", hours) | |
fmt.Println("Group 7 (minute)", minutes) | |
fmt.Println("Group 8 (second)", seconds) | |
now := time.Now() | |
fmt.Println("current time: ", now.Format(time.RFC3339)) | |
result := now.AddDate(years, months, days) | |
result = result.Add(time.Hour * time.Duration(hours)) | |
result = result.Add(time.Minute * time.Duration(minutes)) | |
result = result.Add(time.Second * time.Duration(seconds)) | |
fmt.Println("expiration time: ", result.Format(time.RFC3339)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment