如何在GO中解析相对日期时间?
相对日期的例子:
today at 9:17 AM
yesterday at 9:58 PM
Saturday at 9:44 PM
Wednesday at 11:01 AM
因此格式为DAY (in the past) at TIME
。我尝试了下一个例子:
const longForm = "Monday at 3:04 PM"
t, _ := time.Parse(longForm, "Saturday at 3:50 PM")
fmt.Println(t)
正确解析时间,但忽略日期/日期......
答案 0 :(得分:1)
扩展我的评论:
只有Monday
没有进一步的日期引用在解析器的眼中是没有意义的,所以它被丢弃了。哪个星期一?解析器是严格的,而不是模糊的。假设星期一指的是当前周不是这样的解析器可以做的事情。你不会为此编写自己更复杂的解析器。
所以它必须沿着这些方向 - 一个将相对模糊日转换为实际日期的函数,并替换原始表达式中的函数,另一个函数解析整个事物:
const dateFormat = "2006-01-02"
const longForm = "2006-01-02 at 3:04 PM"
func parseFuzzyDate(fuzzyTime string) (time.Time, error) {
formattedTime, err := parseDayAndReplaceIt(fuzzyTime)
if err != nil {
return nil, err
}
return time.Parse(longForm, formattedTime)
}
并且第二个函数获得模糊时间,找到日期,解析它并返回。我不打算实现它,只需在评论中写下应该做什么:
func parseDayAndReplaceIt(fuzzyTime string) (string, error) {
// 1. Extract the day
// 2. Parse weekday names to relative time
// 3. if it's not a weekday name, parse things like "tomorrow" "yesterday"
// 4. replace the day string in the original fuzzyTime with a formatted date that the parser can understand
// 5. return the formatted date
}
答案 1 :(得分:0)
我调整了一段时间后写的东西并将其合并到这个示例代码中:
func lastDateOf(targetDay time.Weekday, timeOfDay time.Time) time.Time {
const oneDay = 24 * time.Hour
var dayIndex time.Duration
//dayIndex -= oneDay
for {
if time.Now().Add(dayIndex).Weekday() == targetDay {
y, m, d := time.Now().Add(dayIndex).Date()
return timeOfDay.AddDate(y, int(m)-1, d-1)
}
dayIndex -= oneDay
}
}
它返回上一个targetDay
的相对于现在的日期,添加到timeOfDay
,假设timeOfDay
包含小时,分钟和秒,以及零时间值年,月,日它会给你一个合适的答案。
它不是很灵活,但我相信它很适合你的例子。虽然它没有涉及“明天”,“昨天”或“下周六”等相关术语。
playground中的可运行版本。
答案 2 :(得分:0)
自定义解析器:
func RelativeDateParse(s string) (time.Time, error) {
for n := 0; n < 7; n++ {
day := time.Now().AddDate(0, 0, -n)
dayName := day.Format("Monday")
switch n {
case 0:
dayName = "today"
case 1:
dayName = "yesterday"
}
s = strings.Replace(s, dayName + " at", day.Format("2006-01-02"), -1)
}
return time.Parse("2006-01-02 3:04 PM", s)
}