2 回答
TA贡献1862条经验 获得超6个赞
这是解决问题的一种方法:
package main
import "time"
type window struct { time.Time }
func (w window) isDay(s string) bool {
return w.Weekday().String() == s
}
func (w window) isHourRange(begin, end int) bool {
return w.Hour() >= begin && w.Hour() <= end
}
func main() {
w := window{
time.Now(),
}
{
b := w.isDay("Friday")
println(b)
}
{
b := w.isHourRange(20, 23)
println(b)
}
}
这假设只有一天有效,因此您需要修改它以处理多天。不过,这应该可以帮助您入门。
TA贡献1934条经验 获得超2个赞
有很多复杂的时代。例如:
如果升级日是“Søndag”(丹麦语)而不是“星期日”怎么办?
我们应该在当地时间还是 UTC 工作?如果是本地的,谁的位置很重要?如果服务器在伦敦而我在旧金山,我们使用服务器的时间还是我的时间?
如果升级间隔包括凌晨 2 点,那么这是否包括太平洋夏令时间凌晨 2 点和太平洋标准时间凌晨 2 点?这些时间在我住的地方相隔一小时。如果时间间隔从凌晨 2 点开始,到 2:59:59 结束,那么在许多 DST 轮班时间为一小时的地区,一年中的某一天不存在该时间。
如果您忽略所有这些复杂性——国际化 (i18n)、本地化 (l10n)、夏令时等——仍然存在一些问题,即有人可以设置日期和时间,或者升级本身可能需要一段时间,但通常我们也会忽略这些。
请注意,Gotime.Now()返回本地时间——但是,谁的位置?由于我们还没有回答使用哪个时区的问题,我们可能希望避免担心这个问题。给定其余的输入约束,让我们编写一个函数来确定提供的时间是否满足输入约束,而不是如果满足time.Now()。然后,调用者可以在用户的位置提供 UTC 时间或挂钟时间:
someNow = time.Time() localNow = someNow.In(location) // from time.LoadLocation() or similar
我们还有一些似乎与您的类型不一致的东西:
upgradeDuration int64- 时间量,从时间窗口有效的升级时间开始。最长可达 12 小时
以小时为单位的值介于 0 和 12(含)之间很容易适合 plain int。这是否已经是一个time.Duration以纳秒表示的值?如果是这样,为什么是int64而不是time.Duration?或者它是以秒为单位的值,因此可以在 0 到 43200 之间?如果是这样,它仍然适合int。
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
// startOK determines whether the given starting-time is within a
// time window.
//
// The window starts at a time given as two integers,
// h and m, representing hours and minutes, and extends for
// the given duration d in hours, which in general should not
// extend into another day. If it does extend past the end of
// the day into the next day, we ignore the extension.
//
// The days on which the time *is* in that window are further
// limited by the days[] slice of Weekday values.
//
// Note: it would probably be sensible to return a time.Duration
// value that is how long it will be until the next OK time, but
// we leave that as an exercise.
//
// It would also be sensible to allow the duration d to extend
// into the next day, which is also left as an exercise.
func startOK(when time.Time, days []time.Weekday, h, m, d int) bool {
// Find OK-to-start time, and end-time. If end exceeds
// 24*60, we ignore the extra end time, rather than
// allowing some minutes into the next day.
start := h*60 + m
end := start + d*60
// Convert when to hour-and-minute and see if we are
// in the allowed range.
wh, wm, _ := when.Clock()
now := wh*60 + wm
if now < start || now >= end {
// Not in hh:mm through hh+d:mm; say no.
return false
}
// The time-of-day is OK; check the day-of-week.
// We could do this earlier but by positioning it
// here, we leave room to check to see if it's
// the *next* day, if needed.
if !func(wd time.Weekday) bool {
for _, allowed := range days {
if wd == allowed {
return true
}
}
return false
}(when.Weekday()) {
return false // when.Weekday() not in days[]
}
// time is OK, day is OK
return true
}
// startOKstr is like startOK but the window starts at a time
// given as a string encoded as hh:mm, with the days being a
// slice of strings instead of Weekday. Because of these strings,
// parsing can produce an error, so this function has an error
// return.
func startOKStr(when time.Time, days []string, hhmm string, d int) (bool, error) {
parts := strings.Split(hhmm, ":")
// optional: be strict about two-digit values
if len(parts) != 2 {
return false, fmt.Errorf("invalid time string %q", hhmm)
}
h, err := strconv.Atoi(parts[0])
if err != nil {
return false, err
}
if h < 0 || h >= 60 {
return false, fmt.Errorf("invalid hour value %s", parts[0])
}
m, err := strconv.Atoi(parts[1])
if err != nil {
return false, err
}
if m < 0 || m >= 60 {
return false, fmt.Errorf("invalid minute value %s", parts[1])
}
var wd []time.Weekday
for _, s := range days {
w, err := parseWeekday(s)
if err != nil {
return false, err
}
wd = append(wd, w)
}
ok := startOK(when, wd, h, m, d)
return ok, nil
}
// parseWeekday handles weekday strings.
//
// Ideally we'd use time.Parse for this, as it already has
// these in it, but they are not exported in usable form.
func parseWeekday(s string) (time.Weekday, error) {
strToWeekday := map[string]time.Weekday{
"Sunday": time.Sunday,
"Monday": time.Monday,
"Tuesday": time.Tuesday,
"Wednesday": time.Wednesday,
"Thursday": time.Thursday,
"Friday": time.Friday,
"Saturday": time.Saturday,
}
if v, ok := strToWeekday[s]; ok {
return v, nil
}
return time.Sunday, fmt.Errorf("invalid day-of-week %q", s)
}
// tests should be converted to real tests and put in
// a separate file.
func tests() {
okDays := []string{"Sunday", "Wednesday"}
okStart := "04:00"
okDuration := 2 // hours
tfmt := "Mon Jan 2 15:04:05 2006"
t1 := "Sat Sep 5 04:30:00 2020" // time OK, day not
t2 := "Sun Sep 6 04:30:00 2020" // time OK, day OK
check := func(s string, expect bool) {
when, err := time.Parse(tfmt, s)
if err != nil {
panic(err)
}
result, err := startOKStr(when, okDays, okStart, okDuration)
if err != nil {
panic(err)
}
if result != expect {
fmt.Printf("fail: expected %v for %q\n", expect, s)
}
}
check(t1, false)
check(t2, true)
fmt.Println("2 tests run")
}
func main() {
tests()
}
- 2 回答
- 0 关注
- 176 浏览
添加回答
举报
