Wie kann ich das aktuelle Datum und die aktuelle Uhrzeit in UTC oder GMT in Java abrufen?


479

Wenn ich ein neues DateObjekt erstelle , wird es auf die aktuelle Zeit initialisiert, jedoch in der lokalen Zeitzone. Wie kann ich das aktuelle Datum und die aktuelle Uhrzeit in GMT abrufen?


Ich weiß, dass diese Art von Themen völlig überdiskutiert sind, aber ich fand, dass das commons-lang-Paket diese häufigen Java-Probleme wirklich gut behandelt. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Schauen Sie sich die verschiedenen Pakete an, die sie haben.

Welche Ortszeit möchten Sie und mit welcher Präzision. Die meisten Zeitzonen sind relativ zu UTC mit einem festen Versatz in SI- Sekunden definiert, aber die Beziehung zwischen GMT, die auf Sonnenbeobachtung und einer (leicht) variablen Sekunde basiert, ist komplexer. Die beiden unterscheiden sich um bis zu 0,9 Sekunden.
mc0e

1
A Datehat keine Zeitzone, daher ist "aber in der lokalen Zeitzone" nicht korrekt (oder bestenfalls ungenau). Siehe Alles über java.util.Date .
Ole VV

Antworten:


409

java.util.Datehat keine bestimmte Zeitzone, obwohl sein Wert am häufigsten in Bezug auf UTC angenommen wird. Was lässt Sie denken, dass es in der Ortszeit ist?

Um genau zu sein: Der Wert innerhalb von a java.util.Dateist die Anzahl der Millisekunden seit der Unix-Epoche, die am 1. Januar 1970 um Mitternacht UTC stattfand. Dieselbe Epoche könnte auch in anderen Zeitzonen beschrieben werden, aber die traditionelle Beschreibung bezieht sich auf UTC. Da es eine Anzahl von Millisekunden seit einer festen Epoche ist, ist der Wert innerhalbjava.util.Date zu jedem Zeitpunkt weltweit gleich, unabhängig von der lokalen Zeitzone.

Ich vermute, das Problem ist, dass Sie es über eine Instanz des Kalenders anzeigen, die die lokale Zeitzone verwendet, oder möglicherweise über Date.toString()die lokale Zeitzone, oder aSimpleDateFormat Instanz, die standardmäßig auch die lokale Zeitzone verwendet.

Wenn dies nicht das Problem ist, geben Sie bitte einen Beispielcode ein.

Ich würde jedoch empfehlen, trotzdem Joda-Time zu verwenden, das eine viel klarere API bietet.


5
Dann ist das wahrscheinlich ein Treiberproblem. Möglicherweise müssen Sie Ihre Verbindung auf UTC oder ähnliches einstellen. Ich habe solche Probleme schon einmal gesehen, aber das Problem liegt nicht in java.util.Date.
Jon Skeet

13
Behrang, laut stackoverflow.com/questions/4123534/… , konvertiert der MySQL JDBC-Treiber ein bestimmtes java.util.Timestamp(oder java.util.Date) in die Server-Zeitzone.
Derek Mahar

5
@Herr. Katze: Wie bestimmen Sie das? Ist es durch Schreiben System.out.println(new Date())? Wenn ja, sollten Sie sich bewusst sein, dass es die toString()Methode ist, die die Zeitzone dort anwendet. Wenn dies nicht der Fall ist, geben Sie bitte weitere Details an.
Jon Skeet

8
@KanagaveluSugumar: Verwendet toString()immer die Standardzeitzone. date.getTime()Gibt definitiv Millisekunden seit der Unix-Epoche in UTC zurück. Es ist am genauesten zu sagen, dass es Dateselbst überhaupt keine Zeitzone gibt - es ist nur ein Augenblick, der in mehreren Zeitzonen betrachtet werden kann. Wenn Sie jedoch eine Instanz erstellen, hängt dies nicht von Ihrer Zeitzone ab.
Jon Skeet

