【问题标题】:UIDatePicker does not respect Daylight Savings TimeUIDatePicker 不遵守夏令时
【发布时间】:2018-09-13 23:37:15
【问题描述】:

我正在尝试从UIDatePicker 获取小时和分钟值以在我的服务器中使用,但UIDatePicker 的值是一个小时。我的本地时区目前使用夏令时,所以我假设 UIDatePicker 不尊重这一点。

这是我用来将UIDatePicker 提供的日期转换为其小时和分钟值的代码:

struct MyTimeSettings {

    var time: Date!

    init(from json: [String : Any]) {
        var calendar = Calendar.current
        calendar.timeZone = TimeZone(abbreviation: "UTC")!

        self.time = calendar.date(from: DateComponents(timeZone: TimeZone(abbreviation: "UTC")!, year: 0, month: 0, day: 0, hour: (json["Hour"] as! Int), minute: (json["Minute"] as! Int)))
    }

    init() {}

    func getJSON() -> [String : Any] {
        var calendar = Calendar.current
        calendar.timeZone = TimeZone(abbreviation: "UTC")!
        let components = calendar.dateComponents(in: TimeZone(abbreviation: "UTC")!, from: self.time)

        return [
            "Hour" : components.hour!,
            "Minute" : components.minute!
        ]
    }

    static func ==(lhs: MyTimeSettings, rhs: MyTimeSettings) -> Bool {
        return (lhs.time == rhs.time)
    }
}

为了测试它,我给了它一个Date,它的计算结果是美国东部时间晚上 10:15:

var settings = MyTimeSettings()
let date = Date(timeIntervalSince1970: 1522894500)
settings.time = date

print(settings.getJSON()) // ["Hour": 2, "Minute": 15]

它也适用于输入 JSON:

let json = ["Hour": 2, "Minute": 15]
print(MyTimeSettings(from: json).getJSON()) // ["Hour": 2, "Minute": 15]

我的问题是,在从UIDatePicker 获取日期时,相同的代码不能正常工作。我正在使用Eureka 库在表格视图单元格中显示UIDatePicker

<<< TimePickerRow() { row in
    row.cell.datePicker.timeZone = TimeZone.current
    row.cell.datePicker.locale = Locale.current
    row.value = self.myTimeSettings.time
}.onChange({ (row) in
    self.myTimeSettings.time = row.value
})

然后我将日期选择器上的时间设置为晚上 10:15 (EDT),但我没有得到 2:15 AM UTC:

print(myTimeSettings.getJSON()) // ["Hour": 3, "Minute": 12]

为什么日期选择器返回错误的时间?

【问题讨论】:

  • 在深入了解可能出现的问题之前,this 是否有任何澄清或建议?
  • 如果你只是print(datePicker.date),你会得到什么?
  • @DonMag 我还是凌晨 3:12:-0001-11-30 03:12:00 +0000
  • 您获得了正确的日期/时间。 UTC 没有“夏令时”,因此(例如)在美国东部时区,10:45 PM on March 10, 20183:45 AM on March 11 UTC10:45 PM on March 11, 20182:45 AM on March 12 UTC

标签: ios swift nscalendar nsdatecomponents


【解决方案1】:

根据Apple's Documentation,您需要调用此方法:

声明

func daylightSavingTimeOffset(for date: Date = default) -&gt; TimeInterval

参数

日期

用于计算的日期。默认值为当前 日期。

【讨论】:

  • 谢谢!我能够让它工作 - 请参阅下面的答案。
【解决方案2】:

感谢Jake's answer,我能够通过将daylightSavingTimeOffset 函数添加到MyTimeSettings 来获得正确的UTC 时间:

init(from json: [String : Any]) {
    var calendar = Calendar.current
    calendar.timeZone = TimeZone(abbreviation: "UTC")!

    self.enabled = json["Enabled"] as! Bool
    self.daysToNotify = (json["Interval"] as! [String]).map { SHNotificationIntervalType(rawValue: $0)! }
    self.time = calendar.date(from: DateComponents(timeZone: TimeZone(abbreviation: "UTC")!, year: 0, month: 0, day: 0, hour: (json["Hour"] as! Int), minute: (json["Minute"] as! Int)))
    if TimeZone.current.isDaylightSavingTime() {
        let offset = TimeZone.current.daylightSavingTimeOffset()
        self.time = self.time + offset
    }
}

init() {}

func getJSON() -> [String : Any] {
    var calendar = Calendar.current
    calendar.timeZone = TimeZone(abbreviation: "UTC")!

    var components: DateComponents
    if TimeZone.current.isDaylightSavingTime() {
        let offset = TimeZone.current.daylightSavingTimeOffset()
        components = calendar.dateComponents(in: TimeZone(abbreviation: "UTC")!, from: self.time - offset)
    } else {
        components = calendar.dateComponents(in: TimeZone(abbreviation: "UTC")!, from: self.time)
    }

    return [
        "Enabled" : self.enabled!,
        "Interval" : (self.daysToNotify.map { $0.rawValue }),
        "Hour" : components.hour!,
        "Minute" : components.minute!
    ]
}

【讨论】:

  • 做得很好。如有疑问,我总是去 Apple 文档
猜你喜欢
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
  • 2015-03-04
  • 2010-12-07
  • 2015-03-11
  • 2021-03-08
相关资源
最近更新 更多