Java - Datum und Uhrzeit zwischen Zeitzone konvertieren

Java - Konvertiert Datum und Uhrzeit zwischen Zeitzone

timezone

In diesem Tutorial zeigen wir Ihnen einige Beispiele (ZonedDateTime (Java 8),Date,Calendar undJoda Time) zum Konvertieren von Datum und Uhrzeit zwischen verschiedenen Zeitzonen.

In allen Beispielen werden Datum und Uhrzeit von konvertiert

(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?
Vermeiden Sie für die Zeitzone sowohlDate als auchCalendar

  1. Wenn Sie JDK> = 8 verwenden, verwenden Sie das neue Frameworkjava.time.*.

  2. Wenn Sie JDK <8 verwenden, verwenden Sie Joda Time. (Das neue Java 8java.time.*Framework ist von dieser Bibliothek inspiriert.)

1. ZonedDateTime

Verwenden Sie immer diese neuen Java 8java.time.ZonedDateTime, um ein Datum und eine Uhrzeit mit Zeitzone darzustellen.

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));

    }

}

Ausgabe

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
Weitere Beispiele für Zeitzone, benutzerdefinierten Versatz und Sommerzeit (DST) finden Sie inZonedDateTime tutorial.

2. Date

Note
java.util.Date hat kein Konzept der Zeitzone und repräsentiert nur die Anzahl der Sekunden, die seit der Unix-Epoche vergangen sind - 1970-01-01T00: 00: 00Z. Wenn Sie das Datumsobjekt jedoch direkt drucken, wird das Datumsobjekt immer mit der Standardsystemzeitzone gedruckt. Überprüfen Sie den Quellcode vonDate.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));

    }

}

Ausgabe

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. Kalender

3.1 A Calendar example to set a time zone :

    Calendar calendar = new GregorianCalendar();
    calendar.setTime(date);
    calendar.setTimeZone(tzInAmerica);

Ein sehr häufiger Fehler ist, diejava.util.Date direkt so zu erhalten:

    //Wrong, it will display 22-1-2015 10:15:55 AM, time is still in the system default time zone!
    Date dateInAmerican = calendar.getTime());

Im obigen Beispiel wird das Datumsobjekt unabhängig von der im Kalender festgelegten Zeitzone immer mit der Standardsystemzeitzone gedruckt. (Überprüfen Sie den Quellcode vonDate.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())

oder erhalte das Datum übercalendar.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);

    }

}

Ausgabe

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 Zeit

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);

Wiederum ist es ein häufiger Fehler, das Datum direkt so abzurufen. Die Zeitzone geht verloren.

    //Output : 22-1-2015 10:15:55 AM
    Date dateInAmerica = dtus.toDate();

Der richtige Weg wird zuerst in JodaLocalDateTime konvertiert.

    //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);

    }

}

Ausgabe

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