【问题标题】:Go - Unix timestamp for first day of the week from ISO year weekGo - 从 ISO 年开始一周的第一天的 Unix 时间戳
【发布时间】:2013-09-04 21:33:46
【问题描述】:

什么是获取时间戳的好方法,例如,2010 年第五周的星期一 00:00:00?本质上,我在 time 包中寻找 ISOweek 的反函数。我似乎无法找到实现这一目标的方法。 Parse() 不读取周数,简单地计算自一年/月的第一天以来有多少个“7 天”并不能真正让我得到我需要的东西。

提前非常感谢! 比尔

【问题讨论】:

  • 这里没什么简单的:1 月 4 日。总是在第 1 周。所以找到它的工作日,回到星期一并提前 7*weekno 天。但这不尊重在从/到夏令时切换期间可能发生的时区变化。您必须确定您是否跨越时区并进行相应调整。

标签: go unix-timestamp iso


【解决方案1】:

我不明白为什么

仅计算自一年/月的第一天以来已经有多少“7 天”并不能真正让我得到我需要的东西

这是我的尝试:

func firstDayOfISOWeek(year int, week int, timezone *time.Location) time.Time {
    date := time.Date(year, 0, 0, 0, 0, 0, 0, timezone)
    isoYear, isoWeek := date.ISOWeek()
    for date.Weekday() != time.Monday { // iterate back to Monday
        date = date.AddDate(0, 0, -1)
        isoYear, isoWeek = date.ISOWeek()
    }
    for isoYear < year { // iterate forward to the first day of the first week
        date = date.AddDate(0, 0, 1)
        isoYear, isoWeek = date.ISOWeek()
    }
    for isoWeek < week { // iterate forward to the first day of the given week
        date = date.AddDate(0, 0, 1)
        isoYear, isoWeek = date.ISOWeek()
    }
    return date
}

这里是健全性检查的工作示例:http://play.golang.org/p/UVFNFcpaoI

代码通俗易懂,没有年/月/日的算术,只是简单的迭代。运行时复杂度为 O(n),但考虑到 n 总是小于 400 - 这实际上根本不是问题。

如果golang date.AddDate 正确实现,它应该不会有夏令时、闰年和其他棘手的日期问题。

附:有趣的事实:) 2008 年第 1 周的第一天是 2007-12-31。没错,你可以在日历中查看。

【讨论】:

  • 我希望我不必这样做。只是看起来很不雅。但我会接受它作为正确答案,因为它有效。谢谢。
  • 如果它总是只循环一定次数,这实际上是 O(1)。
【解决方案2】:

为了这个目的,我实现了另一个简单的 Go 包:

https://github.com/snabb/isoweek

示例用法:

st := isoweek.StartTime(1985, 1, time.UTC)
fmt.Println(st)
// Output:
// 1984-12-31 00:00:00 +0000 UTC

我不喜欢接受答案中的方法,因为它会前后迭代,这很荒谬。

我也不喜欢另一个答案中的 goweek 包,因为它看起来过于复杂而且 API 很奇怪(为什么是可变参数?等等)。

【讨论】:

  • 我已经测试成功了。风格和效率的最佳选择。伟大的贡献
【解决方案3】:

无耻的自我推销,但我刚刚发布了在 Go 中工作数周的 lib:https://github.com/grsmv/goweek

【讨论】:

    【解决方案4】:
    func GetStartDayOfWeek(tm time.Time) time.Time { //get monday 00:00:00
        weekday := time.Duration(tm.Weekday())
        if weekday == 0 {
            weekday = 7
        }
        year, month, day := t.Date()
        currentZeroDay:= time.Date(year, month, day, 0, 0, 0, 0, time.Local)
        return currentZeroDay.Add(-1 * (weekday - 1) * 24 * time.Hour)
    }
    

    【讨论】:

    • 这不以周数作为输入,因此不回答问题。
    • 尽管如此,它帮助我获得了本周的开始,谢谢! :D
    猜你喜欢
    • 2021-12-23
    • 1970-01-01
    • 2010-10-24
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2016-11-29
    • 2018-07-25
    相关资源
    最近更新 更多