java.time
Jon Skeetによる回答は正しいです。問題のある従来の日時クラスに取って代わった最新のjava.timeクラスを使用するように更新されたコードを次に示します。
フォーマットパターン
入力に一致するフォーマット パターンを定義します。
ところで、あなたのフォーマットの選択は不適切です。代わりに、日時の値をテキストとして交換するために設計された標準のISO 8601形式を使用することをお勧めします。
12 時間制と 24 時間制
入力データまたはフォーマット パターンに欠陥があります。h
12 時間制の 1 時間または 2 桁を意味する小文字を使用しました (24 時間制の大文字H
またはではなくHH
)。したがって、AM
またはのインジケーターを追加しない限り、入力は意味がありませんPM
。質問のコードからこれを誤って省略したと思います。
Locale locale = Locale.US ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu h:m a" ).withLocale( locale ) ;
LocalDateTime
LocalDateTime
このような文字列は、意図したタイム ゾーンまたは UTC からのオフセットのインジケーターがないため、オブジェクトとして解析します。
String input = "23/01/2020 4:5 PM" ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
ldt.toString(): 2020-01-23T16:05
一瞬
上記LocalDateTime
で取得したオブジェクトは、瞬間を表すものではなく、タイムライン上のポイントでもありません。23日の午後4時くらいまでお時間をいただいております。しかし、これが東京の午後 4 時なのか、トゥールーズなのか、それともトレドなのかはわかりません。数時間離れた非常に異なる瞬間です。
瞬間を判断するには、目的のタイムゾーンを確実に知る必要があります。次に、そのゾーンを として適用してZoneId
を取得しZonedDateTime
ます。それから私たちは一瞬で到着しました。
Locale
タイムゾーンではありません
デバイスのロケールを何でも
ALocale
はtime zone とは何の関係もありません。Locale
は、日時オブジェクトを表す生成テキストをローカライズするために使用されます。
ローカライズするには、次を指定します。
FormatStyle
文字列の長さまたは省略形を決定します。
Locale
決定する:
- 曜日名、月名などを翻訳する人語。
- 略語、大文字、句読点、区切り記号などの問題を決定する文化的規範。
例:
Locale l = Locale.CANADA_FRENCH ; // Or Locale.US, Locale.JAPAN, etc.
DateTimeFormatter f =
DateTimeFormatter
.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( l )
;
String output = myZonedDateTime.format( f );
Locale.CANADA_FRENCH
人間の言語と文化的規範にを使用するケベック出身のエンジニアがいる可能性がありますが、日本を訪問している間はAsia/Tokyo
、予定のスケジュールにタイムゾーンを使用します。
ZonedDateTime
オブジェクトに戻りLocalDateTime
ます。チュニジアの実時間で見られる瞬間を表すことを意図したものであることが確実な場合は、 のタイムゾーンを適用しますAfrica/Tunis
。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
あなたは尋ねました:
デバイスはどのタイムゾーンが与えられた日付であるかをどのように認識し、それに応じて計算しますか?
タイムゾーンまたは UTC からのオフセットのインジケーターがない日時の概念を説明できない、ひどい日時クラスを使用していました。したがって、技術的には、コードはごちゃごちゃでハックであり、Joda -Timeとその後継であるjava.timeの前の時代には避けられませんでした。
&の振る舞いを理解しようと努力しないことをお勧めします。業界をリードする日時処理フレームワークであるjava.timeの使用に移ってください。Date
Calendar