HOME > NSCalenderやNSDateで日付の仕組みを知る
NSDate,NSDateComponents,NSCalendarを利用してローカル通知の実装をしていたのですが、 取得できる時間が日本時間ではなく毎回混乱している、、、ので、この記事で整理できたらと思います。
やりたいことは、現在の日付がなぜズレているのか、 を紐解いて現在の日本時間を表示する方法を行ってみます。
参考:iOS8からの日付(NSDate)操作・比較
参考:[Swift]NSDateComponentで日付の各要素を取得
参考:Foundation Framework Reference NSCalendar Class Reference
参考:How to get the current time(and hour) as datetime - Swift
参考:Swift NSDate UTC time and local tme
参考:イギリス / ロンドンの時差と現在時刻
参考:グリニッジ標準時間:2015年9月7日 月曜日 22:44
参考:Swiftで現在日時を取得し、様々なスタイルで出力する方法
まず以下を実行してみます。
println(NSDate())
2015-09-07 22:29:09 +0000と表示されました。ちなみに、現在本当の日本時間は、 2015-09-08 07:29:09 +0000となっています。9時間進んでいる。確かイギリスの標準時間と日本との時差は8時間だった 気がしていたので、ハマっていました。うーん、なんでだろうか。
以下のグリニッジ標準時間と比較しても、時差8時間で正しい感じがします
サマータイム中だけど、関係ないよね、、、あるのかな。
関係ありました、グリニッジ標準時間と9時間の時差でした。。orz ただサマータイム中は8時間のようです。こういった要素から、プログラム上と 僕の頭の中では混乱が生じていたのかなぁ、、、と思いました。つきましてはNSDateをそのまま利用してprintlnするとGMT グリニッジ標準時の値が 表示されていることを理解しました。
方法として二つ。1つはNSDateFormatterを利用、または、NSDateComponetnsを利用する方法。それぞれ見てまいります。
let now = NSDate() //現在時刻
println(now) //->2015-09-07 22:52:43 +0000
let df = NSDateFormatter()
df.timeStyle = .ShortStyle//ここを変更すると出力日付の情報量を変更可能
df.dateStyle = .ShortStyle//ここを変更すると出力日付の情報量を変更可能
df.locale = NSLocale(localeIdentifier: "en_US")
println(df.stringFromDate(now)) // -> 9/8/15, 7:52 AM
df.locale = NSLocale(localeIdentifier: "ja_JP")
println(df.stringFromDate(now)) // -> 2015/09/08 7:52
どうやら自分が勘違いしていた箇所がありました。NSLocaleで英語や日本語に変換した時に時差も変わるかと漠然と勘違いしていました。。。 東京とかNYとかセットするわけではないので、普通に考えれば当たり前だったのかもしれませんが、ハマっていました。
同様にNSCalendarを利用する方法もあります。
西暦を利用したい場合はカレンダーにNSCalendarIdentifierGregorianを指定します。
let now = NSDate()
println(now);// -> 2015-09-07 23:03:58 +0000
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
var comps:NSDateComponents = calendar!.components(NSCalendarUnit.YearCalendarUnit|NSCalendarUnit.MonthCalendarUnit|NSCalendarUnit.DayCalendarUnit|NSCalendarUnit.HourCalendarUnit|NSCalendarUnit.MinuteCalendarUnit|NSCalendarUnit.SecondCalendarUnit,
fromDate: now)
var year = comps.year
var month = comps.month
var day = comps.day
var hour = comps.hour
var minute = comps.minute
var second = comps.second
println("\(year)/\(month)/\(day)/\(hour)/\(minute)/\(second)")// -> 2015/9/8/8/3/58
和暦を利用したい場合はカレンダーにNSCalendarIdentifierJapaneseを指定します。 和暦とは日本の平成とかの元号を利用した表示をしてくれます。以下の例であれば、平成27年の年度が取得できています。
let now = NSDate()
println(now);// -> 2015-09-07 23:05:54 +0000
let calendar = NSCalendar(identifier: NSCalendarIdentifierJapanese)
var comps:NSDateComponents = calendar!.components(NSCalendarUnit.YearCalendarUnit|NSCalendarUnit.MonthCalendarUnit|NSCalendarUnit.DayCalendarUnit|NSCalendarUnit.HourCalendarUnit|NSCalendarUnit.MinuteCalendarUnit|NSCalendarUnit.SecondCalendarUnit,
fromDate: now)
var year = comps.year
var month = comps.month
var day = comps.day
var hour = comps.hour
var minute = comps.minute
var second = comps.second
println("\(year)/\(month)/\(day)/\(hour)/\(minute)/\(second)")// -> 27/9/8/8/5/54
ふむふむ、、、、なるほどです。自分で納得してきております。。。
勘違いしていたNSDateの理解度、自分自身この記事で少し整理できたようにおもいますので、 何かヘルプになっていれば幸いです。
2021-05-14 14:21:41 | WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。
AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、
昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は... |
2021-05-06 14:04:37 | LINEのアニメーションスタンプ制作の落とし穴、、、失敗談
ゴールデンウィークにLINEスタンプを作成してみました。
作り切って申請も通したんですが、意図したアニメーションと違う、、、、
LINEクリエーターの画面だと、アニメーションのプレビュー... |
2021-05-01 18:05:35 | 久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。
忘れないようにメモ
エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。
ターゲット→ex... |
Tweet | |||
|