質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
date

dateは、date型や日付に関する関数や処理についてのタグです

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

761閲覧

SwiftのStringからDateへの変換時にlocaleを設定するとcalenderも変更される

bbdd

総合スコア43

date

dateは、date型や日付に関する関数や処理についてのタグです

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/01/30 10:46

質問内容

localeを設定するとcalenderも変更される、と思っていますが、
これは正しい認識でしょうか?
また、これが正しいならそれについて記載された公式のリファレンス等ありますでしょうか?
(この内容について確信が持てず、、)

詳細

例えば以下のように
"2000/8/24"をDate型に変換した際に、このdateは端末の暦の設定に依存して
値が変わるという認識でした。

swift

1let dateString = "2000/8/24" 2let formatter = DateFormatter() 3formatter.dateFormat = "yyyy/MM/dd" 4formatter.locale = Locale(identifier: "ja_JP") 5let date = formatter.date(from: dateString) 6print("date: (date!)")

この認識は例えばこの記事の下記内容などからそのように思っていました。

これを実行してみると通常の設定ではdateは正しく2017/8/12と取得されます。
しかし、例えばiPhoneの設定から日付を西暦ではなく「和暦」にしてみるとどうでしょう?
すると4005/8/12と取得されてしまいます。

つまり想定される値は
端末の言語設定(設定>一般>言語と地域)により下記のように変更されることでした。

  • 西暦: 2000-08-23 15:00:00 +0000
  • 和暦: 3988-08-23 15:00:00 +0000

でしたが、実際には西暦/和暦共に2000-08-23 15:00:00 +0000が出力されていました。
そこでformatterのlocale、calenderの値を出力してみたところ下記のようになっていました。

locale: ja_JP (fixed) calender:gregorian (fixed)

従ってlocaleを設定するとcalenderも変更される、と思っていますが、
これは正しい認識でしょうか?
localeを設定し、暦が変更されているので端末の影響を受けていない、という解釈です。
また、これが正しいならそれについて記載された公式のリファレンス等ありますでしょうか?
(この内容について確信が持てず、、)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Qiitaの説明記事は、少し言葉足らずになっていると思います。

しかし、例えばiPhoneの設定から日付を西暦ではなく「和暦」にしてみるとどうでしょう?
すると4005/8/12と取得されてしまいます。

というよりも

しかし、例えばiPhoneの設定から日付を西暦ではなく「和暦」にし、
formatter.locale = Locale(identifier: "ja_JP")の行を削除してみるとどうでしょう?
すると4005/8/12と取得されてしまいます。

と説明すべきだと思います。
(今は令和になっているので、令和2000年=西暦4018になるようです。)

DateFormatterのlocaleとCalendarのlocaleは別に連動したりしません。

formatter.locale = Locale(identifier: "ja_JP")
を設定したら、localeは ja_JP (fixed)になるし、
locale設定コードを削除すれば、iPhoneの設定内容がデフォルトで入るので、
localeは japanese (current)のようになります。

Calendarは、
let calendar = Calendar(identifier: .gregorian)
でcalendarを生成したら、localeは gregorian (fixed)になるし、
let calendar = Calendar.current
でcalendarを生成したらiPhoneの設定内容がデフォルトで入るので、
localeはjapanese (current)のようになります。
インスタンスの生成の仕方の違いで中に設定されているlocaleが変わるだけです。


(2/2 0:15 追記)

すみません。質問の意図を勘違いしていました。
DateFormatterのlocaleプロパティと別のCalendarインスタンスのlocaleプロパティは連動しているのか?
と聞いているのではなく、
DateFormatterのlocaleプロパティと同じDateFormatterインスタンスのcalendarプロパティは連動しているのか?
と聞いているのですね。

swift

1let dateString = "2000/8/24" 2let formatter = DateFormatter() 3formatter.dateFormat = "yyyy/MM/dd" 4print(formatter.locale!) 5print(formatter.calendar!) 6print(formatter.calendar.locale!) 7print("date: (formatter.date(from: dateString)!)") 8 9formatter.locale = Locale(identifier: "ja_JP") 10print(formatter.locale!) 11print(formatter.calendar!) 12print(formatter.calendar.locale!) 13print("date: (formatter.date(from: dateString)!)")

iPhoneの設定を「和暦」にして、上記のコードを実行してみたところ、
次の結果が得られましたので、localeを設定すると、そのlocaleに
対応したCalendarインスタンスがcalendarプロパティに設定される
と考えて良いと思います。

en@calendar=japanese (current) japanese (current) en@calendar=japanese (current) date: 4018-08-23 15:00:00 +0000 ja_JP (fixed) gregorian (fixed) ja_JP (fixed) date: 2000-08-23 15:00:00 +0000

投稿2020/01/30 16:01

編集2020/02/01 15:16
TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bbdd

2020/02/01 11:38 編集

@TakeOne 早速のご返答ありがとうございます! 下記内容が理解出来なかったです。。 > DateFormatterのlocaleとCalendarのlocaleは別に連動したりしません。 質問内容の下記コードの場合`Calendar`のインスタンスは明示的に生成していません。 しかし、`calender:gregorian (fixed)`になっていることの説明としては、` Locale(identifier: "ja_JP")`時にCalendarのインスタンスが生成されている、という認識でしょうか? ``` let dateString = "2000/8/24" let formatter = DateFormatter() formatter.dateFormat = "yyyy/MM/dd" formatter.locale = Locale(identifier: "ja_JP") let date = formatter.date(from: dateString) print("date: (date!)") ```
TakeOne

2020/02/01 15:16

すみません。質問を少し勘違いしていたので、回答を追記しました。
bbdd

2020/02/03 01:08 編集

質問意図が分かりにくくすみませんでした! 追記内容確認しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問