检查当前时间是否在给定间隔GOLANG中

时间:2019-03-11 00:06:04

标签: go time

我试图找到一种方法来检查当前时间是否在给定的时间间隔内,用户最终(最终)会给出开始和结束的时间。

在确保所有时间都在UTC之后,我一直在尝试使用Time包中的After和Before,但是显然我做错了。

代码看起来类似于以下示例:

>>> import re
>>> re.sub('\D', '', 'random123random456')
'123456'
>>> re.sub('\D', '', 'random123')
'123'

感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

例如,

package main

import (
    "fmt"
    "strconv"
    "time"
)

func inTimeSpan(start, end, check time.Time) bool {
    start, end = start.UTC(), end.UTC()
    if start.After(end) {
        start, end = end, start
    }
    check = check.UTC()
    return !check.Before(start) && !check.After(end)
}

func main() {
    now := time.Now()
    newLayout := "15:04"
    ns, _ := time.Parse(newLayout, strconv.Itoa(now.Hour())+":"+strconv.Itoa(now.Minute()))
    srt, _ := time.Parse(newLayout, "23:00")
    end, _ := time.Parse(newLayout, "05:00")

    fmt.Println(srt, end)
    fmt.Println(ns)
    fmt.Println("1 : ", inTimeSpan(srt, end, ns))
}

输出:

0000-01-01 23:00:00 +0000 UTC 0000-01-01 05:00:00 +0000 UTC
0000-01-01 20:37:00 +0000 UTC
1 :  true

答案 1 :(得分:1)

func inTimeSpan(start, end, check time.Time) bool {
    if check.After(end) {
        return false
    }
    if end.After(start) {
        return check.After(start)
    }
    return check.Before(start)
}

在游乐场https://play.golang.org/p/ISFpxzIjvY_L上查看

package main

import (
    "fmt"
    "time"
)

func inTimeSpan(start, end, check time.Time) bool {
    if check.After(end) {
        return false
    }
    if end.After(start) {
        return check.After(start)
    }
    return check.Before(start)
}

func main() {
    test := []struct {
        start string
        end   string
        check string
    }{
        {"23:00", "05:00", "04:00"},
        {"23:00", "05:00", "23:30"},
        {"23:00", "05:00", "20:00"},
        {"10:00", "21:00", "11:00"},
        {"10:00", "21:00", "22:00"},
        {"10:00", "21:00", "03:00"},
    }
    newLayout := "15:04"
    for _, t := range test {
        check, _ := time.Parse(newLayout, t.check)
        start, _ := time.Parse(newLayout, t.start)
        end, _ := time.Parse(newLayout, t.end)
        fmt.Println(t.start+"-"+t.end, t.check, inTimeSpan(start, end, check))
    }
}

结果:

23:00-05:00 04:00 true
23:00-05:00 23:30 false
23:00-05:00 20:00 false
10:00-21:00 11:00 true
10:00-21:00 22:00 false
10:00-21:00 03:00 false

答案 2 :(得分:0)

建立在Kamil's answer上,这是错误的,正如它自己的测试所示,这是一种仅使用Go的时间接口的解决方案。 知道Go会使用时间AND日期进行BeforeAfter进行比较的诀窍是,只要将其结束时间“小于”开始时间,则将结束时间推至第二天。然后,如果检查时间早于开始时间,则需要进行相同的操作。

我接受了相同的测试用例,并添加了一些重要的测试用例,例如午夜。

package main

import (
    "fmt"
    "time"
)

func inTimeSpan(start, end, check time.Time) bool {
    _end := end
    _check := check
    if end.Before(start) {
        _end = end.Add(24 * time.Hour)
        if check.Before(start) {
            _check = check.Add(24 * time.Hour)
        }
    }
    return _check.After(start) && _check.Before(_end)
}

