iOS: converti UTC NSDate in fuso orario locale

Come posso convertire un NSDate UTC nel fuso orario locale NSDate in Objective C o / e Swift?

 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 

Tabella dei parametri della stringa di formattazione:

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

Se la prestazione è una priorità, potresti prendere in considerazione l’utilizzo di strftime

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

EDIT Quando ho scritto questo non sapevo che avrei dovuto usare un dataformatter che è probabilmente un approccio migliore, quindi controlla anche la risposta di slf .

Ho un servizio web che restituisce le date in UTC. Io uso toLocalTime per convertirlo in ora locale e toGlobalTime per riconvertire se necessario.

Qui è dove ho ricevuto la mia risposta:

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 

Il metodo più semplice che ho trovato è questo:

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

Se vuoi Data e ora locale. Prova questo codice: –

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

Swift 3+ : da UTC a locale e da locale a 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) } } 

Qui l’input è una stringa currentUTCTime (nel formato 08/30/2012 11:11) converte il tempo di input in GMT nel tempo della zona impostata del sistema

 //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; 

Converti la tua data UTC in Data locale

 -(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]; } 

Usa questo

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

Converti la data dal calendario UTC in una con il NSTimeZone locale appropriato.

 //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 

Scrivo questo metodo per convertire la data e l’ora in LocalTimeZone

-Here (NSString *) Il parametro TimeZone è un fuso orario del server

 -(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; } 

Dal momento che nessuno sembrava utilizzare NSDateComponents , ho pensato di NSDateComponents uno in … In questa versione, non viene utilizzato NSDateFormatter , quindi nessun parsing di stringhe e NSDate non viene utilizzato per rappresentare il tempo al di fuori di GMT (UTC). L’originale NSDate trova nella variabile 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 potrebbe essere NSCalendarIdentifierGregorian o qualsiasi altro calendario. La NSString consentita per i_anotherTimeZone può essere acquisita con [NSTimeZone knownTimeZoneNames] , ma anotherCalendar.timeZone potrebbe essere [NSTimeZone defaultTimeZone] o [NSTimeZone localTimeZone] o [NSTimeZone systemTimeZone] tutto.

In realtà è un altro anotherComponents tiene il tempo nel nuovo fuso orario. Noterai che anotherDate è uguale a i_date , perché contiene il tempo in GMT (UTC).

Converti ora UTC in fuso orario corrente.

funzione di chiamata

 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]; 

Funzione

 -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; } 

Puoi provare questo:

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