web-dev-qa-db-ja.com

NSDate-日付をGMTに変換

NSDate値をGMT日付に変換する機能が必要です。

IPhoneデバイスが使用している日付ロケール設定に関係なく、NSDate値をGMT形式のNSDate値に変換するにはどうすればよいですか?

50
Mick
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm";

    NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    [dateFormatter setTimeZone:gmt];
    NSString *timeStamp = [dateFormatter stringFromDate:[NSDate date]];
    [dateFormatter release];
132
Howard

Cocoaで時間を操作するのは複雑です。 NSDateオブジェクトを取得すると、ローカルタイムゾーンになります。 [[NSTimeZone defaultTimeZone] secondsFromGMT]は、GMTからの現在のタイムゾーンのオフセットを提供します。次に、これを行うことができます:

NSDate *localDate = // get the date
NSTimeInterval timeZoneOffset = [[NSTimeZone defaultTimeZone] secondsFromGMT]; // You could also use the systemTimeZone method
NSTimeInterval gmtTimeInterval = [localDate timeIntervalSinceReferenceDate] - timeZoneOffset;
NSDate *gmtDate = [NSDate dateWithTimeIntervalSinceReferenceDate:gmtTimeInterval];

これで、gmtDateのGMTの日付が正しいはずです。それを表示するには、NSDateFormatter、特にsetDateStyleおよびsetTimeStyleメソッドを見てください。 NSDateFormatterを作成し、希望する方法で構成してから、stringFromDate:を呼び出して、適切にフォーマットされた文字列を取得します。

42
Alex

ハワードの答え は正しいので、投票して受け入れてください。

参考までに、日付オブジェクトとローカライズされた日付表現の違いを説明すると役立つと思います。

多くのプログラミング言語では、日付オブジェクトを使用して、特定の時点を表します。 相対論的 引数を無視すると、どのような場合でも、時間を測定する方法に関係なく、すべての人に普遍的に等しい時点を定義できると仮定できます。

各時点で一意のラベルを作成できる場合、そのラベルは明確に渡され、参照されます。 日付オブジェクトの目的は、特定の時点の一意のユニバーサルラベルとして機能することです。

そのようなラベル付けスキームを構築するための任意の数の手法を思い付くことができ、各日付オブジェクトがそれを選択する方法は、それらを使用する誰にとっても重要ではありません。

例としては、ユニバーサルイベントからの数値オフセットを使用する場合があります(Sunが爆発してからX秒)。

タイムゾーン、ロケールなどの複雑さを処理する必要があるのは、ある時点を取得して人間が読み取れる文字列にシリアル化する場合のみです。

ローカル日付文字列)+(日付フォーマッタ)=>時点

時刻+(日付フォーマッター)=>(ローカル日付文字列

すべての時点は普遍的です...ニューヨークの時点、またはgmt時間のようなものはありませんpoint。タイムポイントをローカル文字列に変換すると(日付フォーマッタを使用)、タイムゾーンへの関連付けが表示されます。

注:このまさに問題に関する多くのブログ/記事があるはずですが、私のgoogle fooはこの時間に私を失敗させます。誰かがこの問題を拡大したいという熱意を持っているなら、遠慮なくそうしてください。

16
Akusete

Alexの答えは良いスタートでしたが、DST(夏時間)を扱っておらず、基準日との不必要な変換を追加しました。次は私のために働く:

DSTを考慮してlocalDateからGMTに変換するには:

NSDate *localDate = <<your local date>>
NSTimeInterval timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMTForDate:localDate];
NSDate *gmtDate = [localDate dateByAddingTimeInterval:-timeZoneOffset]; // NOTE the "-" sign!

DSTを考慮して、GMT日付からlocalDateに変換するには:

NSDate *gmtDate  = <<your gmt date>>
NSTimeInterval timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMTForDate:gmtDate];
NSDate *localDate = [gmtDate dateByAddingTimeInterval:timeZoneOffset];

小さなメモ:dateByAddingTimeIntervalを使用しました。これはiOS 4のみです。 OS 3以前の場合は、addTimerIntervalを使用します。

5
thevoid

Swift 4

//UTC or GMT ⟺ Local 

extension Date {

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

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

}
4
Krunal

NSDateFormatterのドキュメントを見てみましたか?

NSDateFormatter

NSDateFormatterには、特にTimeZonesで遊ぶためのメソッドがいくつかあるようです。

-setTimeZone:

私は自分でテストしていませんが、もともと別のタイムゾーンで表されていた日付のタイムゾーンとしてGMTを設定すると、新しいタイムゾーンに合わせて正しい調整が行われた日付が表示されると思います。

3
Jasarien