iOS:将UTC NSDate转换为本地时区

134 timezone objective-c nsdate ios swift

如何NSDate在Objective C或/和Swift中将UTC转换为本地时区NSDate?

slf*_*slf 137

NSTimeInterval seconds; // assume this exists
NSDate* ts_utc = [NSDate dateWithTimeIntervalSince1970:seconds];

NSDateFormatter* df_utc = [[[NSDateFormatter alloc] init] autorelease];
[df_utc setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[df_utc setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];

NSDateFormatter* df_local = [[[NSDateFormatter alloc] init] autorelease];
[df_local setTimeZone:[NSTimeZone timeZoneWithName:@"EST"]];
[df_local setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];

NSString* ts_utc_string = [df_utc stringFromDate:ts_utc];
NSString* ts_local_string = [df_local stringFromDate:ts_utc];

// you can also use NSDateFormatter dateFromString to go the opposite way
Run Code Online (Sandbox Code Playgroud)

格式化字符串参数表:

https://waracle.com/iphone-nsdateformatter-date-formatting-table/

如果性能优先,您可能需要考虑使用 strftime

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/strftime.3.html

  • @DaveDeLong如果您只是将日期显示为字符串,这一切都很好.但是,在某个日期进行时区转换是完全正确的理由.例如,如果要使用setDate:在UIDatePicker上默认日期.Web服务返回的日期通常是UTC,但代表用户本地时区的事件,如电视列表.在未转换的日期传递将在选择器中显示不正确的时间. (34认同)
  • @GlennMaynard我不同意.这个答案的实质是不需要转换为`NSDate`对象,这是正确的.转换为时区发生在格式化日期时,而不是在创建日期时,因为日期没有时区. (5认同)

gyo*_*dor 106

编辑当我写这篇文章时,我不知道我应该使用dateformatter,这可能是一种更好的方法,所以也请查看slf答案.

我有一个web服务,返回UTC的日期.我用toLocalTime它将它转换为本地时间并toGlobalTime在需要时转换回来.

这是我得到答案的地方:

https://agilewarrior.wordpress.com/2012/06/27/how-to-convert-nsdate-to-different-time-zones/

@implementation NSDate(Utils)

-(NSDate *) toLocalTime
{
  NSTimeZone *tz = [NSTimeZone defaultTimeZone];
  NSInteger seconds = [tz secondsFromGMTForDate: self];
  return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}

-(NSDate *) toGlobalTime
{
  NSTimeZone *tz = [NSTimeZone defaultTimeZone];
  NSInteger seconds = -[tz secondsFromGMTForDate: self];
  return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}

@end
Run Code Online (Sandbox Code Playgroud)

  • 不要这样做.NSDates始终为UTC.这只是混淆了这个问题. (25认同)
  • 这对于上面提到的"webservice"情况非常有用.假设您有一个以UTC格式存储事件的服务器,并且客户端想要询问今天发生的所有事件.为此,客户端需要获取当前日期(UTC/GMT),然后在将其发送到服务器之前将其移动时区偏移量. (13认同)
  • 很高兴注意你从哪里复制代码:https://agilewarrior.wordpress.com/2012/06/27/how-to-convert-nsdate-to-different-time-zones/ (3认同)
  • @aryaxt你是对的,对不起.老实说,我不记得我在发布答案时从哪里复制了. (2认同)

Sen*_*doa 49

我发现最简单的方法是:

NSDate *someDateInUTC = …;
NSTimeInterval timeZoneSeconds = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate *dateInLocalTimezone = [someDateInUTC dateByAddingTimeInterval:timeZoneSeconds];
Run Code Online (Sandbox Code Playgroud)

  • 很有帮助.如果你想考虑夏令时,应该使用一个额外的`secondsFromGMTForDate`.参见[苹果文档(https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSTimeZone_Class/index.html#//apple_ref/occ/instm/NSTimeZone/secondsFromGMTForDate :) (9认同)
  • 这个答案感觉更便携.下面的答案假设时区在运行时是固定的,而上面的答案从平台得到时区. (3认同)

Kru*_*nal 30

Swift 3+:UTC到本地,本地到UTC

extension Date {

    // Convert UTC (or GMT) to local time
    func toLocalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }

    // Convert local time to UTC (or GMT)
    func toGlobalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }
}
Run Code Online (Sandbox Code Playgroud)


Moh*_*shi 26

如果您想要本地日期和时间.试试这个代码: -

NSString *localDate = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
Run Code Online (Sandbox Code Playgroud)


小智 6

这里输入的是一个字符串currentUTCTime(格式为08/30/2012 11:11)将GMT中的输入时间转换为系统设置区时间

//UTC time
NSDateFormatter *utcDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[utcDateFormatter setDateFormat:@"MM/dd/yyyy HH:mm"];
[utcDateFormatter setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT: 0]];

// utc format
NSDate *dateInUTC = [utcDateFormatter dateFromString: currentUTCTime];

// offset second
NSInteger seconds = [[NSTimeZone systemTimeZone] secondsFromGMT];

// format it and send
NSDateFormatter *localDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[localDateFormatter setDateFormat:@"MM/dd/yyyy HH:mm"];
[localDateFormatter setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT: seconds]];

// formatted string
NSString *localDate = [localDateFormatter stringFromDate: dateInUTC];
return localDate;
Run Code Online (Sandbox Code Playgroud)


Vvk*_*Vvk 5

将您的UTC日期转换为本地日期

-(NSString *)getLocalDateTimeFromUTC:(NSString *)strDate
{
    NSDateFormatter *dtFormat = [[NSDateFormatter alloc] init];
    [dtFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dtFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    NSDate *aDate = [dtFormat dateFromString:strDate];

    [dtFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dtFormat setTimeZone:[NSTimeZone systemTimeZone]];

    return [dtFormat stringFromDate:aDate];
}
Run Code Online (Sandbox Code Playgroud)

使用像这样

NSString *localDate = [self getLocalDateTimeFromUTC:@"yourUTCDate"];
Run Code Online (Sandbox Code Playgroud)