golang中的日期/时间比较

eat*_*hil 83 datetime go datetime-comparison

在Golang中进行日期比较有什么选择吗?我必须根据日期和时间对数据进行排序 - 独立.因此,我可以允许在一系列日期内发生的对象,只要它也在一定范围内发生.在这个模型中,我不能简单地选择最早的日期,最年轻的时间/最晚的日期,最新的时间和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
}
Run Code Online (Sandbox Code Playgroud)

所以TLDR,我写了一个内部时间范围(范围,时间)函数,但它没有完全正常工作.(事实上​​,大多数情况下只是第二种情况,时间跨度超过几天.原来的部分有效,我只是意识到在从本地转换到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;
}
Run Code Online (Sandbox Code Playgroud)

但是我真的想做这个过滤器服务器端.

and*_*olm 90

使用时间包在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, ".")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 尝试http://godoc.org/time#Time.Equal或http://godoc.org/time#Time.After进行简单比较,或http://godoc.org/time#Time.Sub找出两次之间的差异. (11认同)
  • 也许我看不懂,但我没有看到任何关于时间比较的内容。如果有的话,你能给我指出一篇确切的文章吗? (2认同)

Cha*_*aye 18

对于两个时间之间的比较使用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)
Run Code Online (Sandbox Code Playgroud)

该方案产出:

Lifespan is 3h0m0s
Run Code Online (Sandbox Code Playgroud)

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

  • 这是最好的答案。 (2认同)

Ole*_*kin 12

如果您的间隔结束时没有像"从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) {
    ...
}
Run Code Online (Sandbox Code Playgroud)


Igo*_*gor 9

可以将int64Unix 纪元的日期使用与秒粒度进行比较。如果您需要更精确的比较,例如毫秒或微秒等。我想@Oleg Neumyvakin 的答案是完美的。

if expirationDate.Unix() > time.Now().Unix() {
...
}
Run Code Online (Sandbox Code Playgroud)