Java - Convertir la date et l'heure entre les fuseaux horaires
Dans ce tutoriel, nous allons vous montrer quelques exemples (ZonedDateTime (Java 8),Date,Calendar etJoda Time) pour convertir une date et une heure entre différents fuseaux horaires.
Tous les exemples convertiront la date et l'heure de
(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?
Pour le fuseau horaire, évitez à la foisDate
etCalendar
-
Si vous utilisez JDK> = 8, utilisez le nouveau framework
java.time.*
. -
Si vous utilisez JDK <8, utilisez Joda Time. (Le nouveau framework Java 8
java.time.*
est inspiré de cette bibliothèque)
1. ZonedDateTime
Utilisez toujours ce nouveau Java 8java.time.ZonedDateTime
pour représenter une date et une heure contenant un fuseau horaire.
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)); } }
Sortie
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
Reportez-vous à ceZonedDateTime
tutorial pour plus d'exemples de fuseau horaire, de décalage personnalisé et d'heure d'été (DST).
2. Date
Note
Lejava.util.Date
n'a pas de concept de fuseau horaire, et ne représente que le nombre de secondes écoulées depuis l'époque Unix - 1970-01-01T00: 00: 00Z. Mais, si vous imprimez l'objet Date directement, l'objet Date sera toujours imprimé avec le fuseau horaire système par défaut. Vérifiez le code source deDate.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)); } }
Sortie
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. Calendrier
3.1 A Calendar example to set a time zone :
Calendar calendar = new GregorianCalendar(); calendar.setTime(date); calendar.setTimeZone(tzInAmerica);
Une erreur très courante est d'obtenir lesjava.util.Date
directement comme ceci:
//Wrong, it will display 22-1-2015 10:15:55 AM, time is still in the system default time zone! Date dateInAmerican = calendar.getTime());
Dans l'exemple ci-dessus, quel que soit le fuseau horaire que vous définissez dans le calendrier, l'objet Date sera toujours imprimé avec le fuseau horaire système par défaut. (Vérifiez le code source deDate.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())
ou obtenez la date viacalendar.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); } }
Sortie
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. Joda Time
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);
Encore une fois, une erreur courante est d'obtenir la date directement comme ceci, le fuseau horaire sera perdu.
//Output : 22-1-2015 10:15:55 AM Date dateInAmerica = dtus.toDate();
La méthode correcte est d'abord convertie en 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); } }
Sortie
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