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)")