NSDate与另一个NSDate在不同时区的当地时间相同

我有一个约会时间:

Friday, July 8, 2016 at 6:30:00 PM India Standard Time 

我想要一个这样的date时间:

 Friday, July 8, 2016 at 6:30:00 PM Central Daylight Time 

我不想将使用NSDateFormatter的date从一个时区转换为另一个时区,因为此转换会给我

 Friday, July 8, 2016 at 8:00:00 AM Central Daylight Time 

我想要相同的date时间,但在不同的时区。 我怎样才能做到这一点?

dasblinkenlight的答案是绝对正确的,但我会更全面地解释一下,并且在ObjC而不是Swift中显示步骤。 你不希望在不同的时区使用同一date。 你需要相同的当地时间 (或时间 ):一个人在看钟表时会看到什么。

不同地区的同一天有不同的本地时间:2016年7月8日星期五下午6:30:00印度标准时间 2016年7月8日星期五)中央夏令时间上午8:00:00。 在加尔各答的一个人看着时钟,看到下午6:30,一个在奥马哈看着她的时钟的人会看到上午8:00。

首先,仅仅为了演示的目的,我们将使用dateparsing器从您给出的string中创build原始date。 您只需从您的通知对象获取date。

 NSString * originalDateString = @"Friday, July 8, 2016 at 6:30:00 PM India Standard Time"; NSDateFormatter * parser = [NSDateFormatter new]; [parser setDateStyle:NSDateFormatterFullStyle]; [parser setTimeStyle:NSDateFormatterFullStyle]; NSDate * originalDate = [parser dateFromString:originalDateString]; 

尽pipe原始string包含时区信息, 但date不包含。 但是,墙的时间依赖于区域,所以我们需要一个时区对象来进行下一步。 你也可以从你的通知对象中得到这个。 在这里,我们只是从它的标识符创build一个: NSTimeZone * originalTZ = [NSTimeZone timeZoneWithAbbreviation:@"IST"];

我们需要NSDateComponents来表示区域中date的本地时间值。 NSCalendar负责将date分成这些组件:

 NSCalendar * cal = [NSCalendar currentCalendar]; NSDateComponents * localComps; localComps = [cal componentsInTimeZone:originalTZ fromDate:originalDate]; 

如果你现在检查localComps ,你会看到值封装你期望的墙上时间:2016-07-08 18:30:00。 现在我们已经打破了这些价值观,我们基本上可以把它们放到另一个没有翻译的地方 。 也就是说,没有重新解释价值作为一个绝对的时间,这将给2016-07-08 08:00:00,如上所述。 简单地改变时区(再次,你会从你的通知,而不是从它的缩写)的区域:

 NSTimeZone * destinationTZ = [NSTimeZone timeZoneWithAbbreviation:@"CDT"]; [localComps setTimeZone:destinationTZ]; 

现在日历可以从这些组件构造一个新的date对象。 NSDate * destinationDate = [cal dateFromComponents:localComps]; *

此date是时区无关的时间,代表2016年7月8日星期五中央夏令时间6:30:00。 与任何NSDate ,如果您只是打印出来,它将格式化为格林尼治标准时间。 如果您想要查看预期的挂钟时间值,则需要使用设置为目标时区的格式化程序。


*由于dasblinkenlight的答案显示, localComps有一个关联的日历,所以它也能够自己创build一个date。 我认为这会更清楚一些。

您可以通过将您的date分成原始时区中的组件,在组件上设置目标时区以及检索结果date(这不会是相同的date/时间)

 import Foundation let calendar = NSCalendar.currentCalendar() let date = NSDate() let origTz = NSTimeZone(abbreviation: "IST")! let destTz = NSTimeZone(abbreviation: "CDT")! let components = calendar.componentsInTimeZone(origTz, fromDate: date) components.timeZone = destTz let res = components.date! let fmt = NSDateFormatter() fmt.timeZone = destTz fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX") fmt.dateStyle = .FullStyle fmt.timeStyle = .FullStyle fmt.timeZone = origTz print(fmt.stringFromDate(date)) // Sunday, July 10, 2016 at 2:14:21 AM India Standard Time fmt.timeZone = destTz print(fmt.stringFromDate(res)) // Sunday, July 10, 2016 at 2:14:21 AM Central Daylight Time