6
@Jemenake: Eigentlich ist es nicht passiert, als es Mitternacht in Greenwich war, weil Großbritannien zu dieser Zeit auf UTC + 1 war. Nur eines der merkwürdigen Teile der Geschichte. Aber ich verstehe Ihren Standpunkt - es ist besser zu sagen "new Date (). GetTime () gibt die Millisekunden seit der Unix-Epoche zurück, die Anfang Januar 1970, UTC, Mitternacht war". Die UTC ist also Teil der Festlegung der Epoche auf einen bestimmten Zeitpunkt und nicht Teil des Ergebnisses.
Jon Skeet

324

tl; dr

Instant.now()   // Capture the current moment in UTC. 

Generieren Sie eine Zeichenfolge, um diesen Wert darzustellen:

Instant.now().toString()  

2016-09-13T23: 30: 52.123Z

Einzelheiten

Wie die richtige Antwort von Jon Skeet feststellte, hat ein java.util.Date-Objekt keine Zeitzone . Bei der toStringImplementierung wird jedoch die Standardzeitzone der JVM angewendet, wenn die Zeichenfolgendarstellung dieses Datums- / Uhrzeitwerts generiert wird. Für den naiven Programmierer verwirrend, scheint ein Datum eine Zeitzone zu haben, tut dies aber nicht.

Die java.util.Date, j.u.Calendarund java.text.SimpleDateFormatKlassen mit Java gebündelt sind notorisch schwierig. Vermeide sie. Verwenden Sie stattdessen eine dieser kompetenten Datums- / Uhrzeitbibliotheken:

java.time (Java 8)

Java 8 enthält ein hervorragendes neues Paket java.time. * , Das die alten Klassen java.util.Date/Calendar ersetzt.

Das Abrufen der aktuellen Zeit in UTC / GMT ist ein einfacher Einzeiler…

Instant instant = Instant.now();

Diese InstantKlasse ist der Grundbaustein in java.time und repräsentiert einen Moment auf der Zeitachse in UTC mit einer Auflösung von Nanosekunden .

In Java 8 wird der aktuelle Moment mit einer Auflösung von nur bis zu Millisekunden erfasst. Java 9 bietet eine neue Implementierung von ClockCaptures für den aktuellen Moment bis zur vollen Nanosekunden-Fähigkeit dieser Klasse, abhängig von der Fähigkeit der Clock-Hardware Ihres Host-Computers.

Die toStringMethode generiert eine String-Darstellung ihres Werts unter Verwendung eines bestimmten ISO 8601-Formats . Dieses Format gibt nach Bedarf null, drei, sechs oder neun Ziffern ( Millisekunden , Mikrosekunden oder Nanosekunden ) aus, um den Sekundenbruchteil darzustellen.

Wenn Sie eine flexiblere Formatierung oder andere zusätzliche Funktionen wünschen, wenden Sie einen Versatz von UTC von Null an, damit UTC selbst ( ZoneOffset.UTCkonstant ) a erhält OffsetDateTime.

OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );

Auf die Konsole werfen ...

System.out.println( "now.toString(): " + now );

Beim Laufen…

now.toString(): 2014-01-21T23:42:03.522Z

Tabelle der Datums- und Uhrzeittypen in Java, sowohl modern als auch alt.


Über java.time

Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für java.sql.*Klassen.

Woher bekomme ich die java.time-Klassen?

Tabelle, welche java.time-Bibliothek mit welcher Java- oder Android-Version verwendet werden soll

Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden Interval, YearWeek, YearQuarter, und mehr .


Joda-Zeit

UPDATE: Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

Mit der kostenlosen Open-Source-Bibliothek von Joda-Time von Drittanbietern können Sie die aktuelle Datums- und Uhrzeitangabe in nur einer Codezeile abrufen.

