SimpleDateFormatクラスを使用してJavaで日時をフォーマットし、日付の後に+0000を付けずに日付のタイムゾーン部分を指定することは可能ですか?.
編集
Java内のデフォルトのタイムゾーンを次のように変更します:
SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");
TimeZone.setDefault(tz);
残念ながら、私はこのコードを削除する立場にありません。システム全体が機能しなくなると推測するのは危険です。最初の作者は、いつか夏時間の問題を回避するためにこれを入れたと思います。
これを念頭に置いて、日付を次のようにフォーマットします。
2011-12-27 09:00 GMT
または
2011-12-27 09:00 BST
SimpleDateFormatを次のように出力することしかできません。
2011-12-27 09:00:00 GMT + 00:00
これはフォーマット文字列を使用しますyyyy-MM-dd HH:mm:ss z
単純なタイムゾーンが冬時間(GMT)IDまたは夏時間ID(BST)を参照している場所はどこにも見当たりません。
エレガントなソリューションではありませんが、それは私たちにとってはうまくいきます。 DateFormat/SimpleDateFormatのカスタム実装を作成する必要がありました。これは次のようになります。
static {
// this would be initialized like something as follows when the application starts
// which causes the headaches of SimpleDateFormat not to work...
SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");
TimeZone.setDefault(tz);
}
// therefore this class will workaround the issue,
public class OurOwnCustomDateFormat
extends SimpleDateFormat {
/** The pattern to use as the format string. */
protected String pattern;
public OurOwnCustomDateFormat(String pattern) {
super(pattern);
// store the pattern
this.pattern = pattern;
}
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
// custom implementation to format the date and time based on our TimeZone
toAppendTo.insert(pos.getBeginIndex(), "the date with our custom format calculated here");
return toAppendTo;
}
この質問と回答は現在時代遅れです。それらは、Java 8以降に組み込まれたJava.timeフレームワークによって時代遅れになった古い日時クラスを使用します。古いクラスは、設計が不十分で、混乱し、面倒です;それらを避けてください。
BST
などの3〜4文字のコードは避けてください。それらは標準化されておらず、一意でもありません。これらは実際にはタイムゾーンを表すものではありません。また、夏時間(DST)の問題にさらに混乱が生じます。
代わりに、 適切なタイムゾーン を使用してください。ほとんどは、 continent/region
などのEurope/London
形式です。
Java.util.TimeZone.setDefault
の呼び出しは、最も極端な場合にのみ実行する必要があります。この呼び出しは、JVM内のすべてのアプリのすべてのスレッドで実行されているすべてのコードにすぐに影響しますduringランタイム。
代わりに、すべての日時コードで、目的の/予想されるタイムゾーンを指定します。省略した場合、Javaは、JVMの現在のデフォルトのタイムゾーンに暗黙的に依存することでフォールバックします。上記のように、このデフォルトは実行時にいつでも変更できます!代わりに、明示的に指定してください。定期的に渡される引数として期待されるタイムゾーンの場合、現在のデフォルトのタイムゾーンは意味がなく、無関係です。
Java.timeフレームワークはJava 8以降に組み込まれています。 チュートリアル を参照してください。JSR310によって定義されています。非常に成功したJoda-Timeライブラリに触発されています。
Instant
Instant
は、UTCのタイムライン上の瞬間です。
次の例は、Java.timeクラスが、標準の ISO 8601 形式で、解析パターンを指定する必要がない場合に、デフォルトで文字列を解析/生成する方法を示しています。 DateTimeFormatter
クラスを使用して、他の非標準パターンを指定します。
Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );
ZonedDateTime
必要に応じてタイムゾーンを適用し、 ZonedDateTime
を生成します。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
DateTimeFormatter
を使用して、ZonedDateTimeオブジェクトのテキスト表現を作成できます。カスタムパターンを指定できます。または、私がお勧めするように、Java.timeをローカライズさせてください。
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );
タイムゾーンと同じ理由で、目的/期待値を指定するのが最適です Locale
JVMの現在のデフォルトは、内で実行されているアプリの任意のスレッドの任意のコードによっていつでも変更できます。 JVM。 Locale
は、(a)日と月の名前に使用される人間の言語、および(b)コンマとピリオドなどの文化的規範、および月、日、年などの部分の順序を決定します。
formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );
Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは厄介な古いクラスに取って代わります- legacy 日時クラス Java.util.Date
、 Calendar
、& SimpleDateFormat
。
Joda-Time プロジェクトは、現在 メンテナンスモード であり、 Java.timeへの移行をアドバイスします。 クラス。
詳細については、 Oracle Tutorial を参照してください。そして、StackOverflowで多くの例と説明を検索してください。仕様は JSR 31 です。
Java.timeオブジェクトをデータベースと直接交換できます。 JDBC driverJDBC 4.2 以降に準拠しています。文字列やJava.sql.*
クラスは必要ありません。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある試験場です。 Interval
、 YearWeek
、 YearQuarter
などの便利なクラスがここにあります。 、および more 。
要件に合った正しいパターンを使用していると思いますが、JDKはタイムゾーンの名前を認識していないため、代わりに GMTオフセット値 を使用するように切り替えます。
パターンを使用して日付をフォーマットすると、タイムゾーン部分に「GMT」が表示されます。
TimeZone.getDefault().getDisplayName()
はあなたに何を与えますか?私の場合、「グリニッジ標準時」を取得します。
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new Date()));
は2011-11-22 13:42:16 GMT
を返すだけなので、希望どおりに機能しているように見えます。他の場所で問題が発生しているようですが、独自のフォーマッタクラスを作成する必要はありません。
この問題を自分のコンピューターで再現できないためです。これはローカリゼーションに関係していると思います。これを試して
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z",Locale.US).format(new Date()));
お役に立てれば。