【问题标题】:Swift: Compare date by daysSwift:按天比较日期
【发布时间】:2017-03-30 17:03:37
【问题描述】:

我尝试比较两天忽略时间。所以我用

calendar.compare(date1, to: date2, toGranularity: .day)

但是在将字符串日期转换为 Date 类型时,它会转换为 UTC。所以它会从 1.1.2016 0:05 到 31.12.2015 11:05 pm。当按天比较时,这仅包括剩余的小时。转换前是 24 小时。有什么想法可以毫不费力地处理这个问题吗?

另外: 代码:

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm"
var date1 : Date = dateFormatter.date(from:  "01-01-2016 00:05")!
var date2 = dateFormatter.date(from:  "01-01-2016 03:30")

if let dateFromString = dateFormatter.date(from:  "01-01-2016 00:05") {
    print(dateFromString)
    dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
    let stringFromDate = dateFormatter.string(from: dateFromString)
}


Calendar.current.compare(date1, to: date2!, toGranularity: .day) == .orderedSame

【问题讨论】:

  • 以上代码根据日历比较给定日期是同一天还是不同天。请展示一个包含预期输出和实际输出的独立可重复示例。
  • 我添加了代码并变得更加困惑。我必须先做一些测试! :-)
  • 您对实际问题不是很清楚。是它转换为导致问题的 UTC 格式的问题,还是转换时您丢失了小时信息,或者转换后它不再是 24 小时格式?尝试重写并清楚您遇到的问题,这将使您能够更快地得到答案。

标签: swift date compare utc


【解决方案1】:

详情

  • Xcode 11.5 (11E608c)、Swift 5.1

想法

基于使用dateComponents(_:from:to:)函数

解决方案

import Foundation

extension Date {

    func fullDistance(from date: Date, resultIn component: Calendar.Component, calendar: Calendar = .current) -> Int? {
        calendar.dateComponents([component], from: self, to: date).value(for: component)
    }

    func distance(from date: Date, only component: Calendar.Component, calendar: Calendar = .current) -> Int {
        let days1 = calendar.component(component, from: self)
        let days2 = calendar.component(component, from: date)
        return days1 - days2
    }

    func hasSame(_ component: Calendar.Component, as date: Date) -> Bool {
        distance(from: date, only: component) == 0
    }
}

完整样本

别忘了把解决方案代码放在这里(看上面)

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm:ss"
//dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let smallerDate = dateFormatter.date(from: "01-01-2012 00:05:01")!
let biggerDate  = dateFormatter.date(from: "03-12-2019 09:30:01")!

print(smallerDate.fullDistance(from: biggerDate, resultIn: .day))       // Optional(2893)
print(biggerDate.fullDistance(from: smallerDate, resultIn: .day))       // Optional(-2893)
print(smallerDate.fullDistance(from: biggerDate, resultIn: .year))      // Optional(7)
print(biggerDate.fullDistance(from: smallerDate, resultIn: .year))      // Optional(7)
print(smallerDate.fullDistance(from: biggerDate, resultIn: .hour))      // Optional(69441)
print(biggerDate.fullDistance(from: smallerDate, resultIn: .hour))      // Optional(-69441)

print(smallerDate.distance(from: biggerDate, only: .day))               // -2
print(biggerDate.distance(from: smallerDate, only: .day))               // 2
print(smallerDate.distance(from: biggerDate, only: .year))              // -7
print(biggerDate.distance(from: smallerDate, only: .year))              // 7
print(smallerDate.distance(from: biggerDate, only: .hour))              // -9
print(biggerDate.distance(from: smallerDate, only: .hour))              // 9

print(smallerDate.hasSame(.day, as: biggerDate))                        // false
print(biggerDate.hasSame(.second, as: smallerDate))                     // true

【讨论】:

  • 请注意,dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) 会根据设备的 GMT 更改日期,这可能会导致不同的日子。
  • @RodolfoAntonici,正确,因为我想比较“干净”的日期和相同的时区
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
相关资源
最近更新 更多