Joda-Time hat die neuen Klassen java.time. * In Java 8 inspiriert, hat aber eine andere Architektur. Sie können Joda-Time in älteren Java-Versionen verwenden. Joda-Time arbeitet weiterhin in Java 8 und wird weiterhin aktiv gewartet (Stand 2014). Das Joda-Time-Team empfiehlt jedoch die Migration zu java.time.

System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );

Detaillierterer Beispielcode (Joda-Time 2.3)…

org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );

Auf die Konsole werfen ...

System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );

Beim Laufen…

Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z

Weitere Beispiele für Code, der Zeitzonenarbeiten ausführt, finden Sie in meiner Antwort auf eine ähnliche Frage.

Zeitzone

Ich empfehle, immer eine Zeitzone anzugeben, anstatt sich implizit auf die aktuelle Standardzeitzone der JVM zu verlassen (die sich jederzeit ändern kann!). Ein solches Vertrauen scheint eine häufige Ursache für Verwirrung und Fehler bei der Arbeit mit Datum und Uhrzeit zu sein.

Wenn Sie anrufen, now()übergeben Sie die gewünschte / erwartete Zeitzone, die zugewiesen werden soll. Verwenden Sie die DateTimeZoneKlasse.

DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );

Diese Klasse hält eine Konstante für die UTC- Zeitzone.

DateTime now = DateTime.now( DateTimeZone.UTC );

Wenn Sie die aktuelle Standardzeitzone der JVM wirklich verwenden möchten, rufen Sie explizit auf, damit sich Ihr Code selbst dokumentiert.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

ISO 8601

Lesen Sie mehr über ISO 8601- Formate. Sowohl java.time als auch Joda-Time verwenden die sinnvollen Formate dieses Standards als Standard für das Parsen und Generieren von Zeichenfolgen.


Eigentlich java.util.Date hat eine Zeitzone hat, tief begraben unter Schichten von Quellcode. Für die meisten praktischen Zwecke wird diese Zeitzone ignoriert. Als Kurzform sagen wir also, dass java.util.Date keine Zeitzone hat. Darüber hinaus ist diese vergrabene Zeitzone nicht diejenige, die von der toStringMethode von Date verwendet wird. Diese Methode verwendet die aktuelle Standardzeitzone der JVM. Umso mehr Grund, diese verwirrende Klasse zu vermeiden und bei Joda-Time und java.time zu bleiben.


2
DateTime.now().toDateTime(DateTimeZone.UTC)war was ich suchte! Vielen Dank!
Managarm

1
@ Managarm Sie können das verkürzen auf: DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
Basil Bourque

Wie Sie dies mit Pure Java 8 2014-01-21T15:34:29.933-08:00in dem von Ihnen verwendeten Beispiel erreichennew org.joda.time.DateTime()
GOXR3PLUS

1
@ GOXR3PLUS ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() Wir erhalten den aktuellen Moment für eine bestimmte Zeitzone. Als nächstes entfernen Sie alle Mikros / Nanos. Dann konvertieren wir zu einem bloßen Versatz von UTC (Anzahl der Stunden-Minuten-Sekunden) anstatt zu einer vollständigen Zeitzone (eine Geschichte vergangener, gegenwärtiger und zukünftiger Änderungen des Versatzes, der von den Menschen von a verwendet wird bestimmte Region). Zuletzt generieren wir Text, der den Wert OffsetDateTimegemäß dem Standardformat ISO 8601 darstellt, das standardmäßig in seiner toStringMethode verwendet wird.
Basil Bourque

Vielen Dank für diese ausführliche Erklärung, auch +1 für die Android-Unterstützung :) @BasilBourque
mochadwi

271
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

//Local time zone   
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );

11
Warum analysieren Sie mit dateFormatLocal, nachdem Sie das dateFormatGmt-Format verwendet haben? Das Lesen macht keinen Sinn. Ich bin sicher, dass es funktioniert, aber ich frage mich nur?
MindWire

