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

jor*_*rjj 5 nsdate nscalendar nsdatecomponents ios swift

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

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

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) 
Run Code Online (Sandbox Code Playgroud)

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

Swe*_*per 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)
Run Code Online (Sandbox Code Playgroud)

如果要获取日期组件并处理它们,请使用该dateComponents(in:from:)方法.

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


Gri*_*mxn 5

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

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

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

3) 反过来,Calendar不仅改变返回的值DateComponents,我们必须使用将Date+解包Calendar为天、月、年和纪元(例如 BC/AD),甚至周数等......,而且还有一些日历可能没有与其他日历相同的组件

4)一天中的时间(如您所知)取决于TimeZone,因此根据您所在的位置,相同的绝对时间可以是许多不同时间“o'clock”之一。它也可能(如您在下面的示例中所见)更改日期以及“o'clock”。这当然可以是自动的(您所在的位置)或由程序员设置;

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

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

您发布将无法正常工作的代码,因为它是所有需要Date,变换它通过CalendarDateComponents(到目前为止都好),但随后再现了Date从组件-所有你得到的是原来的Date-相同的绝对点时间。

我从问题和您对评论中问题的回答中相信的是,您需要一个需要绝对时间(例如“现在”)又名 a 的函数,并将其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 
Run Code Online (Sandbox Code Playgroud)

...我认为这回答了您的问题的最低限度,但要巧妙地解决它,我们需要从DateComponentsDateFormatter

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
Run Code Online (Sandbox Code Playgroud)

Locale如果您想将您的应用程序国际化,您可以继续并开始使用,但我将把它留作练习!

ps 这些不是所有的概念 - 见这里

pps 另请参阅此答案此答案(均不重复)