【问题标题】:How do you deal with wall-clock times without date in Go?在 Go 中如何处理没有日期的挂钟时间?
【发布时间】:2021-09-05 21:43:52
【问题描述】:

我想知道在 Golang 中是否有任何现有的包来处理没有日期的日期时间。

问题如下。想象一下,我想存储有关公司班次的信息,包括班次的开始和结束时间,我会创建如下内容:

import "time"

type Shift struct {
    StartTime  time.Time
    FinishTime time.Time
    // More fields
}

问题是,time.Time 字段还存储有关日、月和年的信息,这可能会导致在比较班次时出现一些问题。

有没有像 Civil.Date (https://pkg.go.dev/cloud.google.com/go/civil) 这样的替代方案,但只是时间而不是日期?

【问题讨论】:

  • time.Time 有时间日期。如果您使用time.Time 并且“忽略”日期部分,那么剩下的就是时间。使用相同的日期部分,这样问题就消失了(只要确保它不是夏令时)。
  • A time.Time 是时间的一个实例。看来您想处理“时钟读数”,它不是 时间实例,而只是一个字符串。那么为什么不使用字符串呢?如果您有兴趣使用“下午 2:30”。
  • 是的,但关键是,如果您允许用户给出日期,那么 time.Time 在小于/大于比较中很容易出现错误。目标应该是有一个可比较的结构,并且用户不要给出日期以免弄乱它。
  • 如果您获得“挂钟”时间作为用户的输入,您可以将其转换为time.Duration,其中 0 表示任何一天的 00:00:00.000(因为您忽略反正天)。然后,您可以轻松比较这些持续时间。
  • 不过,比较挂钟时间并不明显。 23:00 是 01:00 前两小时还是 22 小时后?午夜和中午呢?这是一些你必须在你的上下文中决定的。我怀疑是否存在在所有情况下都可以完全满足您的需求的软件包。不过,自己实现它应该很简单。

标签: datetime go time


【解决方案1】:

为了有时间并省略有关日、月和年的其他信息,您可以使用Format() 方法。我已经创建了一个示例程序,如下所示:

package main

import (
    "fmt"
    "time"
)

func main() {

    const (
        layoutTime = "15:04:05"
    )

    fmt.Println("Date", time.Now())
    fmt.Println("Time", time.Now().Format(layoutTime))

}

输出:

Date 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
Time 23:00:00

【讨论】:

    【解决方案2】:

    这个问题有点难回答,因为除了这个,你还没有真正描述过这个类型需要做什么:

    是的,但重点是,那个 time.Time 会很容易出现小于 / 的 bug 如果您允许用户给出日期,则不仅仅是比较。目标应该是 有一个可比较的结构,并且用户不要给出日期以便不 搞砸了。

    因此,您可以使用以下内容:

    package wall
    import "errors"
    
    type Clock struct { hour, minute, second int }
    
    func NewClock(h, m, s int) (*Clock, error) {
       if h > 23 || m > 59 || s > 59 {
          return nil, errors.New("invalid input")
       }
       return &Clock{h, m, s}, nil
    }
    
    func (c Clock) Seconds() int {
       return c.hour * 60 * 60 + c.minute * 60 + c.second
    }
    
    func (c Clock) LessThan(d *Clock) bool {
       return c.Seconds() < d.Seconds()
    }
    

    例子:

    package main
    import "wall"
    
    func main() {
       c, err := wall.NewClock(9, 59, 59)
       if err != nil {
          panic(err)
       }
       d, err := wall.NewClock(10, 59, 59)
       if err != nil {
          panic(err)
       }
       println(c.LessThan(d))
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      相关资源
      最近更新 更多