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

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

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

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

iOS

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

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

Xcode

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

Swift

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

Q&A

解決済

1回答

1799閲覧

DateからStringを生成する際に「西暦」「和暦」の設定で出力が異なる

bbdd

総合スコア43

date

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

iOS

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

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

Xcode

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

Swift

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

0グッド

1クリップ

投稿2020/02/12 04:35

編集2020/02/18 06:58

前提

Swift5

わからないこと

「<言語設定が「西暦」の場合>」の「label2Text」のString from Date:の出力が2000/08/24である事の理由

詳細

下記のような検証用の実装を実行します。

swift

1 // 検証対象の日付String 2 let dateString = "2000/8/24" 3 4 /// stringからlocaleを指定せずにDateを生成し使用 5 func stringFromDate2() { 6 // Dateの生成 7 let formatter = DateFormatter() 8 formatter.dateFormat = "yyyy/MM/dd" 9 10 print("2 locale: (formatter.locale!)") 11 print("2 calender:(formatter.calendar!)") 12 print("\n") 13 let date = formatter.date(from: dateString) 14 15 // "yyyy/MM/dd"として表示 16 let f = DateFormatter() 17 f.dateFormat = "yyyy/MM/dd" 18 19 print("2.2 locale: (f.locale!)") 20 print("2.2 calender:(f.calendar!)") 21 print("\n") 22 let label2Text = "date: (date!)\n String from Date: (f.string(from: date!))" 23 } 24 25 /// stringからlocaleをja_JP指定にしてDateを生成し使用 26 func stringFromDate3() { 27 // Dateの生成 28 let formatter = DateFormatter() 29 formatter.locale = Locale(identifier: "ja_JP") 30 formatter.dateFormat = "yyyy/MM/dd" 31 32 print("3 locale: (formatter.locale!)") 33 print("3 calender:(formatter.calendar!)") 34 print("\n") 35 let date = formatter.date(from: dateString) 36 37 // "yyyy/MM/dd"として表示 38 let f = DateFormatter() 39 f.dateFormat = "yyyy/MM/dd" 40 41 print("3.2 locale: (f.locale!)") 42 print("3.2 calender:(f.calendar!)") 43 print("\n") 44 let label3Text = "date: (date!)\n String from Date: (f.string(from: date!))" 45 } 46 47 /// stringからlocaleをen_US_POSIX指定してDateを生成し使用 48 func stringFromDate4() { 49 // Dateの生成 50 let formatter = DateFormatter() 51 formatter.locale = Locale(identifier: "en_US_POSIX") 52 formatter.dateFormat = "yyyy/MM/dd" 53 54 print("4 locale: (formatter.locale!)") 55 print("4 calender:(formatter.calendar!)") 56 print("\n") 57 let date = formatter.date(from: dateString) 58 59 // "yyyy/MM/dd"として表示 60 let f = DateFormatter() 61 f.dateFormat = "yyyy/MM/dd" 62 63 print("4.2 locale: (f.locale!)") 64 print("4.2 calender:(f.calendar!)") 65 print("\n") 66 let label4Text = "date: (date!)\n String from Date: (f.string(from: date!))" 67 } 68

この時、

<言語設定が「西暦」の場合>

label2Text

date:2000-08-23 15:00:00:00 +0000 String from Date: 2000/08/24

label3Text

date:2000-08-23 15:00:00:00 +0000 String from Date: 2000/08/24

label4Text

date:2000-08-23 15:00:00:00 +0000 String from Date: 2000/08/24

<言語設定が「和暦」の場合>

label2Text

date:3988-08-23 15:00:00:00 +0000 String from Date: 2000/08/24

label3Text

date:2000-08-23 15:00:00:00 +0000 String from Date: 0012/08/24

label4Text

date:2000-08-23 15:00:00:00 +0000 String from Date: 0012/08/24

となります。
この際、「<言語設定が「西暦」の場合>」の「label2Text」のString from Date:の出力が2000/08/24である事の理由がわかりません。
stringFromDate2, stringFromDate3, stringFromDate4において、Dateから Stringを生成する際にはどれもDateFormatterを生成しそれを用いてStringに変換する、というやり方は同じですが、和暦において出力の差異が生じていることが分からなかったです。
フォーマッターのlocale等を指定していないので、String from Date: 0012/08/24が出力される想定でした。

これはその前の処理である、StringからDateを生成する際のCalendar設定が影響しているという事なのでしょうか?

参考

【Swift】Dateの王道 【日付】 - Qiita

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

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

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

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

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

bbdd

2020/02/12 05:16 編集

