有没有一种方法可以迭代特定的月份或周数?

14
go 中,有没有一种方式可以遍历特定的月份并获取其中所有的 time.Date 对象?
例如,遍历四月将会得到从 0401201604312016 的结果:
for _, dayInMonth := range date.April {
   // do stuff with dates returned
}

(目前上述代码显然无法工作)。

或者如果没有包含在标准库中,是否有第三方库相当于moment.js


这里有一个日期包可能对此有用:https://github.com/aodin/date - Kalnode
3个回答

33
标准库中没有定义“时间日期(Date)”对象,只有“时间(Time)”对象。也没有一种可以在range循环中使用它们的方式,但是手动循环它们相当简单:
// set the starting date (in any way you wish)
start, err := time.Parse("2006-1-2", "2016-4-1")
// handle error

// set d to starting date and keep adding 1 day to it as long as month doesn't change
for d := start; d.Month() == start.Month(); d = d.AddDate(0, 0, 1) {
    // do stuff with d
}

谢谢,这对我来说是一个好的解决方案!只需要注意for循环的第三部分应该有一个赋值给d - d = d.AddDate(0, 0, 1)。否则你会陷入无限循环。 - Shikloshi
3
接近了,但还不够。First Parse()返回两个值,所以你至少需要这样做:start, _ := time.Parse("2006-1-2", "2016-4-1"),当然,在实际情况下,通常会处理并不会丢弃错误。第二个 AddDate() 返回一个 time.Time,因此要将其用于增加 d 值的操作,应该写成 for d := start; d.Month() == start.Month(); d = d.AddDate(0, 0, 1) - Snowman
1
当然,你说得对。我应该更加小心。无论如何,我已经编辑了答案,现在它可以正常工作了。 - jussius
@jussius,我有一个开始日期和结束日期,想要找到它们之间的唯一星期一,你能帮我吗?如果可以,请看一下这个问题 - gourav

0

@jessius 的方法只适用于迭代在一个月内的情况。 更好的迭代方式是使用时间的纪元格式。

例如,对于 oneDay,我们知道它是 86400 秒。 我们可以这样做:

oneDay := int64(86400) // a day in seconds.
startDate := int64(1519862400)
endDate := int64(1520640000)

for timestamp := startDate; timestamp <= endDate; timestamp += oneDay {
   // do your work
}

对于迭代天数来说,这是一个简单且可行的方法。

但对于月份来说,这种方法行不通,因为每个月的天数都不同。我只有与@jussius类似的想法,但进行了调整以适用于月份迭代。


endDate 可以是大于 timestamp += oneDay 的最后一个添加时间,因此会跳过最后一天。 - Lorenzo Belli
@LorenzoBelli 是的,需要注意endDate,可能需要先处理一下以确保最后一天不被跳过。 - Huang Qi Victor

-1

我很想比较日期

func LeqDates(a, b time.Time) bool {
    year1, month1, day1 := a.Date()
    year2, month2, day2 := b.Date()

    if year1 < year2 {
        return true
    } else if year1 <= year2 && month1 < month2 {
        return true
    } else {
        return year1 <= year2 && month1 <= month2 && day1 <= day2
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接