web-dev-qa-db-ja.com

NSDateオブジェクトからUTC時間と現地時間を取得する

Objective-Cでは、次のコードはdate APIを使用してUTC日時情報を生成します。

NSDate *currentUTCDate = [NSDate date]

ただし、Swiftでは、

let date = NSDate.date()

ローカルの日付と時刻になります。

2つの質問があります。

  1. dateオブジェクトでUTC時間とローカル時間(NSDateはローカル時間を与える)を取得するにはどうすればよいですか。
  2. NSDateオブジェクトから秒単位の精度を取得するにはどうすればよいですか。

編集1:すべての入力に感謝しますが、NSDateFormatterオブジェクトまたは文字列値を探していません。 NSDateオブジェクトを探しているだけです(ただし、それらを作成しますが、それが要件です)。
ポイント1を参照してください。

57
p0lAris

ドキュメントでは、dateメソッドは、使用されている言語に関係なく、現在の日付と時刻に設定された新しい日付を返すと述べています。

この問題は、おそらくNSDateFormatterを使用して日付を提示する場所にあります。 NSDateはタイムライン上の単なるポイントです。 NSDateについて話すとき、タイムゾーンはありません。テストをしました。

Swift

print(NSDate())

出力:2014-07-23 17:56:45 +0000

Objective-C

NSLog(@"%@", [NSDate date]);

出力:2014-07-23 17:58:15 +0000

結果-差異なし

27
RaffAl

NSDateは特定の時点タイムゾーンなしです。基準日から経過した秒数と考えてください。特定の参照日からあるタイムゾーンと別のタイムゾーンで何秒経過しましたか? 答えは同じです。

outputその日付(デバッガーの確認を含む)によっては、異なるタイムゾーンで回答が得られる場合があります。

それらが同時に実行された場合、これらの値は同じです。これらは両方とも基準日からの秒数であり、フォーマットされる場合があります出力時 UTCまたは現地時間。日付変数内では、両方ともUTCです。

Objective-C:

NSDate *UTCDate = [NSDate date]

迅速:

let UTCDate = NSDate.date()

これを説明するために、プレイグラウンドでNSDateFormatterを使用できます。

import UIKit

let date = NSDate.date()
    // "Jul 23, 2014, 11:01 AM" <-- looks local without seconds. But:

var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
let defaultTimeZoneStr = formatter.stringFromDate(date)
    // "2014-07-23 11:01:35 -0700" <-- same date, local, but with seconds
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.stringFromDate(date)
    // "2014-07-23 18:01:41 +0000" <-- same date, now in UTC

日付outputはさまざまですが、日付は一定です。これはまさにあなたが言っていることです。ローカルNSDateのようなものはありません。

マイクロ秒を取得する方法については、これを使用できます(同じプレイグラウンドの下部に配置します)。

let seconds = date.timeIntervalSince1970
let microseconds = Int(seconds * 1000) % 1000 // chops off seconds

2つの日付を比較するには、date.compare(otherDate)を使用できます。

60
Steven Fisher

Xcode 9•Swift 4(Swift 3.xも機能します)

extension Formatter {
    // create static date formatters for your date representations
    static let preciseLocalTime: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "HH:mm:ss.SSS"
        return formatter
    }()
    static let preciseGMTTime: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.dateFormat = "HH:mm:ss.SSS"
        return formatter
    }()
}

extension Date {
    // you can create a read-only computed property to return just the nanoseconds from your date time
    var nanosecond: Int { return Calendar.current.component(.nanosecond,  from: self)   }
    // the same for your local time
    var preciseLocalTime: String {
        return Formatter.preciseLocalTime.string(for: self) ?? ""
    }
    // or GMT time
    var preciseGMTTime: String {
        return Formatter.preciseGMTTime.string(for: self) ?? ""
    }
}

遊び場のテスト