2
setTimeZone hat es geschafft (ich denke, Sie können getTimeZone ("UTC") auch wie GMT verwenden?)
rogerdpack

6
Die Zeit hängt jedoch von der eingestellten Zeit des Geräts ab. Wenn der Benutzer auf seinem Gerät eine falsche Zeit eingestellt hat, erhalten Sie eine falsche UTC. Korrigieren Sie mich, wenn ich falsch
liege

@ BasavarajHampali, aber in der heutigen Welt sind die meisten Geräte mit dem Internet verbunden, was die falsche Zeit korrigiert
Akshat Agarwal

3
Es gibt keinen Zeitunterschied zwischen der koordinierten Weltzeit (UTC) und der Greenwich Mean Time (GMT)
Slott

86

Dies gibt definitiv die UTC-Zeit zurück: als String- und Date-Objekte!

static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

public static Date getUTCdatetimeAsDate() {
    // note: doesn't check for null
    return stringDateToDate(getUTCdatetimeAsString());
}

public static String getUTCdatetimeAsString() {
    final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    final String utcTime = sdf.format(new Date());

    return utcTime;
}

public static Date stringDateToDate(String StrDate) {
    Date dateToReturn = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);

    try {
        dateToReturn = (Date)dateFormat.parse(StrDate);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return dateToReturn;
}

In meiner Antwort habe ich vergessen zu zeigen, wie DATEFORMAT definiert ist: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Jemand irgendwo

21
Bitte vermeiden Sie es, Methodennamen in Java in Großbuchstaben zu beginnen. Methodennamen finden Sie in den Java-Codierungskonventionen .
Florian Schrofner

2
Wenn ich auf diese Antwort umgeleitet new Date()werde , gibt Calling niemals die richtige UTC-Zeit zurück, wenn die Gerätezeit falsch ist.
Sanoop

Hängt diese Methode die Zeit vom Gerätekalender ab?
Arnold Brown

Eine Sache zu beachten. Bei jeder Lösung, die ein Datum oder einen Zeitstempel in UTC abrufen muss, besteht der Schlüssel anscheinend darin, das SimpleDateFormat nicht erneut zu verwenden, sondern eines zu verwenden, um UTC in eine Zeichenfolge zu übertragen, und dann eine andere UTC zu erstellen, wenn die Zeichenfolge in ein Datum konvertiert wird oder Zeitstempelobjekt. Ich habe festgestellt, dass, wenn Sie versuchen, dasselbe SimpleDateFormat wiederzuverwenden, das resultierende Datums- / Zeitstempelobjekt anstelle von UTC auf die lokale Zeitzone zurückgesetzt wird.
Brian begann

65
    Calendar c = Calendar.getInstance();
    System.out.println("current: "+c.getTime());

    TimeZone z = c.getTimeZone();
    int offset = z.getRawOffset();
    if(z.inDaylightTime(new Date())){
        offset = offset + z.getDSTSavings();
    }
    int offsetHrs = offset / 1000 / 60 / 60;
    int offsetMins = offset / 1000 / 60 % 60;

    System.out.println("offset: " + offsetHrs);
    System.out.println("offset: " + offsetMins);

    c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
    c.add(Calendar.MINUTE, (-offsetMins));

    System.out.println("GMT Time: "+c.getTime());

52

Eigentlich keine Zeit, aber die Darstellung könnte geändert werden.

SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));

Die Zeit ist an jedem Punkt der Erde gleich, aber unsere Wahrnehmung der Zeit kann je nach Ort unterschiedlich sein.


Ja, schöne und saubere Lösung. Es macht mir nur Sorgen, ob es ineffektiv ist, ein neues Datumsobjekt zu erstellen, anstatt nur eine Kalenderinstanz abzurufen?
Beemo

Es wird von JVM optimiert und HotSpot wird den effektivsten x86-Code ausführen
Antonio

