日付文字列があり、それをJava Date APIを使用して通常の日付に解析したいのですが、以下が私のコードです:
public static void main(String[] args) {
String date="2010-10-02T12:23:23Z";
String pattern="yyyy-MM-ddThh:mm:ssZ";
SimpleDateFormat sdf=new SimpleDateFormat(pattern);
try {
Date d=sdf.parse(date);
System.out.println(d.getYear());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ただし、例外が発生しました:Java.lang.IllegalArgumentException: Illegal pattern character 'T'
だから、文字列を分割して手動で解析する必要があるのだろうか?
ところで、私はTの両側に一重引用符を追加しようとしました:
String pattern="yyyy-MM-dd'T'hh:mm:ssZ";
また、機能しません。
Javaの最新バージョンでは、壊れたJava.util.Date
の代わりにInstant
を使用する必要があるため、今すぐInstant.parse("2015-04-28T14:23:38.521Z")
を実行して正しいことを取得できます。
DateTimeFormatter
の代わりにSimpleDateFormatter
も使用する必要があります。
以下の説明は、形式が表すものとして引き続き有効です。しかし、それはJava 8が遍在する前に書かれたため、Java 8以上を使用している場合は使用すべきではない古いクラスを使用します。
Z
を持つ入力で機能します。パターンでは、
T
は、両側に'
でエスケープされます。末尾の
Z
のパターンは、XXX
のJavaDocに記載されているように、実際はSimpleDateFormat
ですが、Z
は古いTimeZone
情報のマーカーも同様です。
import Java.text.SimpleDateFormat;
import Java.util.Calendar;
import Java.util.Date;
import Java.util.GregorianCalendar;
import Java.util.TimeZone;
public class Q2597083
{
/**
* All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone.
*/
public static final TimeZone UTC;
/**
* @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">Combined Date and Time Representations</a>
*/
public static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
/**
* 0001-01-01T00:00:00.000Z
*/
public static final Date BEGINNING_OF_TIME;
/**
* 292278994-08-17T07:12:55.807Z
*/
public static final Date END_OF_TIME;
static
{
UTC = TimeZone.getTimeZone("UTC");
TimeZone.setDefault(UTC);
final Calendar c = new GregorianCalendar(UTC);
c.set(1, 0, 1, 0, 0, 0);
c.set(Calendar.MILLISECOND, 0);
BEGINNING_OF_TIME = c.getTime();
c.setTime(new Date(Long.MAX_VALUE));
END_OF_TIME = c.getTime();
}
public static void main(String[] args) throws Exception
{
final SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT);
sdf.setTimeZone(UTC);
System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME));
System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME));
System.out.println("sdf.format(new Date()) = " + sdf.format(new Date()));
System.out.println("sdf.parse(\"2015-04-28T14:23:38.521Z\") = " + sdf.parse("2015-04-28T14:23:38.521Z"));
System.out.println("sdf.parse(\"0001-01-01T00:00:00.000Z\") = " + sdf.parse("0001-01-01T00:00:00.000Z"));
System.out.println("sdf.parse(\"292278994-08-17T07:12:55.807Z\") = " + sdf.parse("292278994-08-17T07:12:55.807Z"));
}
}
sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z
sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z
sdf.format(new Date()) = 2015-04-28T14:38:25.956Z
sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 28 14:23:38 UTC 2015
sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 01 00:00:00 UTC 1
sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 17 07:12:55 UTC 292278994
Instant.parse( "2010-10-02T12:23:23Z" )
この形式は、日時文字列形式の ISO 8601 標準で定義されています。
両方:
…文字列の解析と生成には、デフォルトでISO 8601形式を使用します。
通常、古いJava.util.Date/。CalendarおよびJava.text.SimpleDateFormatクラスを使用することは避けてください。これらのクラスは、面倒で混乱を招き、欠陥があることで有名です。相互運用に必要な場合は、前後に変換できます。
Java 8以降には、新しい Java.time フレームワークが組み込まれています。 JSR-31 によって定義され、 ThreeTen-Extra プロジェクトによって拡張された Joda-Time に触発されました。
Instant instant = Instant.parse( "2010-10-02T12:23:23Z" ); // `Instant` is always in UTC.
古いクラスに変換します。
Java.util.Date date = Java.util.Date.from( instant ); // Pass an `Instant` to the `from` method.
タイムゾーン
必要に応じて、タイムゾーンを割り当てることができます。
ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Define a time zone rather than rely implicitly on JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); // Assign a time zone adjustment from UTC.
変換します。
Java.util.Date date = Java.util.Date.from( zdt.toInstant() ); // Extract an `Instant` from the `ZonedDateTime` to pass to the `from` method.
更新:Joda-Timeプロジェクトは現在、メンテナンスモードになっています。チームは、Java.timeクラスへの移行を推奨しています。
Joda-Time 2.8のサンプルコードを次に示します。
org.joda.time.DateTime dateTime_Utc = new DateTime( "2010-10-02T12:23:23Z" , DateTimeZone.UTC ); // Specifying a time zone to apply, rather than implicitly assigning the JVM’s current default.
古いクラスに変換します。 j.u.Dateにタイムゾーンを割り当てることはできないため、割り当てられたタイムゾーンは変換で失われることに注意してください。
Java.util.Date date = dateTime_Utc.toDate(); // The `toDate` method converts to old class.
タイムゾーン
必要に応じて、タイムゾーンを割り当てることができます。
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime_Montreal = dateTime_Utc.withZone ( zone );
Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、 Java.util.Date
、 Calendar
、および SimpleDateFormat
などの厄介な古い レガシー 日時クラスに取って代わります。
メンテナンスモード になった Joda-Time プロジェクトは、 Java.time クラスへの移行を推奨しています。
詳細については、 Oracle Tutorial を参照してください。また、Stack Overflowで多くの例と説明を検索してください。仕様は JSR 31 です。
Java.timeオブジェクトをデータベースと直接交換できます。 JDBC 4.2 以降に準拠する JDBCドライバー を使用します。文字列やJava.sql.*
クラスは必要ありません。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、Java.timeを追加のクラスで拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。ここでは、 Interval
、 YearWeek
、 YearQuarter
、および more 。