リンクのご提示ありがとうございます! こちらの記事は参考済みであり、本件は内容確認後なお生じた疑問となります。 参考記事として明記させて頂きました。
guest

回答1

0

ベストアンサー

macOS 10.15.3, XCode 11.3.1, iOS 13.3 (Simulator), タイムゾーン PST の環境で試しましたが、
言語設定が「英語」かつカレンダーが「和暦(Japanese)」の場合、label2Text は

date: 4018-08-24 07:00:00 +0000 String from Date: 2000/08/24

となりました。これは令和 2000 年(西暦 4018 年)を意味します。

iOS や macOS の DateFormatter では locale の他に calendar を指定できますが、Locale は calendar を含んでいるため、
・無指定の場合、言語・カレンダーともに環境設定で指定したもの
・locale のみを指定した場合、言語・カレンダーともに locale で指定したもの
・locale と calendar をそれぞれ指定した場合、言語・カレンダーそれぞれ指定したもの
になるようです。

swift

1// locale, calendar いずれも無指定の場合、 2let f1 = DateFormatter() 3print("locale: (f1.locale!)") // locale: en_US@calendar=japanese (current) 4print("calender: (f1.calendar!)") // calender: japanese (current) 5 6// locale のみを指定した場合 7let f2 = DateFormatter() 8f2.locale = Locale(identifier: "ja_JP") 9print("locale: (f2.locale!)") // locale: ja_JP (fixed) 10print("calender: (f2.calendar!)") // calender: gregorian (fixed) 11 12// カレンダーつき locale を指定した場合 13let f3 = DateFormatter() 14f3.locale = Locale(identifier: "ja_JP@calendar=japanese") 15print("locale: (f3.locale!)") // locale: ja_JP@calendar=japanese (fixed) 16print("calender: (f3.calendar!)") // calender: japanese (fixed) 17 18// locale, calendar をそれぞれ指定した場合 19let f4 = DateFormatter() 20f4.locale = Locale(identifier: "ja_JP") 21f4.calendar = Calendar(identifier: .japanese) 22print("locale: (f4.locale!)") // locale: ja_JP (fixed) 23print("calender: (f4.calendar!)") // calender: japanese (fixed)

投稿2020/02/12 07:02

編集2020/02/12 07:07
hoshi-takanori

総合スコア7901

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

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

bbdd

2020/02/18 06:56

ご回答ありがとうございます! ご返答が遅くなり申し訳ございません。 本質問にあります、 > 「<言語設定が「西暦」の場合>」の「label2Text」のString from Date:の出力が2000/08/24である事の理由 というところの理由としてはどのように考えていますでしょうか? 質問内の「label2Text」 「label4Text」においてDateから出力する際のlocaleとcalenderはどちらも下記のようになると思います(locale, calenderの指定はないので) locale: ja_JP (current) calender:gregorian (current) 同じ設定なのに出力がなぜ異なるのか、ご説明頂けると幸いです。 (回答内容は理解しているつもりなのですが、そちらに記載済みの内容でしたらすみません。。自分の理解が及んでいないです。。)
hoshi-takanori

2020/02/18 07:05

すみません、「同じ設定なのに出力がなぜ異なるのか」とは、どれとどれのことでしょうか?
bbdd

2020/02/20 10:54 編集

こちらこそ分かり辛くすみません、、 質問分内の下記箇所となります。 <言語設定が「和暦」の場合> label2Text → date:3988-08-23 15:00:00:00 +0000 String from Date: 2000/08/24 と <言語設定が「和暦」の場合> label4Text → date:2000-08-23 15:00:00:00 +0000 String from Date: 0012/08/24 です。 「label2Text」 「label4Text」においてlocaleとcalendarの設定は locale: ja_JP (current), calender:gregorian (current) となると思うのですが、出力が異なっているのが気がかりとなっております。
hoshi-takanori

2020/02/20 21:41

label2Text, label4Text のいずれも、入力と出力で DateFormatter が異なります(入力は formatter、出力は f)ので、分けて考える必要があります。 <言語設定が「和暦」の場合> の label2Text は、入力は formatter が和暦なので、和暦で入力され、平成または令和 2000 年と解釈され、出力は (date) は常に西暦なので 3988 年(平成 2000 年)、f は和暦なので f.string(from: date) は元号を省略して 2000 年と表示されます。 <言語設定が「和暦」の場合> の label4Text は、入力特には formatter.locale が指定されているのでcalendar が gregorian となり、西暦 2000 年と解釈され、出力は (date) は常に西暦なので 2000 年、f は和暦なので f.string(from: date) は元号(平成)を省略して 12 年と表示されます。
bbdd

2020/02/25 08:30

こちらの返答で理解/納得致しました。 ご返答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問