Objective-C,如何获取UTC时区的当前date?

我在尝试:

NSDate *currentDateInLocal = [NSDate date]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"]; NSString *currentLocalDateAsStr = [dateFormatter stringFromDate:currentDateInLocal]; NSDateFormatter * dateFormatter2 = [[NSDateFormatter alloc] init]; NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; [dateFormatter2 setTimeZone:timeZone]; [dateFormatter2 setDateFormat:@"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"]; NSDate *currentDateInUTC = [dateFormatter2 dateFromString:currentLocalDateAsStr]; 

但它仍然不代表当前的UTC时间,我怎么能实现这个?

谢谢

 NSDate *currentDate = [[NSDate alloc] init]; 

现在是UTC(至less在使用下面的方法之后)
将此时间存储为UTC(自1970年参考date以来)使用

 double secsUtc1970 = [[NSDate date]timeIntervalSince1970]; 

设置date格式化程序输出本地时间:

 NSTimeZone *timeZone = [NSTimeZone defaultTimeZone]; // or Timezone with specific name like // [NSTimeZone timeZoneWithName:@"Europe/Riga"] (see link below) NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setTimeZone:timeZone]; [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"]; NSString *localDateString = [dateFormatter stringFromDate:currentDate]; 

可用的NSTimeZone名称

NSDate对象始终使用UTC作为时间参考,但date的string表示forms不一定基于UTC时区。

请注意,UTC不是(仅)时区,它是一个如何测量时间,如何协调(UTC中的C代表协调)的系统。
NSDate与UTC时间1970年1月1日午夜的参考date有关,尽pipe苹果公司稍微错误地描述了1.1.1970 GMT。

在原来的问题中,最后一个字timeZone并不完美。

你太过于复杂了

NSDate没有时区或日历。 [NSDate date]获取当前date,这是衡量历史的一个时刻。 如果我在欧洲同时运行[NSDate date] ,那么我们会得到完全相同的值。

如何打印date取决于日历和时区。 所以公历上印的date与Julian日历上印的date不同。 并且在UTC公历日历中打印的date看起来与PST公历日历中打印的date不同。 但他们仍然是相同的date。

所以你想直接跳到你的dateFormatter2

Alex Wien接受的答案是不正确的

默认情况下,NSDateFormatter将NSDate的date时间值从UTC调整到用户的本地时区。 为了防止这种调整,告诉NSDateFormatter使用UTC的时区。

要validation结果,谷歌“当前时间utc”。

我的源代码下面应该做的工作,这意味着得到当前的date时间作为一个string在由Z的UTC ( 祖鲁 )时区的ISO 8601格式的结尾。

 NSDate* datetime = [NSDate date]; NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; // Prevent adjustment to user's local time zone. [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"]; NSString* dateTimeInIsoFormatForZuluTimeZone = [dateFormatter stringFromDate:datetime]; 

你可以把这个逻辑放在你的应用程序的某个方便的方法中。

 - (NSString*)now { // Purpose: Return a string of the current date-time in UTC (Zulu) time zone in ISO 8601 format. return [self toStringFromDateTime:[NSDate date]]; } 

…和…

 - (NSString*)toStringFromDateTime:(NSDate*)datetime { // Purpose: Return a string of the specified date-time in UTC (Zulu) time zone in ISO 8601 format. // Example: 2013-10-25T06:59:43.431Z NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"]; NSString* dateTimeInIsoFormatForZuluTimeZone = [dateFormatter stringFromDate:datetime]; return dateTimeInIsoFormatForZuluTimeZone; } 

使用示例…

 NSString* now = [self now]; 

或者把这些减号变成加号,用作类方法而不是实例方法。

 NSString* now = [SomeClassNameHere now]; 

提示:为了便于人员阅读,请将格式中的T更改为SPACE。 为了更好地实现软件的互操作性,请保留T ISO 8601规范容忍一个空间,但build议保持T


提示:我没有testing,但是…有些人说实例化[NSDateFormatter][4]是昂贵的。 如果经常这样做(例如在一个循环中)考虑caching一个单一的实例重用。

请设置日历标识符!

我还不迟! 因为我看到没有人设置日历标识符 。 这对全球用户来说非常重要 。 许多用户使用非公历日历。 他们会得到错误的一年string。 特别是,当你需要将它存储到你自己的数据库。 (我们之前遇到过这个问题)

NSCalendarIdentifierGregorian
NSCalendarIdentifierBuddhist
NSCalendarIdentifierChinese
NSCalendarIdentifierHebrew
NSCalendarIdentifierIslamic
NSCalendarIdentifierIslamicCivil
NSCalendarIdentifierJapanese
NSCalendarIdentifierRepublicOfChina
NSCalendarIdentifierPersian
NSCalendarIdentifierIndian
NSCalendarIdentifierISO8601

码:

 -(NSString *)getUTCFormateDate:(NSDate *)localDate { NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; [dateFormatter setCalendar:gregorianCalendar]; [dateFormatter setTimeZone:timeZone]; [dateFormatter setLocale:locale]; [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSString *dateString = [dateFormatter stringFromDate:localDate]; return dateString; } 

[NSDatedate]是UTC。 也许你会因为在当地人看来而被愚弄? 然后它转换到你的时区。

如果你看到当地人的价值,你可以在当地时间看到它,但是如果你在控制台上打印它,你可以看到UTC。

当您在时间之后看到“+0000”时,您知道它是UTC

还有另外一种方法,就像你的Objective C项目中的C ++类一样。 (所以,制作一个.mm文件,并用public和private构build一个C ++类,并将其粘贴到公共部分(除非您需要私有)。然后,像NSString *sNowUTC = MyClass::getUTCTimestamp();

 static NSString *getUTCTimestamp(){ time_t rawtime; struct tm * timeinfo; char buffer [80]; time (&rawtime); timeinfo = gmtime (&rawtime); // make format like "2016-06-16 02:37:00" for // June 16, 2016 @ 02:37:00 UTC time strftime (buffer,80,"%F %T",timeinfo); std::string sTime(buffer); NSString *sUTC = @(sTime.c_str()); return sUTC; } 

这是我用的。

 static func makeISO8601Date(isoDateString: String) -> Date { let formatter = DateFormatter() formatter.calendar = Calendar(identifier: .iso8601) formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" return formatter.date(from: isoDateString) } 

makeISO8601Date(isoDateString: "2017-12-31T23:59:59+00:00")

Swift 3

 let utcTimestamp = Date().timeIntervalSince1970 print("timeStamp = \(utcTimestamp)")