在Go语言中进行日期比较有什么选择吗?我必须根据日期和时间对数据进行排序--独立的。所以我可能会允许一个对象出现在一个日期范围内,只要它也出现在一个时间范围内。在这个模型中,我不能简单地选择最早的日期、最年轻的时间/最晚的日期、最晚的时间和Unix()秒来比较它们。我真的很感谢你的建议。
最后,我编写了一个时间解析字符串比较模块来检查时间是否在某个范围内。我有一些空白的问题。我会张贴在这里只是为了好玩,但我希望有一个更好的方式来比较时间。
package main
import (
"strconv"
"strings"
)
func tryIndex(arr []string, index int, def string) string {
if index <= len(arr)-1 {
return arr[index]
}
return def
}
/*
* Takes two strings of format "hh:mm:ss" and compares them.
* Takes a function to compare individual sections (split by ":").
* Note: strings can actually be formatted like "h", "hh", "hh:m",
* "hh:mm", etc. Any missing parts will be added lazily.
*/
func timeCompare(a, b string, compare func(int, int) (bool, bool)) bool {
aArr := strings.Split(a, ":")
bArr := strings.Split(b, ":")
// Catches margins.
if (b == a) {
return true
}
for i := range aArr {
aI, _ := strconv.Atoi(tryIndex(aArr, i, "00"))
bI, _ := strconv.Atoi(tryIndex(bArr, i, "00"))
res, flag := compare(aI, bI)
if res {
return true
} else if flag { // Needed to catch case where a > b and a is the lower limit
return false
}
}
return false
}
func timeGreaterEqual(a, b int) (bool, bool) {return a > b, a < b}
func timeLesserEqual(a, b int) (bool, bool) {return a < b, a > b}
/*
* Returns true for two strings formmated "hh:mm:ss".
* Note: strings can actually be formatted like "h", "hh", "hh:m",
* "hh:mm", etc. Any missing parts will be added lazily.
*/
func withinTime(timeRange, time string) bool {
rArr := strings.Split(timeRange, "-")
if timeCompare(rArr[0], rArr[1], timeLesserEqual) {
afterStart := timeCompare(rArr[0], time, timeLesserEqual)
beforeEnd := timeCompare(rArr[1], time, timeGreaterEqual)
return afterStart && beforeEnd
}
// Catch things like `timeRange := "22:00:00-04:59:59"` which will happen
// with UTC conversions from local time.
// THIS IS THE BROKEN PART I BELIEVE
afterStart := timeCompare(rArr[0], time, timeLesserEqual)
beforeEnd := timeCompare(rArr[1], time, timeGreaterEqual)
return afterStart || beforeEnd
}
TLDR,我写了一个withinTimeRange(range,time)函数,但它不能完全正确地工作。(事实上,主要是第二种情况,时间范围跨越了几天。最初的部分工作正常,我只是意识到在从本地转换到UTC时需要考虑这一点。)
如果有更好的(最好是内置的)方式,我很乐意听到它!
注意:作为一个例子,我在Javascript中用这个函数解决了这个问题:
function withinTime(start, end, time) {
var s = Date.parse("01/01/2011 "+start);
var e = Date.parse("01/0"+(end=="24:00:00"?"2":"1")+"/2011 "+(end=="24:00:00"?"00:00:00":end));
var t = Date.parse("01/01/2011 "+time);
return s <= t && e >= t;
}
不过,我真的想做这个过滤器服务器端。
9条答案
按热度按时间pxyaymoc1#
使用time包在Go语言中处理时间信息。
可以使用Before、After和Equal方法比较时间瞬间。Sub方法减去两个瞬间,产生持续时间。Add方法将时间和持续时间相加,产生时间。
Play示例:
fhg3lkii2#
对于***两个时间之间的比较***使用time.sub()
程序输出:
http://play.golang.org/p/bbxeTtd4L6
pbgvytdp3#
对于间隔的
end
日期不包含小时(如“从2017-01-01到2017-01-16全天”)的情况,最好将间隔的end
调整为第二天的午夜,以包括所有毫秒,如下所示:xam8gpfp4#
可以使用
int64
的Unix纪元以秒为粒度来比较日期。如果你需要更精确的比较,如毫秒或微秒等,我想@Oleg Neumyvakin的答案是完美的。h7wcgrx35#
如果你有兴趣比较一个时间是否接近另一个时间以进行测试,你可以使用testi
assert.WithinDuration
来完成这个任务。否则,可以在代码中重用
assert.WithinDuration
的实现,以确定两个时间的接近程度(从一个日期减去另一个日期得到时间差):cbjzeqam6#
最近的协议更倾向于使用RFC 3339/golang time package documentation。
通常,对于坚持RFC 1123 Z格式的服务器,应该使用RFC 1123 Z而不是RFC 1123,对于新协议,应该首选RFC 3339。RFC 822、RFC 822 Z、RFC 1123和RFC 1123 Z对于格式化是有用的;它们不接受RFC允许的所有时间格式。
bwleehnv7#
如the theread中所述,我们可以在测试中使用
github.com/google/go-cmp/cmp
包进行日期比较。v8wbuo2f8#
yyyllmsg9#
根据提议time: add Time.Compare和related commit,将在新版本(Go 1.20)中添加
time.Compare
样品