Swift転職なら=>【LevTech】
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > NSCalenderやNSDateで日付の仕組みを知る

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で現在日時を取得し、様々なスタイルで出力する方法

やってみた

NSDateが現在の時刻とズレている???件に関して

まず以下を実行してみます。


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を利用する方法。それぞれ見てまいります。

NSDateFormatterを利用する


        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を利用する

同様に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の理解度、自分自身この記事で少し整理できたようにおもいますので、 何かヘルプになっていれば幸いです。

↓こんな記事もありますよ!

外部ブラウザでURLを開く

アプリから外部ブラウザ(Safari)でURLを開く方法を記載します。内部的に利用する場合はWebViewを利用します。

UIFontのフォント一覧をWebViewで表示させてそれをキャプチャ保存する

文字フォントがわかっても実際の文字がわかりませんので、 WebViewに出力させて、その結果を端末のPhotoアルバムに保存させる処理をつくってみました

UIWebView

アプリの中にWebビューを作成して外部ネットワークやローカルのhtmlやcssやjsファイルと連携する方法の説明です。
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!