简体   繁体   English

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

[英]iOS: Convert UTC NSDate to local Timezone

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

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

Table of formatting string parameters:格式化字符串参数表:

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

If performance is a priority, you may want to consider using strftime如果优先考虑性能,您可能需要考虑使用strftime

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

EDIT When i wrote this I didn't know I should use a dateformatter which is probably a better approach, so check out slf 's answer too.编辑当我写这篇文章时,我不知道我应该使用 dateformatter 这可能是一种更好的方法,所以也请查看slf的答案。

I have a webservice that returns dates in UTC.我有一个以 UTC 返回日期的网络服务。 I use toLocalTime to convert it to local time and toGlobalTime to convert back if needed.我用toLocalTime将其转换为本地时间和toGlobalTime到如果需要转换回。

This is where I got my answer from:这是我从这里得到答案的地方:

https://agilewarrior.wordpress.com/2012/06/27/how-to-convert-nsdate-to-different-time-zones/ 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

The easiest method I've found is this:我发现的最简单的方法是这样的:

NSDate *someDateInUTC = …;
NSTimeInterval timeZoneSeconds = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate *dateInLocalTimezone = [someDateInUTC dateByAddingTimeInterval:timeZoneSeconds];

Swift 3+ : UTC to Local and Local to UTC 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)
    }
}

If you want local Date and time.如果您想要本地日期和时间。 Try this code:-试试这个代码:-

NSString *localDate = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];

Convert your UTC date to Local Date将您的 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];
}

Use Like This像这样使用

NSString *localDate = [self getLocalDateTimeFromUTC:@"yourUTCDate"];

Here input is a string currentUTCTime (in format 08/30/2012 11:11) converts input time in GMT to system set zone time这里输入的是一个字符串 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;
//This is basic way to get time of any GMT time.

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"hh:mm a"];  // 09:30 AM
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:1]]; // For GMT+1
NSString *time = [formatter stringFromDate:[NSDate date]];  // Current time

将日期从 UTC 日历转换为具有适当本地NSTimeZone 的日期

I write this Method to convert date time to our LocalTimeZone我编写此方法将日期时间转换为我们的 LocalTimeZone

-Here (NSString *)TimeZone parameter is a server timezone - 这里 (NSString *)TimeZone 参数是服务器时区

-(NSString *)convertTimeIntoLocal:(NSString *)defaultTime :(NSString *)TimeZone
{
    NSDateFormatter *serverFormatter = [[NSDateFormatter alloc] init];
    [serverFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:TimeZone]];
    [serverFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *theDate = [serverFormatter dateFromString:defaultTime];
    NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
    [userFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [userFormatter setTimeZone:[NSTimeZone localTimeZone]];
    NSString *dateConverted = [userFormatter stringFromDate:theDate];
    return dateConverted;
}

Since no one seemed to be using NSDateComponents , I thought I would pitch one in... In this version, no NSDateFormatter is used, hence no string parsing, and NSDate is not used to represent time outside of GMT (UTC).由于似乎没有人使用NSDateComponents ,我想我会NSDateComponents一分... 在这个版本中,没有使用NSDateFormatter ,因此没有字符串解析,并且NSDate不用于表示 GMT (UTC) 之外的时间。 The original NSDate is in the variable i_date .原始NSDate位于变量i_date

NSCalendar *anotherCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:i_anotherCalendar];
anotherCalendar.timeZone = [NSTimeZone timeZoneWithName:i_anotherTimeZone];

NSDateComponents *anotherComponents = [anotherCalendar components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitNanosecond) fromDate:i_date];

// The following is just for checking   
anotherComponents.calendar = anotherCalendar; // anotherComponents.date is nil without this
NSDate *anotherDate = anotherComponents.date;

