如何在 Swift 中查找给定日期的午夜

How to find midnight for a given Date in Swift

我创建了一个行程生成应用程序,要求用户输入 his/her 旅行的日期。唯一的问题是,使用 UIDatePicker,日期总是作为给定 day/month/year 的当前时间给出。

在一个单独的文件中,我扩展了日期 class 以尝试编写一个简单的方法,该方法将在给定日期 return 午夜。

第一次尝试

    var midnight:Date{
    let cal = Calendar(identifier: .gregorian)
    return cal.startOfDay(for: self)
}

然而,根据夏令时,这总是给我 04:00 或 05:00,这让我想到我应该根据夏令时简单地删除 4 或 5 小时,所以我创建了以下方法:

    var timezone:TimeZone{
    return TimeZone.current
}
///Returns the first instance of the date, e.g. 2018-02-26 00:00:00
var trueMidnight:Date{
    let cal = Calendar(identifier: .gregorian)
    let midnight = cal.startOfDay(for: self)
    let secondsFromGMT = TimeZone.current.secondsFromGMT()
    print("Daylight savings? \(daylightSavings)")
    return midnight.addingTimeInterval(Double(secondsFromGMT))
}
///If this var returns true, then daylight savings time is active and an hour of daylight is gained (during the summer).
var isDaylightSavings:Bool{
    return timezone.daylightSavingTimeOffset(for: self) == 0 ? false : true
}
var daylightSavings:Double{
    return isDaylightSavings ? 3600.0 : 0.0
}

但是这些方法有时 return 午夜,23:00,甚至 22:00 前一天。

我是一个相对缺乏经验的程序员,所以我觉得我对日期缺乏基本的了解 class 或缺少一个大概念。为什么我很难简单地找到给定日期的午夜?

我什至放弃了 return 午夜的想法,并尝试使用代码在给定的一天中找到中午:

    var noon:Date{
    let gregorian = Calendar(identifier: .gregorian)
    var components = gregorian.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)

    components.hour = 12
    components.minute = 0
    components.second = 0
    return gregorian.date(from: components)!
}

但是这个 returns 16:00 或 17:00 与中午相反。任何帮助将不胜感激。

打印日期时,以 UTC 时间打印。因此,当您打印 Date 时,它们与当地时间相差 4/5 小时。

如果你改用下面的代码

print(yourDate.description(with: .current))

yourDate 是你的日期,它会在正确的时区。

你糊涂了。

如果您使用

print(Date()) 

您将获得 UTC 日期。如果您处于 UTC+5 时区,则该日期将比您的当地时间晚 5 小时。因此,如果您尝试以 UTC 显示午夜本地时间,它将显示为 5:00 UTC 上午。

试试这个:

extension Date {
    func localString(dateStyle: DateFormatter.Style = .medium, 
      timeStyle: DateFormatter.Style = .medium) -> String {
        return DateFormatter.localizedString(
          from: self, 
          dateStyle: dateStyle, 
          timeStyle: timeStyle)
    }

    var midnight:Date{
        let cal = Calendar(identifier: .gregorian)
        return cal.startOfDay(for: self)
    }
}
print("Tonight at midnight is " + Date().midnight.localString())

该代码使用函数 localString(),该函数利用 DateFormatter 方法 localizedString(from:dateStyle:timeStyle:)Date 转换为当前区域设置(包括本地时区)中的字符串。

我建议将该扩展程序添加到您的应用程序中。