ios 如何使用Swift上的strideable每天从StartDate迭代到EndDate?

eoxn13cs  于 2023-02-10  发布在  iOS
关注(0)|答案(2)|浏览(106)

我试图创建一个函数来接收:

  • 开始日期(DATE)。
  • 结束日期(DATE)。
    能够以yyyy-MM-dd格式逐日重复打印日期
    但我得到了以下错误:
"Cannot invoke 'stride' with an argument list of type '(from: Date, to: Date, by: Int)'"

我试过什么?
我的约会对象符合跨跃协议

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函数

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

在我的ViewDidLoad上尝试运行它

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)
        }
}

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

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

aor9mmx11#

代码无法编译,因为你使用的是整数,但是你已经将Stride定义为TimeInterval,如果你修改dayDurationInSeconds的类型,它可以完成你所期望的大部分事情:

let dayDurationInSeconds: TimeInterval = 60*60*24

但是这会给予你一个完全错误的结果,因为不是每一天都是86,400秒长的。DST以依赖于位置的方式每年改变两次日长。
执行日期计算的正确方法是使用Calendar,如果不使用Calendar,则不能使用任何不明确以秒为单位的值。
您可能需要的是类似于下面的内容,它列举了所讨论的日期之间的所有午夜(UTC)。请记住,在Foundation中Date不是“日期”。它是时间上的精确瞬间。如果您确实想使用“日期”,那么您需要的是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)
}
dtcbnfnu

dtcbnfnu2#

截至2023年,DateFoundation with Stride = TimeInterval的右Stridable

let now = Date()
let dayAfterNow = Date().addingTimeInterval(86400)
// You can stride it to an array
let dateArr : [Date] = Array(stride(from: now, to: dayAfterNow, by: 60))
// ... or use striding for a loop directly
for date in stride(from: now, to: dayAfterNow, by: 3600) {
    print(date)
}

但是正如@Rob所说,要小心这种日期处理,因为not all days have same number of seconds。而且这不是日期的唯一问题。

相关问题