i_anotherCalendar could be NSCalendarIdentifierGregorian or any other calendar. i_anotherCalendar可以是NSCalendarIdentifierGregorian或任何其他日历。 The NSString allowed for i_anotherTimeZone can be acquired with [NSTimeZone knownTimeZoneNames] , but anotherCalendar.timeZone could be [NSTimeZone defaultTimeZone] or [NSTimeZone localTimeZone] or [NSTimeZone systemTimeZone] altogether. i_anotherTimeZone允许的NSString可以通过[NSTimeZone knownTimeZoneNames]获取,但anotherCalendar.timeZone可以是[NSTimeZone defaultTimeZone][NSTimeZone localTimeZone][NSTimeZone systemTimeZone]

It is actually anotherComponents holding the time in the new time zone.它实际上是在新时区中保存时间的anotherComponents You'll notice anotherDate is equal to i_date , because it holds time in GMT (UTC).您会注意到anotherDate等于i_date ,因为它以格林威治标准时间 (UTC) 保存时间。

You can try this one:你可以试试这个:

NSDate *currentDate = [[NSDate alloc] init];
NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:@"ZZZ"];
NSString *localDateString = [dateFormatter stringFromDate:currentDate];
NSMutableString *mu = [NSMutableString stringWithString:localDateString];
[mu insertString:@":" atIndex:3];
 NSString *strTimeZone = [NSString stringWithFormat:@"(GMT%@)%@",mu,timeZone.name];
 NSLog(@"%@",strTimeZone);

Please use this code.请使用此代码。

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; 
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSDate *date = [dateFormatter dateFromString:@"2015-04-01T11:42:00"]; // create date from string

[dateFormatter setDateFormat:@"EEE, MMM d, yyyy - h:mm a"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *timestamp = [dateFormatter stringFromDate:date];

Solution for SwiftDate library: SwiftDate库的解决方案:

// Take date by seconds in UTC time zone
var viewModelDate: Date = DateInRegion(seconds: Double(backendModel.scheduledTimestamp)).date 

...

// Convert date to local timezone and convert to string by format rule.
label.text = viewModelDate.convertTo(region: .current).toFormat(" EEE MM/dd j:mm") 

Convert UTC time to current time zone.将 UTC 时间转换为当前时区。

call function调用函数

NSLocale *locale = [NSLocale autoupdatingCurrentLocale];

NSString *myLanguageCode = [locale objectForKey: NSLocaleLanguageCode];
NSString *myCountryCode = [locale objectForKey: NSLocaleCountryCode];

NSString *rfc3339DateTimeString = @"2015-02-15 00:00:00"];
NSDate *myDateTime = (NSDate*)[_myCommonFunctions _ConvertUTCTimeToLocalTimeWithFormat:rfc3339DateTimeString LanguageCode:myLanguageCode CountryCode:myCountryCode Formated:NO];

Function功能

-NSObject*)_ConvertUTCTimeToLocalTimeWithFormat:rfc3339DateTimeString     LanguageCode:(NSString *)lgc CountryCode:(NSString *)ctc Formated:(BOOL) formated
{
    NSDateFormatter *sUserVisibleDateFormatter = nil;
    NSDateFormatter *sRFC3339DateFormatter = nil;

    NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];

    if (sRFC3339DateFormatter == nil)
    {
        sRFC3339DateFormatter = [[NSDateFormatter alloc] init];

        NSLocale *myPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:[NSString stringWithFormat:@"%@", timeZone]];

        [sRFC3339DateFormatter setLocale:myPOSIXLocale];
        [sRFC3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
        [sRFC3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    }

    // Convert the RFC 3339 date time string to an NSDate.
    NSDate *date = [sRFC3339DateFormatter dateFromString:rfc3339DateTimeString];

    if (formated == YES)
    {
        NSString *userVisibleDateTimeString;

        if (date != nil)
        {
            if (sUserVisibleDateFormatter == nil)
            {
                sUserVisibleDateFormatter = [[NSDateFormatter alloc] init];
                [sUserVisibleDateFormatter setDateStyle:NSDateFormatterMediumStyle];
                [sUserVisibleDateFormatter setTimeStyle:NSDateFormatterShortStyle];
            }

            // Convert the date object to a user-visible date string.
            userVisibleDateTimeString = [sUserVisibleDateFormatter stringFromDate:date];

            return (NSObject*)userVisibleDateTimeString;
        }
    }

    return (NSObject*)date;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM