iOS:UTC NSDateをローカルタイムゾーンに変換する


138

NSDateObjective CまたはSwiftでUTC をローカルタイムゾーンNSDate に変換するにはどうすればよいですか?


14
日付には確かにタイムゾーンがあります。
Glenn Maynard

1
それが役立つ場合は、温度を考えてください。それらは華氏、摂氏、またはケルビンで表すことができます。しかし、表現されている情報(分子の平均的な動き)には固有の単位はありませんが、ある単位で表現された場合にのみ意味があります。
ソフトウェアは

7
@DaveDeLong NSDateにはタイムゾーンがあります。NSDateクラス参照から:「このメソッドは、絶対参照日付(2001年1月1日の最初の瞬間、GMT)に関連する時刻値を返します。」GMTへの明確で具体的な参照に注意してください。
Murray Sagal

3
同意しません。NSDateにはタイムゾーンがありません。NSDateのタイムゾーンを指定するには、NSCalendarオブジェクトまたはNSDateFormatterオブジェクトを使用します。タイムゾーンが指定されていない文字列からNSDateを作成すると、NSDateは文字列がGMT時間であると想定します。
Rickster 2013

1
@MurraySagal 1つの特定のメソッドが特定のタイムゾーンの日付に関連する時刻値を返すからといって、NSDateがタイムゾーンに関連するものとして日付をモデル化しているわけではありません。
eremzeit 2014年

回答:


139
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

フォーマット文字列パラメーターの表:

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

パフォーマンスを優先する場合は、使用を検討することができます strftime

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


おそらく言及する価値があります。フォーマッタを使用して文字列から日付を読み取ることもできます
slf

34
@DaveDeLongは、日付を文字列として表示しているだけの場合は問題ありません。ただし、日付にタイムゾーン変換を行うのには完全に正当な理由があります。たとえば、setDate:を使用してUIDatePickerの日付をデフォルトにしたい場合。多くの場合、Webサービスによって返される日付はUTCですが、テレビのリストなど、ユーザーのローカルタイムゾーンのイベントを表します。変換されていない日付を渡すと、ピッカーに誤った時間が表示されます。
Christopher Pickslay

5
@GlennMaynard同意しない。この回答の本質は、NSDateオブジェクトへの変換が不要であることです。これは正しいことです。日付にはタイムゾーンがないため、タイムゾーンへの変換は、日付の作成時ではなくフォーマット時に行われます。
Dave DeLong 2012

1
@GlennMaynard ...それ以外NSCalendarDateは非推奨です。
Dave DeLong 2012

1
また、これに注意してください:oleb.net/blog/2011/11/… "GMT!= UTC"と書かれています
huggie

106

編集私がこれを書いたとき、私はおそらくより良いアプローチであるdateformatterを使うべきだと知りませんでしたので、slfの答えもチェックしてください。

UTCで日付を返すWebサービスがあります。私は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

25
これを行わないでください。NSDateは常にUTCです。これは問題を混乱させるだけです。
JeremyP 2012

13
これは、上記の「webservice」の場合に非常に役立ちます。イベントをUTCで保存するサーバーがあり、クライアントが今日発生したすべてのイベントを要求したいとします。これを行うには、クライアントは現在の日付(UTC / GMT)を取得し、サーバーに送信する前にタイムゾーンオフセットでシフトする必要があります。
Taylor Lafrinere、2012年

@JeremyP NSDatesは常にGMTであると言う方が正確です。NSDateクラス参照から:「このメソッドは、絶対参照日付(2001年1月1日の最初の瞬間、GMT)に関連する時刻値を返します。」GMTへの明確で具体的な参照に注意してください。GMTとUTCの間には技術的な違いがありますが、ほとんどの場合、ほとんどの人が求めているソリューションとは無関係です。
Murray Sagal

3
:あなたがからコードをコピーノートにいいだろうagilewarrior.wordpress.com/2012/06/27/...を
aryaxt

2
@aryaxtあなたは正しい、ごめんなさい。正直、回答を投稿したときのコピー元は覚えていませんでした。
gyozo kudor 2015年

49

私が見つけた最も簡単な方法はこれです:

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

3
この答えは、よりポータブルに感じられます。以下の答えはタイムゾーンが実行時に固定されていることを前提としていますが、上記の答えはプラットフォームからタイムゾーンを導き出します。
bleeckerj 14

9
非常に役立ちます。さらに、secondsFromGMTForDate夏時間を考慮したい場合に使用してください。Apple Docsを
セルゲイマルケロフ2014

1
これは、DSTの変更を考慮に入れていません。
lkraider 2016年

36

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

タイムゾーンをUTCに、またはその逆に変換しますか?
Mitesh

26

ローカルの日付と時刻が必要な場合。このコードを試してください:-

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

正解です。これにより、現在の日付が取得されます。日付文字列を使用するこれの適応は、で置き換える[NSDate date]こと[NSDate dateWithNaturalLanguageString:sMyDateString]です。
Volomike、2016年

7

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

このように使う

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

1
私には
うまくいき

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;

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


2

このメソッドを作成して、日付時刻をLocalTimeZoneに変換します

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

1

誰もを使用していないようだったのでNSDateComponents、私は1つにピッチングすると思いました...このバージョンでは、NSDateFormatterは使用されていないため、文字列の解析NSDateは行われず、GMT(UTC)外の時間を表すために使用されていません。オリジナル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_anotherCalendarNSCalendarIdentifierGregorianまたはその他のカレンダーである可能性があります。NSString許可i_anotherTimeZoneを取得することができ[NSTimeZone knownTimeZoneNames]ますが、anotherCalendar.timeZone可能性[NSTimeZone defaultTimeZone]または[NSTimeZone localTimeZone]または[NSTimeZone systemTimeZone]完全に。

実際にはanotherComponents、新しいタイムゾーンで時刻を保持しています。はGMT(UTC)で時刻を保持しているため、にanotherDate等しいことがわかりますi_date


0

あなたはこれを試すことができます:

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

-1

UTC時間を現在のタイムゾーンに変換します。

関数を呼び出す

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

関数

-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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.