英文:
Golang parse time.Duration
问题
我想解析 time.Duration
。持续时间是 "PT15M"
(字符串/字节),我想将其转换为有效的 time.Duration
。
如果这是一个 time.Time
的东西,我会使用:
t, err := time.Parse(time.RFC3339Nano, "2013-06-05T14:10:43.678Z")
但是这个函数不存在(ParseDuration
只接受一个参数):
d, err := time.ParseDuration(time.RFC3339Nano, "PT15M")
我该如何解析这个 ISO 8601 duration?
英文:
I would like to parse time.Duration
. The duration is "PT15M"
(string/bytes) and would like to convert it to a valid time.Duration
.
If this were a time.Time
thing, I would use:
But this doesn't exist (ParseDuration
only takes one parameter):
How can I parse this ISO 8601 duration?
答案1
得分: 3
这是一个用于解析时间持续的正则表达式的代码示例:
package main
import "fmt"
import "regexp"
import "strconv"
import "time"
func main() {
fmt.Println(ParseDuration("PT15M"))
fmt.Println(ParseDuration("P12Y4MT15M"))
}
func ParseDuration(str string) time.Duration {
durationRegex := regexp.MustCompile(`P(?P<years>\d+Y)?(?P<months>\d+M)?(?P<days>\d+D)?T?(?P<hours>\d+H)?(?P<minutes>\d+M)?(?P<seconds>\d+S)?`)
matches := durationRegex.FindStringSubmatch(str)
years := ParseInt64(matches[1])
months := ParseInt64(matches[2])
days := ParseInt64(matches[3])
hours := ParseInt64(matches[4])
minutes := ParseInt64(matches[5])
seconds := ParseInt64(matches[6])
hour := int64(time.Hour)
minute := int64(time.Minute)
second := int64(time.Second)
return time.Duration(years*24*365*hour + months*30*24*hour + days*24*hour + hours*hour + minutes*minute + seconds*second)
}
func ParseInt64(value string) int64 {
if len(value) == 0 {
return 0
}
parsed, err := strconv.Atoi(value[:len(value)-1])
if err != nil {
return 0
}
return int64(parsed)
}
这段代码使用正则表达式解析时间持续字符串,并将其转换为Go语言中的time.Duration
类型。它可以解析包含年、月、日、小时、分钟和秒的时间持续字符串,并将其转换为对应的持续时间。
英文:
It's not exactly "out of the box" but a regular expression does the job:
package main
import "fmt"
import "regexp"
import "strconv"
import "time"
func main() {
fmt.Println(ParseDuration("PT15M"))
fmt.Println(ParseDuration("P12Y4MT15M"))
}
func ParseDuration(str string) time.Duration {
durationRegex := regexp.MustCompile(`P(?P<years>\d+Y)?(?P<months>\d+M)?(?P<days>\d+D)?T?(?P<hours>\d+H)?(?P<minutes>\d+M)?(?P<seconds>\d+S)?`)
matches := durationRegex.FindStringSubmatch(str)
years := ParseInt64(matches[1])
months := ParseInt64(matches[2])
days := ParseInt64(matches[3])
hours := ParseInt64(matches[4])
minutes := ParseInt64(matches[5])
seconds := ParseInt64(matches[6])
hour := int64(time.Hour)
minute := int64(time.Minute)
second := int64(time.Second)
return time.Duration(years*24*365*hour + months*30*24*hour + days*24*hour + hours*hour + minutes*minute + seconds*second)
}
func ParseInt64(value string) int64 {
if len(value) == 0 {
return 0
}
parsed, err := strconv.Atoi(value[:len(value)-1])
if err != nil {
return 0
}
return int64(parsed)
}
答案2
得分: 1
以下是处理分数时间单位(如PT3.001S
)的代码。
var durationRegex = regexp.MustCompile(`P([\d\.]+Y)?([\d\.]+M)?([\d\.]+D)?T?([\d\.]+H)?([\d\.]+M)?([\d\.]+?S)?`)
// ParseDuration将ISO8601持续时间转换为time.Duration
func ParseDuration(str string) time.Duration {
matches := durationRegex.FindStringSubmatch(str)
years := parseDurationPart(matches[1], time.Hour*24*365)
months := parseDurationPart(matches[2], time.Hour*24*30)
days := parseDurationPart(matches[3], time.Hour*24)
hours := parseDurationPart(matches[4], time.Hour)
minutes := parseDurationPart(matches[5], time.Second*60)
seconds := parseDurationPart(matches[6], time.Second)
return time.Duration(years + months + days + hours + minutes + seconds)
}
func parseDurationPart(value string, unit time.Duration) time.Duration {
if len(value) != 0 {
if parsed, err := strconv.ParseFloat(value[:len(value)-1], 64); err == nil {
return time.Duration(float64(unit) * parsed)
}
}
return 0
}
希望对你有帮助!
英文:
Here is code that handles fractional time units like PT3.001S
.
var durationRegex = regexp.MustCompile(`P([\d\.]+Y)?([\d\.]+M)?([\d\.]+D)?T?([\d\.]+H)?([\d\.]+M)?([\d\.]+?S)?`)
// ParseDuration converts a ISO8601 duration into a time.Duration
func ParseDuration(str string) time.Duration {
matches := durationRegex.FindStringSubmatch(str)
years := parseDurationPart(matches[1], time.Hour*24*365)
months := parseDurationPart(matches[2], time.Hour*24*30)
days := parseDurationPart(matches[3], time.Hour*24)
hours := parseDurationPart(matches[4], time.Hour)
minutes := parseDurationPart(matches[5], time.Second*60)
seconds := parseDurationPart(matches[6], time.Second)
return time.Duration(years + months + days + hours + minutes + seconds)
}
func parseDurationPart(value string, unit time.Duration) time.Duration {
if len(value) != 0 {
if parsed, err := strconv.ParseFloat(value[:len(value)-1], 64); err == nil {
return time.Duration(float64(unit) * parsed)
}
}
return 0
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论