如何在Swift上使用stride每天从StartDate到EndDate进行迭代? [英] How can I iterate day by day from an StartDate to an EndDate using strideable on Swift?

查看:110
本文介绍了如何在Swift上使用stride每天从StartDate到EndDate进行迭代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个接收以下内容的函数:

Im trying to create a function that receives:

-StartDate(DATE)。

-An StartDate (DATE).

-结束日期(DATE)。

-An EndDate (DATE).

能够日复一日地以yyyy-MM-dd格式打印日期

Capable of iterate day by day printing the day in the format yyyy-MM-dd

但是出现以下错误:

"Cannot invoke 'stride' with an argument list of type '(from: Date, to: Date, by: Int)'"

我尝试了什么?

我的约会符合可扩展协议

My dates are conforming the strideable protocol

extension Date: Strideable {
    public func distance(to other: Date) -> TimeInterval {
        return other.timeIntervalSinceReferenceDate - self.timeIntervalSinceReferenceDate
    }

    public func advanced(by n: TimeInterval) -> Date {
        return self + n
    }
}

我可以使用跨步函数

stride(from: <#T##Strideable#>, to: <#T##Strideable#>, by: <#T##Comparable & SignedNumeric#>)

在试图运行它的ViewDidLoad上

On my ViewDidLoad in trying to run it

override func viewDidLoad() {
        super.viewDidLoad()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy/MM/dd"
        let startDate = formatter.date(from: "2014/01/01")
        let endDate = formatter.date(from: "2019/03/31")
        let dayDurationInSeconds = 60*60*24

        for date in stride(from: startDate!, to: endDate!, by: dayDurationInSeconds) {
            print(date)
        }
}

我希望在控制台上看到什么?

What do I expect to see on my console?

2014-01-01
2014-01-02
2014-01-03
.........
2019-03-30
2019-03-31


推荐答案

您的代码无法编译,因为您正在跨整数,但已将 Stride 定义为 TimeInterval 。如果您修复 dayDurationInSeconds 的类型,它将满足您的大部分期望:

Your code doesn't compile because you're striding by integers, but you've defined your Stride to be TimeInterval. It would do most of what you expect if you fix the type of dayDurationInSeconds:

let dayDurationInSeconds: TimeInterval = 60*60*24

但这会给您完全错误的结果,因为并非每天都有86,400秒。 DST会根据位置的不同,每年两次更改日期长度。

But this will give you completely incorrect results, because not every day is 86,400 seconds long. DST alters the day length twice a year in location-dependent ways.

执行日期数学运算的正确方法是使用日历。如果您没有使用日历,则不能使用几秒钟内未明确显示的任何内容。

The correct way to perform date math is with Calendar. If you're not using Calendar, you can't use anything that isn't explicitly in seconds.

您可能想要的更像这样,它枚举了有关日期之间的所有午夜(UTC)。请记住,Foundation中的 Date 不是日期。这是准确的时间点。如果您确实想使用日期,那么您想要的是 DateComponents

What you may want is something more like this, which enumerates all the midnights (UTC) between the dates in question. Remember, a Date in Foundation is not a "date." It's a precise instant in time. If you really do want to work with "dates", what you want are DateComponents.

let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
let startDate = formatter.date(from: "2014/01/01")!
let endDate = formatter.date(from: "2019/03/31")!

var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(identifier: "UTC")!

calendar.enumerateDates(startingAfter: startDate,
                        matching: DateComponents(hour: 0, minute: 0, second:0),
                        matchingPolicy: .nextTime) { (date, _, stop) in
                            guard let date = date, date < endDate else {
                                stop = true
                                return
                            }

                            print(date)
}

这篇关于如何在Swift上使用stride每天从StartDate到EndDate进行迭代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