Java –タイムゾーン間の日付と時刻の変換

このチュートリアルでは、異なるタイムゾーン間で日付と時刻を変換するためのいくつかの例(ZonedDateTime (Java 8)、Date、Calendar、およびJoda Time)を示します。
すべての例は、日付と時刻を変換します
(UTC+8:00) Asia/Singapore - Singapore Time Date : 22-1-2015 10:15:55 AM
to
(UTC-5:00) America/New_York - Eastern Standard Time Date : 21-1-2015 09:15:55 PM
Which to use?
タイムゾーンでは、DateとCalendarの両方を避けてください
-
JDK> = 8を使用している場合は、新しい
java.time.*フレームワークを使用してください。 -
JDK <8を使用している場合は、Joda Timeを使用します。 (新しいJava 8
java.time.*フレームワークは、このライブラリに触発されています)
1. ZonedDateTime
この新しいJava8java.time.ZonedDateTimeを常に使用して、タイムゾーンを含む日付と時刻を表します。
ZonedDateTimeExample.java
package com.example.date;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class ZonedDateTimeExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) {
String dateInString = "22-1-2015 10:15:55 AM";
LocalDateTime ldt = LocalDateTime.parse(dateInString, DateTimeFormatter.ofPattern(DATE_FORMAT));
ZoneId singaporeZoneId = ZoneId.of("Asia/Singapore");
System.out.println("TimeZone : " + singaporeZoneId);
//LocalDateTime + ZoneId = ZonedDateTime
ZonedDateTime asiaZonedDateTime = ldt.atZone(singaporeZoneId);
System.out.println("Date (Singapore) : " + asiaZonedDateTime);
ZoneId newYokZoneId = ZoneId.of("America/New_York");
System.out.println("TimeZone : " + newYokZoneId);
ZonedDateTime nyDateTime = asiaZonedDateTime.withZoneSameInstant(newYokZoneId);
System.out.println("Date (New York) : " + nyDateTime);
DateTimeFormatter format = DateTimeFormatter.ofPattern(DATE_FORMAT);
System.out.println("\n---DateTimeFormatter---");
System.out.println("Date (Singapore) : " + format.format(asiaZonedDateTime));
System.out.println("Date (New York) : " + format.format(nyDateTime));
}
}
出力
TimeZone : Asia/Singapore Date (Singapore) : 2015-01-22T10:15:55+08:00[Asia/Singapore] TimeZone : America/New_York Date (New York) : 2015-01-21T21:15:55-05:00[America/New_York] ---DateTimeFormatter--- Date (Singapore) : 22-1-2015 10:15:55 AM Date (New York) : 21-1-2015 09:15:55 PM
Note
タイムゾーン、カスタムオフセット、夏時間(DST)の例については、このZonedDateTime
tutorialを参照してください。
2. Date
Notejava.util.Dateにはタイムゾーンの概念がなく、Unixエポックタイム– 1970-01-01T00:00:00Zから経過した秒数のみを表します。 ただし、Dateオブジェクトを直接印刷する場合、Dateオブジェクトは常にデフォルトのシステムタイムゾーンで印刷されます。 Date.toString()のソースコードを確認してください。
2.1 Set a time zone to DateFormat and format the java.util.Date
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
sdfAmerica.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String sDateInAmerica = sdfAmerica.format(date);
2.2 Full example
DateExample.java
package com.example.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class DateExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
TimeZone tz = TimeZone.getDefault();
// From TimeZone Asia/Singapore
System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
System.out.println("TimeZone : " + tz);
System.out.println("Date (Singapore) : " + formatter.format(date));
// To TimeZone America/New_York
SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
sdfAmerica.setTimeZone(tzInAmerica);
String sDateInAmerica = sdfAmerica.format(date); // Convert to String first
Date dateInAmerica = formatter.parse(sDateInAmerica); // Create a new Date object
System.out.println("\nTimeZone : " + tzInAmerica.getID() + " - " + tzInAmerica.getDisplayName());
System.out.println("TimeZone : " + tzInAmerica);
System.out.println("Date (New York) (String) : " + sDateInAmerica);
System.out.println("Date (New York) (Object) : " + formatter.format(dateInAmerica));
}
}
出力
TimeZone : Asia/Kuala_Lumpur - Malaysia Time TimeZone : sun.util.calendar.ZoneInfo[id="Asia/Kuala_Lumpur",...] Date (Singapore) : 22-1-2015 10:15:55 AM TimeZone : America/New_York - Eastern Standard Time TimeZone : sun.util.calendar.ZoneInfo[id="America/New_York",...] Date (New York) (String) : 21-1-2015 09:15:55 PM Date (New York) (Object) : 21-1-2015 09:15:55 PM
3. カレンダー
3.1 A Calendar example to set a time zone :
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
calendar.setTimeZone(tzInAmerica);
よくある間違いは、java.util.Dateを次のように直接取得することです。
//Wrong, it will display 22-1-2015 10:15:55 AM, time is still in the system default time zone!
Date dateInAmerican = calendar.getTime());
上記の例では、カレンダーにどのタイムゾーンを設定しても、Dateオブジェクトは常にデフォルトのシステムタイムゾーンで印刷されます。 (Date.toString()のソースコードを確認してください)
3.2 The correct way should be using the DateFormat to format it :
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
sdfAmerica.setTimeZone(tzInAmerica);
sdfAmerica.format(calendar.getTime())
またはcalendar.get()を介して日付を取得します:
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH); // Jan = 0, dec = 11
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR); // 12 hour clock
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 24 hour clock
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int ampm = calendar.get(Calendar.AM_PM); //0 = AM , 1 = PM
3.3 Full example
CalendarExample.java
package com.example.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class CalendarExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
TimeZone tz = TimeZone.getDefault();
// From TimeZone Asia/Singapore
System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
System.out.println("TimeZone : " + tz);
System.out.println("Date (Singapore) : " + formatter.format(date));
// To TimeZone America/New_York
SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
sdfAmerica.setTimeZone(tzInAmerica);
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
calendar.setTimeZone(tzInAmerica);
System.out.println("\nTimeZone : " + tzInAmerica.getID() + " - " + tzInAmerica.getDisplayName());
System.out.println("TimeZone : " + tzInAmerica);
//Wrong! It will print the date with the system default time zone
System.out.println("Date (New York) (Wrong!): " + calendar.getTime());
//Correct! need formatter
System.out.println("Date (New York) (Correct!) : " + sdfAmerica.format(calendar.getTime()));
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH); // Jan = 0, dec = 11
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR); // 12 hour clock
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 24 hour clock
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int ampm = calendar.get(Calendar.AM_PM); //0 = AM , 1 = PM
//Correct
System.out.println("\nyear \t\t: " + year);
System.out.println("month \t\t: " + month + 1);
System.out.println("dayOfMonth \t: " + dayOfMonth);
System.out.println("hour \t\t: " + hour);
System.out.println("minute \t\t: " + minute);
System.out.println("second \t\t: " + second);
System.out.println("ampm \t\t: " + ampm);
}
}
出力
TimeZone : Asia/Kuala_Lumpur - Malaysia Time TimeZone : sun.util.calendar.ZoneInfo[id="Asia/Kuala_Lumpur",...] Date (Singapore) : 22-1-2015 10:15:55 AM TimeZone : America/New_York - Eastern Standard Time TimeZone : sun.util.calendar.ZoneInfo[id="America/New_York",...]] Date (New York) (Wrong!): Thu Jan 22 10:15:55 MYT 2015 Date (New York) (Correct!) : 21-1-2015 09:15:55 PM year : 2015 month : 01 dayOfMonth : 21 hour : 9 minute : 15 second : 55 ampm : 1
4. ジョーダ時間
4.1 A Joda Time example to set a time zone :
DateTime dt = new DateTime(date);
DateTimeZone dtZone = DateTimeZone.forID("America/New_York");
DateTime dtus = dt.withZone(dtZone);
繰り返しますが、よくある間違いは、このように日付を直接取得することです。タイムゾーンは失われます。
//Output : 22-1-2015 10:15:55 AM
Date dateInAmerica = dtus.toDate();
正しい方法は、最初にJodaLocalDateTimeに変換されます。
//Output : 21-1-2015 09:15:55 PM
Date dateInAmerica = dtus.toLocalDateTime().toDate();
4.2 Full example
JodaTimeExample.java
package com.example.date;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class JodaTimeExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
TimeZone tz = TimeZone.getDefault();
// From TimeZone Asia/Singapore
System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
System.out.println("TimeZone : " + tz);
System.out.println("Date (Singapore) : " + formatter.format(date));
// To TimeZone America/New_York
SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
DateTime dt = new DateTime(date);
DateTimeZone dtZone = DateTimeZone.forID("America/New_York");
DateTime dtus = dt.withZone(dtZone);
TimeZone tzInAmerica = dtZone.toTimeZone();
Date dateInAmerica = dtus.toLocalDateTime().toDate(); //Convert to LocalDateTime first
sdfAmerica.setTimeZone(tzInAmerica);
System.out.println("\nTimeZone : " + tzInAmerica.getID() + " - " + tzInAmerica.getDisplayName());
System.out.println("TimeZone : " + tzInAmerica);
System.out.println("DateTimeZone : " + dtZone);
System.out.println("DateTime : " + dtus);
System.out.println("dateInAmerica (Formatter) : " + formatter.format(dateInAmerica));
System.out.println("dateInAmerica (Object) : " + dateInAmerica);
}
}
出力
TimeZone : Asia/Kuala_Lumpur - Malaysia Time TimeZone : sun.util.calendar.ZoneInfo[id="Asia/Kuala_Lumpur",...] Date (Singapore) : 22-1-2015 10:15:55 AM TimeZone : America/New_York - Eastern Standard Time TimeZone : sun.util.calendar.ZoneInfo[id="America/New_York",...] DateTimeZone : America/New_York DateTime : 2015-01-21T21:15:55.000-05:00 dateInAmerica (Formatter) : 21-1-2015 09:15:55 PM dateInAmerica (Object) : Wed Jan 21 21:15:55 MYT 2015
P.S Tested with Joda-time 2.9.4