在golang的date/时间比较

在Golang中进行date比较有什么select吗? 我必须根据date和时间对数据进行分类。 所以我可能会允许一个对象发生在一个date范围内,只要它也出现在一个时间范围内。 在这个模型中,我不能简单地select最老的date,最新的时间/最新的date,最新的时间和Unix()秒来比较它们。 我真的很感激任何build议。

最终,我写了一个时间parsingstring比较模块来检查时间是否在一个范围内。 然而,这并不是很好, 我有一些空头的问题。 我只是为了好玩而在这里张贴,但我希望有一个更好的方法来比较。

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(范围,时间)函数,但它不能正常工作。 (事实上​​,大多数情况下,第二种情况是时间跨度超过几天,原来的部分工作,我刚刚意识到,当从本地转换为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; } 

不过,我真的想做这个filter服务器端。

使用时间包在Go中处理时间信息。

播放示例:

 package main import ( "fmt" "time" ) func inTimeSpan(start, end, check time.Time) bool { return check.After(start) && check.Before(end) } func main() { start, _ := time.Parse(time.RFC822, "01 Jan 15 10:00 UTC") end, _ := time.Parse(time.RFC822, "01 Jan 16 10:00 UTC") in, _ := time.Parse(time.RFC822, "01 Jan 15 20:00 UTC") out, _ := time.Parse(time.RFC822, "01 Jan 17 10:00 UTC") if inTimeSpan(start, end, in) { fmt.Println(in, "is between", start, "and", end, ".") } if !inTimeSpan(start, end, out) { fmt.Println(out, "is not between", start, "and", end, ".") } } 

两次比较使用time.Sub()

 // utc life loc, _ := time.LoadLocation("UTC") // setup a start and end time createdAt := time.Now().In(loc).Add(1 * time.Hour) expiresAt := time.Now().In(loc).Add(4 * time.Hour) // get the diff diff := expiresAt.Sub(createdAt) fmt.Printf("Lifespan is %+v", diff) 

程序输出:

 Lifespan is 3h0m0s 

http://play.golang.org/p/bbxeTtd4L6

如果你的时间间隔结束的时候没有像“从2017-01-01到2017-01-16全天”那样的小时数,最好把间隔时间调整为23小时59分59秒,如下所示:

 end = end.Add(time.Duration(23*time.Hour) + time.Duration(59*time.Minute) + time.Duration(59*time.Second)) if now.After(start) && now.Before(end) { ... } 

以下解决了将string转换为date的问题

包主要

 import ( "fmt" "time" ) func main() { value := "Thu, 05/19/11, 10:47PM" // Writing down the way the standard time would look like formatted our way layout := "Mon, 01/02/06, 03:04PM" t, _ := time.Parse(layout, value) fmt.Println(t) } // => "Thu May 19 22:47:00 +0000 2011" 

感谢保罗·亚当·史密斯

最近的协议更喜欢每个golang时间包文档使用RFC3339。

对于坚持这种格式的服务器,通常应该使用RFC1123Z而不是RFC1123Z,RFC3339应该是新协议的首选。 RFC822,RFC822Z,RFC1123和RFC1123Z对格式化非常有用; 当与time.Parse一起使用时,他们不接受RFC允许的所有时间格式。

 cutOffTime, _ := time.Parse(time.RFC3339, "2017-08-30T13:35:00Z") // POSTDATE is a date time field in DB (datastore) query := datastore.NewQuery("db").Filter("POSTDATE >=", cutOffTime).