我试图找到一种方法来检查当前时间是否在给定的时间间隔内,开始和结束时间由用户(最终)给出。
在确保所有时间都在 UTC 之后,我一直在尝试使用 Time 包中的 After 和 Before,但显然我做错了什么。
代码看起来类似于这个例子:
func inTimeSpan(start, end, check time.Time) bool {
return check.After(start) && check.Before(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("1 : ", inTimeSpan(srt, end, ns))
}
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏。
编辑:最初是错误的,对此感到抱歉。固定版本,现在的范围也包括在内。也检查Mickael V. 答案,因为增加时间也很有意义。
func inTimeSpan(start, end, check time.Time) bool {
if start.Before(end) {
return !check.Before(start) && !check.After(end)
}
if start.Equal(end) {
return check.Equal(start)
}
return !start.After(check) || !end.Before(check)
}
Run Code Online (Sandbox Code Playgroud)
在操场上查看https://play.golang.org/p/CGWqY2AQ-Th
package main
import (
"fmt"
"time"
)
func inTimeSpan(start, end, check time.Time) bool {
if start.Before(end) {
return !check.Before(start) && !check.After(end)
}
if start.Equal(end) {
return check.Equal(start)
}
return !start.After(check) || !end.Before(check)
}
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"},
// Additional checks.
{"22:00", "02:00", "00:00"},
{"10:00", "21:00", "10:00"},
{"10:00", "21:00", "21:00"},
{"23:00", "05:00", "06:00"},
{"23:00", "05:00", "23:00"},
{"23:00", "05:00", "05:00"},
{"10:00", "21:00", "10:00"},
{"10:00", "21:00", "21:00"},
{"10:00", "10:00", "09:00"},
{"10:00", "10:00", "11:00"},
{"10:00", "10:00", "10: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))
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
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 true
10:00-21:00 21:00 true
23:00-05:00 06:00 false
23:00-05:00 23:00 true
23:00-05:00 05:00 true
10:00-21:00 10:00 true
10:00-21:00 21:00 true
10:00-10:00 09:00 false
10:00-10:00 11:00 false
10:00-10:00 10:00 true
Run Code Online (Sandbox Code Playgroud)
这是一个干净的解决方案,不受时区问题的影响。在我的上下文中,我在并发计时器线程中运行一个函数,它每 5 分钟调用该函数来检查给定范围内的时间。
请注意,您应该仅使用整分钟才能使其发挥作用。虽然我还没有测试过,但我认为time.Kitchen布局会在时间转换过程中减少几秒钟的时间。无需指定秒数,因为选择器将在该范围内的每个时间(除了确切的结束时间)进行计时。
没有午夜的统计,但我不需要该功能。如果你想要你可以测试
if end.Before(start) {
if timeNow.After(start) {
return false
}
if timeNow.After(end) {
return true
}
return false
} else {
....
}
Run Code Online (Sandbox Code Playgroud)
这是我的功能。
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
}
Run Code Online (Sandbox Code Playgroud)
输出
沃尔夫先生,现在几点了?
上午 10:58 区域: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 区域:ACST 偏移 UTC:34200
现在字符串时间:上午 11:03
解码时间: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
是时候吃掉你了!