現地の日付と時刻を取得する方法は知っていますが、私がやりたいのは、さまざまな場所から日付と時刻を取得することです。たとえば、ニューヨークの日時を知りたいのですが。この単純な問題をどのように解決できますか?
これが現地の日付と時刻の私のコードです:
let date = NSDate()
let calendar = Calendar.current
let components = calendar.dateComponents([.hour, .minute, .month, .year, .day, .second, .weekOfMonth], from: date as Date)
let currentDate = calendar.date(from: components)
ここで検索しましたが、欲しいものが見つからず、日付ライブラリを探しています。私をリダイレクトするためのソースやサンプルを知っているなら、本当に感謝しています。
日付を文字列にフォーマットするだけの場合は、代わりにDateFormatter
を使用することを検討してください。
_let date = Date()
let formatter = DateFormatter()
formatter.timeZone = TimeZone(identifier: "America/New_York")
formatter.dateStyle = .long
formatter.timeStyle = .long
formatter.string(from: date)
_
日付コンポーネントを取得して処理する場合は、 dateComponents(in:from:)
メソッドを使用します。
_let components = Calendar.current.dateComponents(in: TimeZone(identifier: "America/New_York")!, from: date)
_
ここにはいくつかの異なる概念が関係しており、これを正しく行うには、(ほぼ)すべてを理解する必要があります...
1)Date
(SwiftではNSDate
)は絶対的な時点です-2017年11月13日のような実際の日付とは関係がないため、名前を少し間違えています。これを定義する必要があるためです。 ..
2)Calendar
。グレゴリオ暦西部の2017年11月13日は、イスラム暦のサファル1439年、ヘシボン暦のヘシボン5778年の24日、またはiOSとMacOSがサポートする他の多くの暦のその他のことである可能性があるためです。 ;
3)次に、Calendar
は、DateComponents
に返される値だけでなく、Date
+ Calendar
を日、月、年、時代(BC/ADなど)、さらには週番号などに解凍するために使用する必要があります。 、だけでなく一部のカレンダーには他のカレンダーと同じコンポーネントがない場合があります;
4)時刻(ご存知のとおり)はTimeZone
に依存するため、同じabsolute時刻は、現在地に応じて「時」のさまざまな時刻の1つになる可能性があります。また、(以下の例でわかるように)dateと「時」を変更する場合もあります。もちろん、これは自動(現在の場所)でも、プログラマーが設定することもできます。
5)さらに、2017年11月13日couldは、英国人かどうかに応じて13/11/17または11/13/17として表されるため、DateFormatter
(DateComponents
をまとめるのに便利です)があります。またはアメリカ人。また、テキストと月のどちらを使用するか、時間を表示する場合は12時間形式と24時間形式のどちらを使用するかを選択することもできます。これらはすべて、DateFormatter
でカバーされますが、butテキスト表現は次のようになります。フランス語の場合は「13eNovembre2017」の概念を紹介します
6)Locale
。これは、TimeZone
のように、デフォルト(デバイスのセットアップ時に選択)またはプログラマーが指定するように設定できます。
投稿したコードは機能しません。これは、Date
を取得し、それをCalendar
からDateComponents
に変換するだけですが(これまでのところすべて問題ありません)、コンポーネントからDate
を再作成します。取得するのは元のDate
だけです。同じ絶対時点。
コメントの質問と質問への回答から私が信じているのは、絶対時間(「今」など)、別名Date
を取り、それを特定のTimeZone
に表示する関数が必要だということです。これは機能します:
func timeComponents(date: Date, timeZone: TimeZone) -> DateComponents {
var calendar = Calendar.current
calendar.timeZone = timeZone
return calendar.dateComponents([.hour, .minute, .month, .year, .day, .second, .weekOfMonth], from: date)
}
let absTime: Date = Date() // Now
let edinburgh = TimeZone(abbreviation: "GMT")!
let newYork = TimeZone(abbreviation: "EST")!
let ec = timeComponents(date: absTime, timeZone: edinburgh)
let nycc = timeComponents(date: absTime, timeZone: newYork)
print(ec)// year: 2017 month: 11 day: 14 hour: 0 minute: 44 second: 10 weekOfMonth: 3 isLeapMonth: false
print(nycc) // year: 2017 month: 11 day: 13 hour: 19 minute: 44 second: 10 weekOfMonth: 3 isLeapMonth: false
...これはあなたの質問の最小限に答えると思いますが、それを精巧にするために、DateComponents
からDateFormatter
に移動する必要があります
func timeString(date: Date, timeZone: TimeZone, timeStyle: DateFormatter.Style) -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = timeZone
dateFormatter.dateStyle = .none
dateFormatter.timeStyle = timeStyle
return dateFormatter.string(from: date)
}
let es = timeString(date: absTime, timeZone: edinburgh, timeStyle: .full)
let nycs = timeString(date: absTime, timeZone: newYork, timeStyle: .full)
print(es) // 12:44:10 AM Greenwich Mean Time
print(nycs) // 7:44:10 PM Eastern Standard Time
アプリを国際化したい場合は、続行してLocale
の使用を開始できますが、これは演習として残しておきます。
p.s.これらはnotすべての概念です ここ を参照してください
検索する場所のタイムゾーンがわからない場合は、CoreLocationのCLGeocoderを使用して、住所文字列を検索できます。次に、その場所のタイムゾーンを取得し、それを探している時間に変換できます。
let geocoder = CLGeocoder()
geocoder.geocodeAddressString("New York, New York") { (placemarks, error) in
guard error == nil else {
print("Error")
print(error!.localizedDescription)
return
}
guard let placemarks = placemarks,
let place = placemarks.first else {
print("No results")
return
}
if let timeZone = place.timeZone {
print("TimeZone: \(timeZone.identifier)")
// TimeZone: America/New_York
//Ignore the time zone offset from this one, it will be the difference between the current time and the new york time
let dateInNewYork = Date().addingTimeInterval(TimeInterval.init(timeZone.secondsFromGMT()))
print(dateInNewYork)
// 2017-11-13 15:03:05 +0000
//Or
let formatter = DateFormatter()
formatter.timeZone = TimeZone(identifier: timeZone.identifier)
formatter.dateStyle = .long
formatter.timeStyle = .long
let formattedDateInNewYork = formatter.string(from: Date())
print(formattedDateInNewYork)
// November 13, 2017 at 3:03:05 PM EST
//Or
let components = Calendar.current.dateComponents(in: TimeZone(identifier: timeZone.identifier)!, from: Date())
print(components.date!)
// 2017-11-13 20:03:05 +0000
}
}