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.
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:
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.
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 );
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.
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 .
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 );
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.
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 =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));//Local time zone SimpleDateFormat dateFormatLocal =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");//Time in GMTreturn dateFormatLocal.parse( dateFormatGmt.format(newDate()));
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!
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.
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
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.
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.
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 =newDate();System.out.println("Local: "+ local);DateTimeZone zone =DateTimeZone.getDefault();long utc = zone.convertLocalToUTC(local.getTime(),false);System.out.println("UTC: "+newDate(utc));
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)
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.
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:
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.
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;publicclassTimZoneTest{publicstaticvoid 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"));}publicstaticString 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 =newSimpleDateFormat(format);
date_format_gmt.setTimeZone(tz);return date_format_gmt.format(date);}}
Ausgabe
10/08/201121: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
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 ZoneDateTime currDateTime =newDateTime();//Current DateTimelong 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
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!
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
{privatestaticfinalString TAG ="SntpClient";privatestaticfinalint RECEIVE_TIME_OFFSET =32;privatestaticfinalint TRANSMIT_TIME_OFFSET =40;privatestaticfinalint NTP_PACKET_SIZE =48;privatestaticfinalint NTP_PORT =123;privatestaticfinalint NTP_MODE_CLIENT =3;privatestaticfinalint NTP_VERSION =3;// Number of seconds between Jan 1, 1900 and Jan 1, 1970// 70 years plus 17 leap daysprivatestaticfinallong OFFSET_1900_TO_1970 =((365L*70L)+17L)*24L*60L*60L;privatelong mNtpTime;publicboolean requestTime(String host,int timeout){try{DatagramSocket socket =newDatagramSocket();
socket.setSoTimeout(timeout);InetAddress address =InetAddress.getByName(host);byte[] buffer =newbyte[NTP_PACKET_SIZE];DatagramPacket request =newDatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0]= NTP_MODE_CLIENT |(NTP_VERSION <<3);
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
socket.send(request);// read the responseDatagramPacket response =newDatagramPacket(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);returnfalse;}returntrue;}publiclong getNtpTime(){return mNtpTime;}/**
* Reads an unsigned 32 bit big endian number from the given offset in the buffer.
*/privatelong 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 valuesint 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).
*/privatelong 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
*/privatevoid 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:
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 ...
publicstaticStringGetCurrentTimeStamp(){Calendar cal=Calendar.getInstance();long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .returnnew java.sql.Timestamp(System.currentTimeMillis()+offset).toString();}
publicclassCurrentUtcDate{publicstaticvoid main(String[] args){Date date =newDate();SimpleDateFormat dateFormat =newSimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));System.out.println("UTC Time is: "+ dateFormat.format(date));}}
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 );
(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.
Date
hat keine Zeitzone, daher ist "aber in der lokalen Zeitzone" nicht korrekt (oder bestenfalls ungenau). Siehe Alles über java.util.Date .Antworten:
java.util.Date
hat 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.Date
ist 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.
quelle
java.util.Timestamp
(oderjava.util.Date
) in die Server-Zeitzone.System.out.println(new Date())
? Wenn ja, sollten Sie sich bewusst sein, dass es dietoString()
Methode ist, die die Zeitzone dort anwendet. Wenn dies nicht der Fall ist, geben Sie bitte weitere Details an.toString()
immer die Standardzeitzone.date.getTime()
Gibt definitiv Millisekunden seit der Unix-Epoche in UTC zurück. Es ist am genauesten zu sagen, dass esDate
selbst ü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.tl; dr
Generieren Sie eine Zeichenfolge, um diesen Wert darzustellen:
Einzelheiten
Wie die richtige Antwort von Jon Skeet feststellte, hat ein java.util.Date-Objekt keine Zeitzone † . Bei der
toString
Implementierung 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.Calendar
undjava.text.SimpleDateFormat
Klassen 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…
Diese
Instant
Klasse 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
Clock
Captures 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
toString
Methode 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.UTC
konstant ) a erhältOffsetDateTime
.Auf die Konsole werfen ...
Beim Laufen…
Ü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?
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.
Detaillierterer Beispielcode (Joda-Time 2.3)…
Auf die Konsole werfen ...
Beim Laufen…
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 dieDateTimeZone
Klasse.Diese Klasse hält eine Konstante für die UTC- Zeitzone.
Wenn Sie die aktuelle Standardzeitzone der JVM wirklich verwenden möchten, rufen Sie explizit auf, damit sich Ihr Code selbst dokumentiert.
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
toString
Methode 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.quelle
DateTime.now().toDateTime(DateTimeZone.UTC)
war was ich suchte! Vielen Dank!DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
2014-01-21T15:34:29.933-08:00
in dem von Ihnen verwendeten Beispiel erreichennew org.joda.time.DateTime()
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 WertOffsetDateTime
gemäß dem Standardformat ISO 8601 darstellt, das standardmäßig in seinertoString
Methode verwendet wird.quelle
Dies gibt definitiv die UTC-Zeit zurück: als String- und Date-Objekte!
quelle
static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
new Date()
werde , gibt Calling niemals die richtige UTC-Zeit zurück, wenn die Gerätezeit falsch ist.quelle
Eigentlich keine Zeit, aber die Darstellung könnte geändert werden.
Die Zeit ist an jedem Punkt der Erde gleich, aber unsere Wahrnehmung der Zeit kann je nach Ort unterschiedlich sein.
quelle
Falsch!
und
wird zur gleichen Zeit zurückkehren. Idem für
quelle
Dieser Code gibt die aktuelle Uhrzeit UTC aus.
Ergebnis
quelle
Dies funktioniert, um UTC-Millisekunden in Android abzurufen.
quelle
c.add(Calendar.MILLISECOND, (-utcOffset))
Kalender mit utc Zeitzone zu bekommenHier ist, was in Jon Skeets Antwort falsch zu sein scheint . Er sagte:
Der Code:
gibt die lokalen Stunden an, nicht GMT (UTC-Stunden), wobei no
Calendar
und no verwendet werdenSimpleDateFormat
.Deshalb scheint etwas nicht zu stimmen.
Zusammenstellen der Antworten, der Code:
zeigt die GMT-Stunden anstelle der lokalen Stunden an - beachten Sie, dass dies
getTime.getHours()
fehlt, da dadurch einDate()
Objekt erstellt wird, das theoretisch das Datum in GMT speichert, aber die Stunden in der lokalen Zeitzone zurückgibt.quelle
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 diegetHours()
Methode, die den Wert innerhalb der lokalen Zeitzone interpretiert - sie ist nicht Teil des Zustands desDate
Objekts selbst.toString
undgetHours
die Standardzeitzone auf ihre Ausgabe an. Naive Programmierer lassen sich also leicht täuschen, da ein Datum anscheinend eine Zeitzone hat, dies jedoch nicht.Wenn Sie ein Datumsobjekt mit für UTC angepassten Feldern möchten, können Sie dies mit Joda Time folgendermaßen tun :
quelle
.toDateTime
Methode auf und übergeben Sie die Konstante für die UTC-Zeitzone.Sie können verwenden:
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.
quelle
quelle
Sie können dies direkt verwenden
quelle
Mit:
Dann
cal
haben 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:
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.
quelle
Hier ein weiterer Vorschlag, um ein GMT-Zeitstempelobjekt zu erhalten:
quelle
Hier ist eine andere Möglichkeit, die GMT-Zeit im String-Format abzurufen
quelle
Hier ist meine Implementierung von toUTC:
Es gibt wahrscheinlich mehrere Möglichkeiten, es zu verbessern, aber es funktioniert für mich.
quelle
Beispielcode zum Rendern der Systemzeit in einer bestimmten Zeitzone und einem bestimmten Format.
Ausgabe
quelle
Nur um diese einfacher zu machen, eine schaffen
Date
inUTC
die Sie verwenden könnenCalendar
:Dadurch wird eine neue Instanz für die
Calendar
Verwendung der "UTC" erstelltTimeZone
.Wenn Sie ein
Date
Objekt aus diesem Kalender benötigen , können Sie es einfach verwendengetTime()
.quelle
Konvertieren der aktuellen DateTime in UTC:
quelle
toString
eine 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 , rufenmyDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) )
.Das hat bei mir funktioniert, gibt den Zeitstempel in GMT zurück!
quelle
Verwenden Sie diese Klasse, um immer die richtige UTC-Zeit von einem Online-NTP-Server zu erhalten:
Und benutze es mit:
Wenn Sie die UTC-Zeit "jetzt" als DateTimeString benötigen, verwenden Sie die folgende Funktion:
und benutze es mit:
quelle
quelle
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 ...
quelle
Das ist meine Implementierung:
quelle
Wenn Sie das Parsen des Datums vermeiden und nur einen Zeitstempel in GMT wünschen, können Sie Folgendes verwenden:
quelle
Wenn Sie die Joda-Zeit verwenden und die aktuelle Zeit in Millisekunden ohne Ihren lokalen Offset anzeigen möchten, können Sie Folgendes verwenden:
quelle
Ausgabe:
Sie können das Datumsformat nach Bedarf ändern.
quelle
SimpleDateFormat
. Heute haben wirjava.time
die 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?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.
quelle
ZoneOffset
) anstelle einer Zeitzone (ZoneId
) verwenden,OffsetDateTime
ist dies geeigneter alsZonedDateTime
. (B)LocalDateTime
sollte 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.