17

Kalender aGMTCalendar = Calendar.getInstance (TimeZone.getTimeZone ("GMT")); Dann werden alle Operationen, die mit dem aGMTCalendar-Objekt ausgeführt werden, mit der GMT-Zeitzone ausgeführt und es werden keine Sommerzeit oder feste Offsets angewendet

Falsch!

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
aGMTCalendar.getTime(); //or getTimeInMillis()

und

Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();

wird zur gleichen Zeit zurückkehren. Idem für

new Date(); //it's not GMT.

17

Dieser Code gibt die aktuelle Uhrzeit UTC aus.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;


public class Test
{
    public static void main(final String[] args) throws ParseException
    {
        final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        f.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(f.format(new Date()));
    }
}

Ergebnis

2013-10-26 14:37:48 UTC

14

Dies funktioniert, um UTC-Millisekunden in Android abzurufen.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;

7
müssen Sie nur den Versatz subtrahieren?
tevch

c.add(Calendar.MILLISECOND, (-utcOffset))Kalender mit utc Zeitzone zu bekommen
Shanavas M

10

Hier ist, was in Jon Skeets Antwort falsch zu sein scheint . Er sagte:

java.util.Dateist immer in UTC. Was lässt Sie denken, dass es in der Ortszeit ist? Ich vermute, das Problem ist, dass Sie es über eine Instanz des Kalenders anzeigen, die die lokale Zeitzone verwendet oder möglicherweise Date.toString()auch die lokale Zeitzone verwendet.

Der Code:

System.out.println(new java.util.Date().getHours() + " hours");

gibt die lokalen Stunden an, nicht GMT (UTC-Stunden), wobei no Calendarund no verwendet werden SimpleDateFormat.

Deshalb scheint etwas nicht zu stimmen.

Zusammenstellen der Antworten, der Code:

System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
                           .get(Calendar.HOUR_OF_DAY) + " Hours");

zeigt die GMT-Stunden anstelle der lokalen Stunden an - beachten Sie, dass dies getTime.getHours()fehlt, da dadurch ein Date()Objekt erstellt wird, das theoretisch das Datum in GMT speichert, aber die Stunden in der lokalen Zeitzone zurückgibt.


6
Ich hatte diese Antwort noch nie gesehen, aber wenn Sie die Dokumentation für die veraltete Date.getHours()Methode lesen , wird deutlich: "Der zurückgegebene Wert ist eine Zahl (0 bis 23), die die Stunde innerhalb des Tages darstellt, die die enthält oder mit der beginnt Zeitpunkt, der durch dieses Datumsobjekt dargestellt wird, wie in der lokalen Zeitzone interpretiert . " (Hervorhebung von mir.) Es ist die getHours()Methode, die den Wert innerhalb der lokalen Zeitzone interpretiert - sie ist nicht Teil des Zustands des DateObjekts selbst.
Jon Skeet

2
Wie Jon Skeet richtig angegeben hat, hat ein java.util.Date-Objekt keine Zeitzone . Aber verwirrenderweise wenden die Methoden toStringund getHoursdie Standardzeitzone auf ihre Ausgabe an. Naive Programmierer lassen sich also leicht täuschen, da ein Datum anscheinend eine Zeitzone hat, dies jedoch nicht.
Basil Bourque

7

Wenn Sie ein Datumsobjekt mit für UTC angepassten Feldern möchten, können Sie dies mit Joda Time folgendermaßen tun :

import org.joda.time.DateTimeZone;
import java.util.Date;

...

Date local = new Date();
System.out.println("Local: " + local);
DateTimeZone zone = DateTimeZone.getDefault();
long utc = zone.convertLocalToUTC(local.getTime(), false);
System.out.println("UTC: " + new Date(utc));

