Java 1.7。
変換しようとしています:
2018-05-23T23:18:31.000Z
に
2018-05-23 23:18:31
DateUtilsクラス:
public class DateUtils {
public static String convertToNewFormat(String dateStr) throws ParseException {
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
sdf.setTimeZone(utc);
Date convertedDate = sdf.parse(dateStr);
return convertedDate.toString();
}
}
それを使用しようとするとき:
String convertedDate = DateUtils.convertToNewFormat("2018-05-23T23:18:31.000Z");
System.out.println(convertedDate);
次の例外を取得します。
Exception in thread "main" Java.text.ParseException: Unparseable date: "2018-05-23T23:22:16.000Z"
at Java.text.DateFormat.parse(DateFormat.Java:366)
at com.myapp.utils.DateUtils.convertToNewFormat(DateUtils.Java:7)
何が間違っているのでしょうか?
より簡単な方法はありますか(Apache Commons libなど)?
これを試して。解析には1つのパターンを使用し、フォーマットには別のパターンを使用する必要があります。
public static String convertToNewFormat(String dateStr) throws ParseException {
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sourceFormat.setTimeZone(utc);
Date convertedDate = sourceFormat.parse(dateStr);
return destFormat.format(convertedDate);
}
Instant.parse( "2018-05-23T23:18:31.000Z" ) // Parse this String in standard ISO 8601 format as a `Instant`, a point on the timeline in UTC. The `Z` means UTC.
.atOffset( ZoneOffset.UTC ) // Change from `Instant` to the more flexible `OffsetDateTime`.
.format( // Generate a String representing the value of this `OffsetDateTime` object.
DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) // Specify a formatting pattern as desired.
) // Returns a `String` object.
2018-05-23 23:18:31
入力文字列は、標準の ISO 8601 形式です。
Java.timeクラスは、文字列の解析/生成時にデフォルトでこれらの標準形式を使用します。
T
は、年月日部分を時分秒から分離します。 Z
はZulu
と発音され、 [〜#〜] utc [〜#〜] を意味します。
Java.timeクラスによって何年も前に取って代わられた厄介な古い日時クラスを使用しています。 Apache DateUtils
も不要になりました。その機能はJava.timeにもあります。
入力文字列をInstant
オブジェクトとして解析します。 Instant
クラスは、 [〜#〜] utc [〜#〜] でタイムライン上の瞬間を表し、 ナノ秒 (小数の最大9桁)の分解能で)。
String input = "2018-05-23T23:18:31.000Z" ;
Instant instant = Instant.parse( input ) ;
別の形式で文字列を生成するには、より柔軟なオブジェクトが必要です。 Instant
クラスは、基本的なビルディングブロックであることを意図しています。 Lets convert it to a
OffsetDateTime`、UTC自体を指定されたUTCからのオフセットとして使用。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
目的の出力に一致するようにフォーマットパターンを定義します。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) ;
String output = odt.format( f ) ;
ヒント:DateTimeFormatter::ofLocalized…
メソッドを使用して、フォーマットパターンをハードコーディングするのではなく、Locale
ごとに文字列生成を自動的にローカライズすることを検討してください。
Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは、 Java.util.Date
、 Calendar
、& SimpleDateFormat
などの厄介な古い レガシー 日時クラスに取って代わります。
Joda-Time プロジェクトが メンテナンスモード になり、 Java.time クラスへの移行を推奨しています。
詳細については、 Oracleチュートリアル を参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様は JSR 31 です。
Java.timeオブジェクトをデータベースと直接交換できます。 JDBC 4.2 以降に準拠した JDBCドライバー を使用してください。文字列も、Java.sql.*
クラスも必要ありません。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明する場です。 Interval
、 YearWeek
、 YearQuarter
、 more などの便利なクラスがここにあります。
Java 1.7制限のない他の人:
Java 1.8なので、パッケージのLocalDateTime
とZonedDateTime
を使用してこれを行うことができます_Java.time
_
_public static void main(String[] args) {
String sourceDateTime = "2018-05-23T23:18:31.000Z";
DateTimeFormatter sourceFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(sourceDateTime, sourceFormat);
String formatedDateTime = dateTime.atZone(ZoneId.of("UTC")).format(targetFormat);
System.out.println(formatedDateTime);
}
_
編集:(コメントを参照)
Oracleからの引用Java LocalDateTime のドキュメント):
LocalDateTimeは、日時を表す不変の日時オブジェクトで、多くの場合、年、月、日、時、分、秒と表示されます。日、週、週などのその他の日付と時刻フィールドにもアクセスできます。時間はナノ秒の精度で表されます。たとえば、値「2007年10月2日13:45.30.123456789」はLocalDateTimeに格納できます。
このクラスは、タイムゾーンを格納または表しません。代わりに、誕生日に使用される日付の説明と、壁掛け時計に表示される現地時間を組み合わせたものです。オフセットやタイムゾーンなどの追加情報がないと、タイムライン上のインスタントを表すことはできません。
oPは入力文字列を日付時刻(年月日日時分秒)に解析するように要求し、ドキュメントには
LocalDateTime ...は日時を表し、多くの場合、年、月、日、時、分、秒と表示されます。
ここでは重要な情報が失われることはありません。そしてdateTime.atZone(ZoneId.of("UTC"))
はZonedDateTime
を返すので、ユーザーがタイムゾーンなどで作業する必要がある場合は、この時点でZimeZoneが再び処理されます。
そのため、回答で提示する「唯一無二の」ソリューションをユーザーに使用させようとしないでください。
KotlinでThreeTenABPを使用すると、
fun getIsoString(year: Int, month: Int, day: Int): String {
val localTime = ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of("Z"))
val utcTime = localTime.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC)
val isoString = utcTime.toInstant().toString() // 1940-15-12T00:00:00Z
val formattedIsoString = val formattedIsoString =
Instant.parse(isoString)
.atOffset(ZoneOffset.UTC)
.format(DateTimeFormatter
.ofPattern("uuuu-MM-dd'T'HH:mm:ss")) // 'T' in quotes so that it is retained.
return formattedIsoString
}
// print it
print(getIsoString(1940, 15, 12)) // 1940-15-12T00:00:00
YYYY
は年の部分と一致しません。 Java 7では、yyyy
が必要です。
T
の場合、'T'
を使用して一致させます
また、ミリ秒部分の派閥がありません:.SSS
これを試して:
String dateStr="2018-05-23T23:18:31.000Z";
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(utc);
Date convertedDate = sdf.parse(dateStr);
convertedDate.toString();