Date().preciseLocalTime // "09:13:17.385"  GMT-3
Date().preciseGMTTime   // "12:13:17.386"  GMT
Date().nanosecond       // 386268973

これは、日付の書式設定にも役立つ場合があります。

enter image description here

40
Leo Dabus

日付はどのタイムゾーンにも依存しないため、Dateformatterを使用して表示用のタイムゾーンを添付します。

迅速:

let date = NSDate()
let dateFormatter = NSDateFormatter()
let timeZone = NSTimeZone(name: "UTC")

dateFormatter.timeZone = timeZone

println(dateFormatter.stringFromDate(date))

objC:

NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];

[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:timeZone];       
NSLog(@"%@", [dateFormatter stringFromDate:date]);
22
Daij-Djan
let date = Date() 
print(date) // printed date is UTC 

playgroundを使用している場合は、printステートメントを使用して時間を確認します。プレイグラウンドでは、印刷するまで現地時間が表示されます。遊び場の右側のパネルに依存しないでください。 enter image description here

このコードは日付をUTCで提供します。現地時間が必要な場合は、タイムゾーンをTimezone.currentとして次の拡張子を呼び出す必要があります

 extension Date {

   var currentUTCTimeZoneDate: String {
        let formatter = DateFormatter()
        formatter.timeZone = TimeZone(identifier: "UTC")
        formatter.amSymbol = "AM"
        formatter.pmSymbol = "PM"
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

        return formatter.string(from: self)
    }
}

UTC時間の場合、次のように使用します:Date().currentUTCTimeZoneDate

17

現時点では(Swiftの最新の変更により)、NSDate.date()は使用できなくなりました。

代わりに、NSDateを初期化するだけで、現在の日付と時刻が取得されます。
試してみるには、遊び場で:

var d = NSDate()
d

そして、あなたは得るでしょう:

Oct 22, 2014, 12:20 PM"  
12
Ali

Swift

UTCから現在のタイムゾーンに基づいて日付を取得できます

extension Date {
    func currentTimeZoneDate() -> String {
        let dtf = DateFormatter()
        dtf.timeZone = TimeZone.current
        dtf.dateFormat = "yyyy-MM-dd HH:mm:ss"

        return dtf.string(from: self)
    }
}

このような呼び出し:

Date().currentTimeZoneDate()
7
Piyush Sanepara

My Xcodeバージョン6.1.1(6A2008a)

遊び場で、次のようにテストします。

// I'm in East Timezone 8
let x = NSDate() //Output:"Dec 29, 2014, 11:37 AM"
let y = NSDate.init() //Output:"Dec 29, 2014, 11:37 AM"
println(x) //Output:"2014-12-29 03:37:24 +0000"


// seconds since 2001
x.hash //Output:441,517,044
x.hashValue //Output:441,517,044
x.timeIntervalSinceReferenceDate //Output:441,517,044.875367

// seconds since 1970
x.timeIntervalSince1970 //Output:1,419,824,244.87537
4
fujianjin6471

Swift4でUTCを取得する簡単な方法を見つけました。このコードを遊び場に置く

let date = Date() 
*//"Mar 15, 2018 at 4:01 PM"*

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let newDate = dateFormatter.string(from: date) 
*//"2018-03-15 21:05:04 +0000"*
1
Usuf

他の回答に加えて、Dateクラスの拡張機能を作成して、特定のTimeZoneでフォーマットされたデータを取得し、将来使用するためのユーティリティ関数として作成することができます。いいね

 extension Date {

 func dateInTimeZone(timeZoneIdentifier: String, dateFormat: String) -> String  {
 let dtf = DateFormatter()
 dtf.timeZone = TimeZone(identifier: timeZoneIdentifier)
 dtf.dateFormat = dateFormat

 return dtf.string(from: self)
 }
}

今、あなたはそれを次のように呼び出すことができます

 Date().dateInTimeZone(timeZoneIdentifier: "UTC", dateFormat: "yyyy-MM-dd HH:mm:ss");
0