1
Du arbeitest zu hart. Joda-Time kann dies in einer einzigen Codezeile tun. Siehe meine eigene Antwort auf diese Frage. Rufen Sie die .toDateTimeMethode auf und übergeben Sie die Konstante für die UTC-Zeitzone.
Basil Bourque

1
DateTime utcDate = new DateTime (). ToDateTime (DateTimeZone.UTC)
Maciej Miklas

6

Sie können verwenden:

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

Dann werden alle Operationen, die mit dem aGMTCalendar-Objekt ausgeführt werden, mit der GMT-Zeitzone ausgeführt und es werden keine Sommerzeit oder feste Offsets angewendet. Ich denke, das vorherige Poster ist richtig, dass das Date () -Objekt immer eine GMT zurückgibt. Erst wenn Sie etwas mit dem Datumsobjekt tun, wird es in die lokale Zeitzone konvertiert.


6
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));

Bitte fügen Sie Ihrer Antwort eine Erklärung hinzu. Wie unterscheidet sie sich von so vielen anderen Antworten?
Akjoshi

Hängt diese Methode die Zeit vom Gerätekalender ab?
Arnold Brown

6

Sie können dies direkt verwenden

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");

5

Mit:

Calendar cal = Calendar.getInstance();

Dann calhaben Sie das aktuelle Datum und die aktuelle Uhrzeit.
Sie können auch das aktuelle Datum und die aktuelle Uhrzeit für die Zeitzone abrufen mit:

Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));

Sie könnten cal.get(Calendar.DATE);oder andere Kalenderkonstanten nach anderen Details fragen .
Datum und Zeitstempel sind in Java veraltet. Kalenderklasse ist es nicht.


6
Bestimmte Methoden und Konstruktoren von Datum und Zeitstempel sind veraltet, die Klassen selbst jedoch nicht.
Powerlord

5

Hier ein weiterer Vorschlag, um ein GMT-Zeitstempelobjekt zu erhalten:

import java.sql.Timestamp;
import java.util.Calendar;

...

private static Timestamp getGMT() {
   Calendar cal = Calendar.getInstance();
   return new Timestamp(cal.getTimeInMillis()
                       -cal.get(Calendar.ZONE_OFFSET)
                       -cal.get(Calendar.DST_OFFSET));
}

5

Hier ist eine andere Möglichkeit, die GMT-Zeit im String-Format abzurufen

String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString =  sdf.format(new Date());

5

Hier ist meine Implementierung von toUTC:

    public static Date toUTC(Date date){
    long datems = date.getTime();
    long timezoneoffset = TimeZone.getDefault().getOffset(datems);
    datems -= timezoneoffset;
    return new Date(datems);
}

Es gibt wahrscheinlich mehrere Möglichkeiten, es zu verbessern, aber es funktioniert für mich.


3

Beispielcode zum Rendern der Systemzeit in einer bestimmten Zeitzone und einem bestimmten Format.

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class TimZoneTest {
    public static void main (String[] args){
        //<GMT><+/-><hour>:<minutes>
        // Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.

        System.out.println(my_time_in("GMT-5:00", "MM/dd/yyyy HH:mm:ss") );
        System.out.println(my_time_in("GMT+5:30", "'at' HH:mm a z 'on' MM/dd/yyyy"));

        System.out.println("---------------------------------------------");
        // Alternate format 
        System.out.println(my_time_in("America/Los_Angeles", "'at' HH:mm a z 'on' MM/dd/yyyy") );
        System.out.println(my_time_in("America/Buenos_Aires", "'at' HH:mm a z 'on' MM/dd/yyyy") );


    }

    public static String my_time_in(String target_time_zone, String format){
        TimeZone tz = TimeZone.getTimeZone(target_time_zone);
        Date date = Calendar.getInstance().getTime();
        SimpleDateFormat date_format_gmt = new SimpleDateFormat(format);
        date_format_gmt.setTimeZone(tz);
        return date_format_gmt.format(date);
    }

}

