1

私は以下のコードを持っています

public Long getEpochTime(String dateToGetItsEpoch) throws ParseException
{
    TimeZone timeZone = TimeZone.getTimeZone("UTC");
    final String REQUEST_DATE_FORMAT = "dd/MM/yyyy h:m";

    DateFormat format = new SimpleDateFormat(REQUEST_DATE_FORMAT);
    Date localDate = format.parse(dateToGetItsEpoch);

    Calendar cal = Calendar.getInstance(timeZone);
    cal.setTime(localDate);

    format.setTimeZone(timeZone);
    final String utcTime = format.format(cal.getTime());

    Date d = cal.getTime();

    return d.getTime();
}

デバイスのロケールを変更すると、戻り値として常に UTC 時刻が返されます。どちらが正しいのですが、これがどのように起こっているのか知りたいですか? デバイスは、どのタイムゾーンが与えられた日付であるかをどのように認識し、それに応じて計算しますか?

4

2 に答える 2

1

java.time

Jon Skeetによる回答は正しいです。問題のある従来の日時クラスに取って代わった最新のjava.timeクラスを使用するように更新されたコードを次に示します。

フォーマットパターン

入力に一致するフォーマット パターンを定義します。

ところで、あなたのフォーマットの選択は不適切です。代わりに、日時の値をテキストとして交換するために設計された標準のISO 8601形式を使用することをお勧めします。

12 時間制と 24 時間制

入力データまたはフォーマット パターンに欠陥があります。h12 時間制の 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の使用に移ってください。DateCalendar

于 2020-02-05T23:37:55.833 に答える