Swift 4:设置不同的日期和时间

时间:2017-11-13 18:40:55

标签: ios swift nsdate nscalendar nsdatecomponents

我知道如何获取当地的日期和时间,但我想要做的是从不同的地方获取日期和时间。例如,我想知道纽约的时间和日期。我该如何解决这个简单的问题?

以下是我的本地日期和时间代码:

let date = NSDate()
let calendar = Calendar.current

let components = calendar.dateComponents([.hour, .minute, .month, .year, .day, .second, .weekOfMonth], from: date as Date)

let currentDate = calendar.date(from: components) 

我在这里搜索了一下,但我找不到我想要的东西,而且我还在寻找日期图书馆。如果您知道要重定向我的任何来源或样本,我真的很感激。

3 个答案:

答案 0 :(得分:6)

如果您只想将日期格式化为字符串,请考虑改为使用DateFormatter

let date = Date()
let formatter = DateFormatter()
formatter.timeZone = TimeZone(identifier: "America/New_York")
formatter.dateStyle = .long
formatter.timeStyle = .long
formatter.string(from: date)

如果您想获取日期组件并进行处理,请使用dateComponents(in:from:)方法。

let components = Calendar.current.dateComponents(in: TimeZone(identifier: "America/New_York")!, from: date)

答案 1 :(得分:2)

如果您不知道要搜索的地点的时区,可以使用CoreLocation的CLGeocoder并搜索地址字符串。然后,您可以获得该地点的时区,并将其转换为您正在寻找的时间:

let geocoder = CLGeocoder()
geocoder.geocodeAddressString("New York, New York") { (placemarks, error) in
    guard error == nil else {
        print("Error")
        print(error!.localizedDescription)
        return
    }
    guard let placemarks = placemarks,
        let place = placemarks.first else {
        print("No results")
        return
    }

    if let timeZone = place.timeZone {
        print("TimeZone: \(timeZone.identifier)")
        // TimeZone: America/New_York

        //Ignore the time zone offset from this one, it will be the difference between the current time and the new york time
        let dateInNewYork = Date().addingTimeInterval(TimeInterval.init(timeZone.secondsFromGMT()))
        print(dateInNewYork)
        // 2017-11-13 15:03:05 +0000

        //Or
        let formatter = DateFormatter()
        formatter.timeZone = TimeZone(identifier: timeZone.identifier)
        formatter.dateStyle = .long
        formatter.timeStyle = .long
        let formattedDateInNewYork = formatter.string(from: Date())
        print(formattedDateInNewYork)
        // November 13, 2017 at 3:03:05 PM EST

        //Or
        let components = Calendar.current.dateComponents(in: TimeZone(identifier: timeZone.identifier)!, from: Date())
        print(components.date!)
        // 2017-11-13 20:03:05 +0000
    }

}

答案 2 :(得分:2)

这里涉及到几个不同的概念,我们需要了解(几乎)所有这些概念才能做到这一点......

1)一个DateNSDate原样,在Swift中)是一个绝对的时间点 - 它有点错误命名,因为它与实际日期无关像2017年11月13日,因为我们需要定义......

2)a Calendar,因为2017年11月13日西格里高利历中也可能是伊斯兰历法中的第23个Safar 1439,或希伯来历法中的Heshvan 5778的第24个,或许多其他的东西其他iOS和日历日历MacOS支持;

3)反过来Calendar不仅会更改DateComponents中我们必须用来将Date + Calendar解压缩到几天,几个月的TimeZone中返回的值,岁月时代(例如BC / AD),甚至周数等......,但某些日历可能与其他日历没有相同的组件;

4)时间(如您所知)取决于DateFormatter,因此相同的绝对时间可以是许多不同时间之一" o'时钟"取决于你在哪里。它也可能(如下面的示例所示)更改 date 以及" o' clock"。这当然可以是自动的(你在哪里)或由程序员设置;

5)此外,我们有DateComponents(这是一个包装DateFormatter的便利),因为2017年11月13日可以表示为13/11/17或11/13/17取决于您是英国人还是美国人。我们可能还希望选择使用文字或数字月份,如果显示时间,我们是否需要12小时或24小时格式 - 所有这些都包含在Locale中文本表示可能是" 13e Novembre 2017"如果你是法国人,那引入了

的概念

6)TimeZone,可以像Date一样设置为默认值(在设置设备时选择)或由程序员指定。

您发布的代码无法正常运行,因为它所做的一切都需要Calendar,通过DateComponents转换为Date(到目前为止一切都很好),但是然后从组件中重新创建Date - 您将获得的是原始Date - 绝对时间点相同。

我对这个问题的看法以及你对评论中问题的回答是你想要一个需要绝对时间的函数(例如"现在")又称TimeZone并将其显示在特定的func timeComponents(date: Date, timeZone: TimeZone) -> DateComponents { var calendar = Calendar.current calendar.timeZone = timeZone return calendar.dateComponents([.hour, .minute, .month, .year, .day, .second, .weekOfMonth], from: date) } let absTime: Date = Date() // Now let edinburgh = TimeZone(abbreviation: "GMT")! let newYork = TimeZone(abbreviation: "EST")! let ec = timeComponents(date: absTime, timeZone: edinburgh) let nycc = timeComponents(date: absTime, timeZone: newYork) print(ec)// year: 2017 month: 11 day: 14 hour: 0 minute: 44 second: 10 weekOfMonth: 3 isLeapMonth: false print(nycc) // year: 2017 month: 11 day: 13 hour: 19 minute: 44 second: 10 weekOfMonth: 3 isLeapMonth: false 。这有效:

DateComponents

...我认为回答你问题的最低限度,但要巧妙,我们需要从DateFormatter转到func timeString(date: Date, timeZone: TimeZone, timeStyle: DateFormatter.Style) -> String { let dateFormatter = DateFormatter() dateFormatter.timeZone = timeZone dateFormatter.dateStyle = .none dateFormatter.timeStyle = timeStyle return dateFormatter.string(from: date) } let es = timeString(date: absTime, timeZone: edinburgh, timeStyle: .full) let nycs = timeString(date: absTime, timeZone: newYork, timeStyle: .full) print(es) // 12:44:10 AM Greenwich Mean Time print(nycs) // 7:44:10 PM Eastern Standard Time

Locale

如果你想让你的应用程序国际化,你可以继续使用$date = date("D, j M Y H:i:s +0000", strtotime("-1 hour")); $emails = imap_search($inbox,'SINCE "'.$date.'"'); ,但我会将其留作练习!

P.S。这些所有概念 - 请参阅here

p.p.s。另请参阅this answerthis answer(不重复)