22

この奇妙な問題があります。ロケールを使用してカレンダーを作成すると、TimeZoneがローカルのカレンダーに戻るだけです。

public void start(Locale locale){
    String s = locale.getDisplayName(); 
    System.err.println(s);
    Calendar c = new GregorianCalendar(locale);
    System.err.println(c.getTimeZone());
}

そしてこれは出力です:

 español (Argentina)
 sun.util.calendar.ZoneInfo[id="Europe/Bucharest", //etc more useless date here....

特定のロケールから適切な時刻を取得するにはどうすればよいですか?

4

2 に答える 2

50

簡単な答え:できません。

長い答え:「ロケールに適したタイムゾーン」などはありません。これは、複数のタイムゾーンを持つ国がいくつかあるためです(たとえば、米国)。タイムゾーンは別の概念です。

とにかく、あなたはあなたの問題を解決しようとしています。Webアプリケーションを作成していて、タイムゾーンがサーバーのデフォルトに戻っていることがわかります。それは典型的な状況です。Locale.getDefault()とは両方ともTimeZone.getDefault()サーバー関連の情報を返します。JVMには、「適切な」タイムゾーンを知る方法がありません。それで、あなたはそれについて何ができますか?

  1. タイムゾーン情報をユーザープロファイルに追加するか(ある場合)、タイムゾーンコンボボックスを作成することができます(ユーザーが実行時に切り替えることができるようにするため)。次に、適切なオブジェクトをインスタンスに割り当てることができ、DateFormatタイムゾーンが自動的に変換されます。
  2. JavaScript Date ObjectのgetTimezoneOffset()関数を介してクライアントから現在のタイムゾーンオフセットを読み取り、何らかの方法で(AJAX)サーバーに送信できます。この方法の問題は、そのオフセットを持つ複数のタイムゾーンがあり、選択したタイムゾーンが他の日付には不適切である可能性があることです。もちろん、時間変更日の前後のデータをポーリングすることでタイムゾーンを推測できますが、これはおそらくあなたがやりたいことではありません。
  3. 書式なしの時刻をクライアントに送信し(たとえば、ISO 8601日時形式またはUTCに関連するエポックのUnix時刻として記述)、 GlobalizeまたはDojo形式の日付と時刻を使用できます。

これらの3つの選択肢の中から、私は常に1番を選びます。ユーザープロファイルにタイムゾーン情報を入力することで、現在のWebブラウザーなどに関係なく、ユーザーの好みのタイムゾーンを確実に把握できます。一部のユーザーは、他の国を訪問しているときにアプリケーションを使用したい場合があります...

于 2012-05-13T10:53:06.167 に答える
9

ロケールとタイムゾーンは直交する問題です

Locale

ALocaleは次のペアを表します。

  • フランス語、英語、中国語などの人間の言語。
  • キャピタライゼーション、省略形、日付の日-月-年などの要素の順序などのフォーマットの質問などの問題を決定し、小数点としてCOMMAとFULLSTOPを使用するための一連の文化的規範。

Locale地理的ではありません。文化的規範を表す方法として国または地域を使用するLocale場合がありますが、それは文字通り、ユーザーが特定の地理的領域にいることを意味するものではありません。たとえば、日本の東京で開催された会議でケベックのエンジニアがのロケールを使用しますがLocale.CANADA_FRENCH、彼女のタイムゾーンはAsia/Tokyo旅行中のものである可能性があります。

ZoneId

タイムゾーン、は、特定の地域の人々が使用するUTCからZoneIdのオフセットに対する過去、現在、および将来の変更の履歴を表します。オフセットは、UTCで使用される本初子午線の前後の数時間-分-秒にすぎません。世界中の政治家は、タイムゾーンを頻繁に再定義し、管轄区域で使用されるオフセットを変更する傾向を示しています。実際、夏時間(DST)の愚かさを採用した地域では、オフセットが年に2回、約6か月ごとに変更されます。

➥つまり、特定のロケールから現在の時刻やタイムゾーンを取得することはできません。


ロケールを使用してカレンダーを作成すると、TimeZoneはローカルのカレンダーに戻ります。

JSR 310によって定義された最新のjava.timeクラスに取って代わられ、現在はレガシーであるひどい日時クラスを使用しています。

UTCで現在の瞬間(ゼロ時間-分-秒のオフセット)を取得するには、を使用しますInstant。定義上、 AnInstantは常にUTCです。

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

特定のタイムゾーンの現在の瞬間が必要な場合は、オブジェクトZoneIdを取得するようにを指定しZonedDateTimeます。

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Capture the current moment as seen in the wall-clock time used by the people of a particular region.

適用するタイムゾーンを知ることに関しては、上で述べたように、次のいずれかを行う必要があります。

  • デフォルトの(ZoneId.systemDefault)、または…</li> を使用します
  • ユーザーに確認してください。

を呼び出すと、既知のタイムゾーンのリストを取得できますZoneId.getAvailableZoneIds

Calendar c = new GregorianCalendar( locale ) ;

GregorianCalendarをとるこのコンストラクターによって混乱するかもしれませんLocale、そして当然のことながらそうです。

このコンストラクターは、従来の日時クラスに見られる多くの不適切で誤った設計上の決定の1つです。率直に言って、これらのレガシークラスは非常にひどいものであり、日時処理の複雑さと微妙さを理解していない人々によって設計されています。Sun、Oracle、およびJCPコミュニティは、正当な理由でそれらをjava.timeに置き換えることを決定しました。

Localeユーザーに表示する日時オブジェクトの値を表すテキストを生成する場合は、タイムゾーンと交差します。ALocaleは、月の名前、曜日の名前などの翻訳に使用する人間の言語を指定します。またLocale、月または曜日の省略(名前は大文字ですか?終止符が追加されていますか?)、日、月、年の順序付けなどの問題を決定するための文化的規範を指定します。

于 2019-12-27T06:49:22.203 に答える