func main() {
    test := []struct {
        start string
        end   string
        check string
    }{
        {"23:00", "05:00", "04:00"},
        {"23:00", "05:00", "23:30"},
        {"23:00", "05:00", "20:00"},
        {"10:00", "21:00", "11:00"},
        {"10:00", "21:00", "22:00"},
        {"10:00", "21:00", "03:00"},
        {"22:00", "02:00", "00:00"},
        {"10:00", "21:00", "10:00"},
        {"10:00", "21:00", "21:00"},
    }
    newLayout := "15:04"
    for _, t := range test {
        check, _ := time.Parse(newLayout, t.check)
        start, _ := time.Parse(newLayout, t.start)
        end, _ := time.Parse(newLayout, t.end)
        fmt.Println(t.start+"-"+t.end, t.check, inTimeSpan(start, end, check))
    }
}

输出:

23:00-05:00 04:00 true
23:00-05:00 23:30 true
23:00-05:00 20:00 false
10:00-21:00 11:00 true
10:00-21:00 22:00 false
10:00-21:00 03:00 false
22:00-02:00 00:00 true
10:00-21:00 10:00 false
10:00-21:00 21:00 false

您会注意到,在最后两种情况下,开始时间和结束时间都不包括支票。如果您需要更改该行为,则可以通过稍微更改功能来补救:

func inTimeSpanEx(start, end, check time.Time, includeStart, includeEnd bool) bool {
    _start := start
    _end := end
    _check := check
    if end.Before(start) {
        _end = end.Add(24 * time.Hour)
        if check.Before(start) {
            _check = check.Add(24 * time.Hour)
        }
    }

    if includeStart {
    _start = _start.Add(-1 * time.Nanosecond)
    }
    if includeEnd {
    _end = _end.Add(1 * time.Nanosecond)
    }

    return _check.After(_start) && _check.Before(_end)
}

true调用以包含开始和结束时提取输出:

10:00-21:00 10:00 true
10:00-21:00 21:00 true

完整的游乐场:https://play.golang.org/p/8ig34gmHl71

答案 3 :(得分:0)

这是一个干净的解决方案,不受时区问题的影响。在我的上下文中,我在并发计时器线程中运行一个函数,该函数每5分钟调用一次此函数,以检查给定范围内的时间。

请注意,您仅应使用整分钟的时间才能正常工作。虽然我没有测试过,但我认为time.Kitchen布局会在时间转换过程中减少几秒钟的时间。无需指定秒数,因为选择器将在除精确结束时间之外的范围内每次都花费时间。

没有考虑到午夜,但我不需要该功能。如果您想测试

if end.Before(start) {

if timeNow.After(start) {
   return false 
}

if timeNow.After(end) {
   return true
}
return false
} else {

....
}

这是我的功能。

func stringToTime(str string) time.Time {
    tm, err := time.Parse(time.Kitchen, str)
    if err != nil {
        fmt.Println("Failed to decode time:", err)
    }
    fmt.Println("Time decoded:", tm)
    return tm
}

func isInTimeRange() bool {

    startTimeString := "06:00AM"  // "01:00PM"

    endTimeString := "06:05AM"

    t := time.Now()

    zone, offset := t.Zone()

    fmt.Println(t.Format(time.Kitchen), "Zone:", zone, "Offset UTC:", offset)

    timeNowString := t.Format(time.Kitchen)

    fmt.Println("String Time Now: ", timeNowString)

    timeNow := stringToTime(timeNowString)

    start := stringToTime(startTimeString)

    end := stringToTime(endTimeString)

    fmt.Println("Local Time Now: ", timeNow)

    if timeNow.Before(start) {
        return false
    }

    if timeNow.Before(end) {
        return true
    }

    return false
}

输出

  

现在几点,沃尔夫先生?

     

10:58 AM区域:ACST偏移UTC:34200

     

现在的字符串时间:上午10:58

     

解码时间:0000-01-01 10:58:00 +0000 UTC

     

解码时间:0000-01-01 11:00:00 +0000 UTC

     

解码时间:0000-01-01 11:05:00 +0000 UTC

     

现在本地时间:0000-01-01 10:58:00 +0000 UTC

     

现在几点,沃尔夫先生?

     

11:03 AM区域:ACST偏移UTC:34200

     

字符串时间现在:11:03AM

     

解码时间:0000-01-01 11:03:00 +0000 UTC

     

解码时间:0000-01-01 11:00:00 +0000 UTC

     

解码时间:0000-01-01 11:05:00 +0000 UTC

     

现在本地时间:0000-01-01 11:03:00 +0000 UTC

     

该吃饭了!