如何在Go中优雅地迭代日期范围

时间:2018-06-22 07:09:26

标签: go

我需要迭代任何指定的日期范围,例如2017-12-21至2018-01-05。在Go中实现该功能的最佳方法是什么?

output:
20171221
20171222
20171223
...
20180104
20180105

2 个答案:

答案 0 :(得分:4)

  

The Go Programming Language Specification

     

Function literals

     

函数文字代表一个匿名函数。

FunctionLit = "func" Signature FunctionBody .

func(a, b int, z float64) bool { return a*b < int(z) }
     

可以将函数文字分配给变量或直接调用。

f := func(x, y int) int { return x + y }
func(ch chan int) { ch <- ACK }(replyChan)
     

函数文字是闭包:它们可以引用在中定义的变量   周围的功能。然后,这些变量将在   周围的函数和函数文字,它们作为   只要它们可以访问。


在Go中,封装函数的复杂性。使用函数文字作为闭包。

例如,

package main

import (
    "fmt"
    "time"
)

// rangeDate returns a date range function over start date to end date inclusive.
// After the end of the range, the range function returns a zero date,
// date.IsZero() is true.
func rangeDate(start, end time.Time) func() time.Time {
    y, m, d := start.Date()
    start = time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
    y, m, d = end.Date()
    end = time.Date(y, m, d, 0, 0, 0, 0, time.UTC)

    return func() time.Time {
        if start.After(end) {
            return time.Time{}
        }
        date := start
        start = start.AddDate(0, 0, 1)
        return date
    }
}

func main() {
    start := time.Now()
    end := start.AddDate(0, 0, 6)
    fmt.Println(start.Format("2006-01-02"), "-", end.Format("2006-01-02"))

    for rd := rangeDate(start, end); ; {
        date := rd()
        if date.IsZero() {
            break
        }
        fmt.Println(date.Format("2006-01-02"))
    }
}

游乐场:https://play.golang.org/p/wmfQC9fEs1S

输出:

2018-06-22 - 2018-06-28
2018-06-22
2018-06-23
2018-06-24
2018-06-25
2018-06-26
2018-06-27
2018-06-28

答案 1 :(得分:1)

start := time.Now()
end := start.AddDate(0, 1, 0)
for d := start; d.After(end) == false; d = d.AddDate(0, 0, 1) {
    fmt.Println(d.Format("2006-01-02"))
}

开始比赛:https://play.golang.org/p/cFcaf-yfo0n