Ausgabe

10/08/2011 21:07:21
at 07:37 AM GMT+05:30 on 10/09/2011
at 19:07 PM PDT on 10/08/2011
at 23:07 PM ART on 10/08/2011

3

Nur um diese einfacher zu machen, eine schaffen Datein UTCdie Sie verwenden können Calendar:

Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Dadurch wird eine neue Instanz für die CalendarVerwendung der "UTC" erstellt TimeZone.

Wenn Sie ein DateObjekt aus diesem Kalender benötigen , können Sie es einfach verwenden getTime().


5
Wenn Sie getTime () aufrufen, gehen die Zeitzoneninformationen verloren und die Ortszeit wird zurückgegeben.
RealCasually

3

Konvertieren der aktuellen DateTime in UTC:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

DateTimeZone dateTimeZone = DateTimeZone.getDefault(); //Default Time Zone

DateTime currDateTime = new DateTime(); //Current DateTime

long utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(), false);

String currTime = formatter.print(utcTime); //UTC time converted to string from long in format of formatter

currDateTime = formatter.parseDateTime(currTime); //Converted to DateTime in UTC

1
Sie machen hier zu viel Arbeit. (a) Das von Ihnen definierte Formatierungsmuster ist standardmäßig bereits in eine DateTime integriert. Rufen Sie einfach toStringeine DateTime auf, um das ISO 8601- Zeichenfolgenmuster zu erhalten. (b) Viel zu viel Code zum Konvertieren zwischen Zeitzonen. Rufen Sie einfach "toDateTime" auf und übergeben Sie ein Zeitzonenobjekt. So : myDateTime.toDateTime( DateTimeZone.UTC ). Für eine bestimmte Zeitzone, instantiate und eine Zeitzone Objekt auf einer Basis passieren richtigen Namen , rufen myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Basil Bourque

2

Das hat bei mir funktioniert, gibt den Zeitstempel in GMT zurück!

    Date currDate;
    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

    long currTime = 0;
    try {

        currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
        currTime = currDate.getTime();
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

2

Verwenden Sie diese Klasse, um immer die richtige UTC-Zeit von einem Online-NTP-Server zu erhalten:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


class NTP_UTC_Time
{
private static final String TAG = "SntpClient";

private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;

private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;

// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

private long mNtpTime;

public boolean requestTime(String host, int timeout) {
    try {
        DatagramSocket socket = new DatagramSocket();
        socket.setSoTimeout(timeout);
        InetAddress address = InetAddress.getByName(host);
        byte[] buffer = new byte[NTP_PACKET_SIZE];
        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

        buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

        writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

        socket.send(request);

        // read the response
        DatagramPacket response = new DatagramPacket(buffer, buffer.length);
        socket.receive(response);          
        socket.close();

        mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);            
    } catch (Exception e) {
      //  if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
        return false;
    }

    return true;
}


public long getNtpTime() {
    return mNtpTime;
}


/**
 * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
 */
private long read32(byte[] buffer, int offset) {
    byte b0 = buffer[offset];
    byte b1 = buffer[offset+1];
    byte b2 = buffer[offset+2];
    byte b3 = buffer[offset+3];

    // convert signed bytes to unsigned values
    int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
    int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
    int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
    int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);

    return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
}

/**
 * Reads the NTP time stamp at the given offset in the buffer and returns 
 * it as a system time (milliseconds since January 1, 1970).
 */    
private long readTimeStamp(byte[] buffer, int offset) {
    long seconds = read32(buffer, offset);
    long fraction = read32(buffer, offset + 4);
    return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);        
}

/**
 * Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
 */    
private void writeTimeStamp(byte[] buffer, int offset) {        
    int ofs =  offset++;

    for (int i=ofs;i<(ofs+8);i++)
      buffer[i] = (byte)(0);             
}

}

