我试图找到一种方法来检查当前时间是否在给定的时间间隔内,用户最终(最终)会给出开始和结束的时间。
在确保所有时间都在UTC之后,我一直在尝试使用Time包中的After和Before,但是显然我做错了。
代码看起来类似于以下示例:
>>> import re
>>> re.sub('\D', '', 'random123random456')
'123456'
>>> re.sub('\D', '', 'random123')
'123'
感谢您的帮助。
答案 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日期进行Before
和After
进行比较的诀窍是,只要将其结束时间“小于”开始时间,则将结束时间推至第二天。然后,如果检查时间早于开始时间,则需要进行相同的操作。
我接受了相同的测试用例,并添加了一些重要的测试用例,例如午夜。
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
答案 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
该吃饭了!