如何在iOS中使用时区保存datetime?

如何在iOS中使用时区保存datetime?,ios,swift,nsdate,swift4,Ios,Swift,Nsdate,Swift4,我是iOS开发的新手,作为一名Android开发人员,我习惯于使用Joda Time library中的一个对象来保存一个带有给定时区的datetime 在阅读了有关日期和时间的iOS文档后,我仍然怀疑应该使用哪个类来保存日期时间。给定Date/NSDate类描述一个特定的时间点,独立于任何日历或时区。它看起来非常无用,因为它是独立于时区的,没有时区的时间没有任何意义,因为它没有任何上下文 我真正的问题;博士: 我有一个数据库,其中日期时间存储在UTC中,如yyyy-MM-dd hh:MM:ss

我是iOS开发的新手,作为一名Android开发人员,我习惯于使用Joda Time library中的一个对象来保存一个带有给定时区的datetime

在阅读了有关日期和时间的iOS文档后,我仍然怀疑应该使用哪个类来保存日期时间。给定Date/NSDate类描述一个特定的时间点,独立于任何日历或时区。它看起来非常无用,因为它是独立于时区的,没有时区的时间没有任何意义,因为它没有任何上下文

我真正的问题;博士:

我有一个数据库,其中日期时间存储在UTC中,如yyyy-MM-dd hh:MM:ss。我想使用某种DateFormatter字符串初始化一个对象,该字符串的格式为yyyy-MM-dd hh:MM:ss加上时区UTC,以便轻松转换为我希望在用户的默认时区时间向其显示的任何时区。如何在iOS中实现这一点

编辑:假设我有一个带有标题和开始时间的课堂活动。标题是一个字符串,开始时间应该是多少?

您可以使用

let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale设置用户的当前区域设置,formatter.dateFormat设置所需的日期格式。在您的情况下,yyyy-MM-dd HH:MM:ss

简单地说:

let utcDateFromServer = "2017-01-01 22:10:10"
let date = formatter.date(from: utcDateFromServer)
日期是一个时间点,如其他注释和文档中所述

如果要将UTC时间转换为本地时间,首先需要使用DateFormatter将数据库中的字符串yyyy MM dd hh:MM:ss转换为日期

然后使用带有相应时区的DateFormatter将日期转换回字符串

输出:2017-12-31 17:00:00


您可以将输入和输出时区更改为相反的方式。

我认为dateformatter至少不能解决模型部分的问题。我可能不是很清楚。假设我有一个带有标题和开始时间的课堂活动。标题是一个字符串,开始时间应该是什么?我几乎可以肯定它不是dateformatter?@Exprove,签出更新的帖子。它更详细地描述了你想做什么。你说的时间没有时区没有任何意义。那是完全错误的。这当然有道理。日期是一个时间点。如果我现在说,这个时间点对世界上的每个人来说都是一样的。时区是不相关的,直到有人想知道“现在”在我的时区是什么时候?。然后您只需将该日期格式化为具有给定时区的字符串。@rmaddy我可能不同意您的意见。想象一下,这次有人给了你注释1970-12-12 11:40:30。你不知道什么时候开始的,这是不确定的。您所描述的是事件后经过的秒数,这对于所有上下文都是相同的。你必须给出一些起点,这就是时区的作用。但是字符串1970-12-12 11:40:30不是日期。这是一根绳子。您将根据特定时区将该字符串转换为日期。一旦你有了日期,你就可以储存它。稍后检索它,您可以将该日期再次转换为任意时区的字符串。这就是重点。日期对象没有特定的时区,也不需要特定的时区。@Exprove否,不要将日期视为UTC。这不是任何时区。这只是一个时间点。句点。@LeoDabus日期在内部表示为自某个历元起的时间间隔,这一事实绝不意味着日期可以被认为是UTC时间。在将原始字符串转换为日期时,很可能不希望将格式化程序的时区设置为GMT。您很可能想要用户的时区,因为它很可能是您正在解析的本地时间。@rmaddy我编辑了答案以提供更多信息。我的意思是,当原始日期字符串是UTC时,提问者可能希望将UTC/GMT日期从数据库转换为本地日期timezone@LWJ假设我有一个带有标题和开始时间的课堂活动。标题是一个字符串,开始时间应该是多少?@Exprove您应该使用日期作为开始时间。只有在向最终用户显示日期时,才可以使用DateFormatter将日期转换为字符串
let dateStringUTC = "2018-01-01 00:00:00"

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
//Set the input timezone (if you don't set anything, the default is user's local time)
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date : Date = dateFormatter.date(from: dateStringUTC)! 
let outputDateFormatter = DateFormatter()
outputDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
//Set the output timezone (if you don't set anything, the default is user's local time)
//outputDateFormatter.timeZone = someTimeZone
let dateString = outputDateFormatter.string(from: date)

print(dateString)