Und benutze es mit:

        long now = 0;

        NTP_UTC_Time client = new NTP_UTC_Time();

        if (client.requestTime("pool.ntp.org", 2000)) {              
          now = client.getNtpTime();
        }

Wenn Sie die UTC-Zeit "jetzt" als DateTimeString benötigen, verwenden Sie die folgende Funktion:

private String get_UTC_Datetime_from_timestamp(long timeStamp){

    try{

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();

        int tzt = tz.getOffset(System.currentTimeMillis());

        timeStamp -= tzt;

        // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
        DateFormat sdf = new SimpleDateFormat();
        Date netDate = (new Date(timeStamp));
        return sdf.format(netDate);
    }
    catch(Exception ex){
        return "";
     }
    } 

und benutze es mit:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);

In einer Zeile <br/> <pre> <code> Calendar utcTime = Calendar.getInstance (). Add (Calendar.MILLISECOND, -time.getTimeZone (). GetOffset (time.getTimeInMillis ()); </ pre> < / Code>
Harun

1
Ja, aber dies ruft die lokale Gerätezeit auf, die manuell vom Benutzer in eine falsche DateTime geändert werden könnte
Ingo

2
public static void main(String args[]){
    LocalDate date=LocalDate.now();  
    System.out.println("Current date = "+date);
}

1

Einfach gesagt. Ein Kalenderobjekt speichert Informationen zur Zeitzone. Wenn Sie jedoch cal.getTime () ausführen, gehen die Zeitzoneninformationen verloren. Für Zeitzonen-Konvertierungen empfehle ich daher die Verwendung von DateFormat-Klassen ...


1

Das ist meine Implementierung:

public static String GetCurrentTimeStamp()
{
    Calendar cal=Calendar.getInstance();
    long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
    return new java.sql.Timestamp(System.currentTimeMillis()+offset).toString();    
}

1

Wenn Sie das Parsen des Datums vermeiden und nur einen Zeitstempel in GMT wünschen, können Sie Folgendes verwenden:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));

0

Wenn Sie die Joda-Zeit verwenden und die aktuelle Zeit in Millisekunden ohne Ihren lokalen Offset anzeigen möchten, können Sie Folgendes verwenden:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());

0
public class CurrentUtcDate 
{
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println("UTC Time is: " + dateFormat.format(date));
    }
}

Ausgabe:

UTC Time is: 22-01-2018 13:14:35

Sie können das Datumsformat nach Bedarf ändern.


1
Bitte bringen Sie den Jungen nicht bei, die längst veralteten und notorisch lästigen zu benutzen SimpleDateFormat. Heute haben wir java.timedie moderne Java-API für Datum und Uhrzeit viel besser . Und was bieten Sie an, das nicht bereits in den Antworten von Dan, Antonio und anderen enthalten ist?
Ole VV

2
(a) Wie schafft diese Antwort einen Mehrwert gegenüber den Dutzenden vorhandener Antworten? (b) Die hier verwendeten lästigen Klassen wurden vor Jahren durch die modernen java.time- Klassen ersetzt. Die Verwendung im Jahr 2018 vorzuschlagen, ist ein schlechter Rat.
Basil Bourque

0

Verwenden Sie das Paket java.time und geben Sie den folgenden Code ein:

ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );

oder

LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );

abhängig von Ihrem Anwendungsbedarf.


(A) Wenn Sie einen Offset ( ZoneOffset) anstelle einer Zeitzone ( ZoneId) verwenden, OffsetDateTimeist dies geeigneter als ZonedDateTime. (B) LocalDateTimesollte nicht zur Erfassung des aktuellen Moments verwendet werden, da es kein Konzept für eine Zeitzone oder einen Versatz von UTC gibt. (C) Andere bereits vorhandene Antworten haben dieses Material behandelt und bessere Arbeit geleistet. Ich sehe nicht, wie diese Antwort einen Mehrwert schafft.
Basil Bourque
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.