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

时间:2018-03-11 00:16:56

标签: swift date nsdate

我创建了一个行程生成应用程序,用户需要输入他/她旅行的日期。唯一的问题是,使用UIDatePicker,日期总是作为给定日/月/年的当前时间给出。

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

首先我试过

    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
}

然而,这些方法有时会在前一天的午夜,23:00或甚至22:00返回。

我是一个相对缺乏经验的程序员,所以我觉得我对日期课程缺乏基本的理解,或者缺少一个大概念。为什么我在特定日期找到午夜这么困难?

我甚至放弃了返回午夜的想法,并尝试在某一天找到中午的代码:

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

但是这比中午返回16:00或17:00。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

你很困惑。

如果您使用

print(Date()) 

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

试试这个:

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转换为当前语言环境中的字符串(包括本地时区。

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

答案 1 :(得分:2)

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

如果您使用以下代码

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

yourDate是您的日期,它将在正确的时区。