Comment puis-je obtenir la date et l'heure actuelles en UTC ou GMT en Java?
479
Lorsque je crée un nouvel Dateobjet, il est initialisé à l'heure actuelle mais dans le fuseau horaire local. Comment puis-je obtenir la date et l'heure actuelles en GMT?
Je sais que ces types de sujets sont complètement débattus, mais j'ai trouvé que le paquet commons-lang gère vraiment bien ces problèmes Java courants. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Découvrez les différents packages dont ils disposent.
Quelle heure locale voulez-vous et avec quelle précision. La plupart des fuseaux horaires sont définis par rapport à l'UTC avec un décalage fixe mesuré en secondes SI , mais la relation de GMT qui est basée sur l'observation solaire et une seconde de longueur (légèrement) variable est plus complexe. Les deux diffèrent jusqu'à 0,9 seconde.
mc0e
1
A Datene détient pas de fuseau horaire, donc "mais dans le fuseau horaire local" n'est pas correct (ou au mieux inexact). Voir Tout sur java.util.Date .
Ole VV
Réponses:
409
java.util.Daten'a pas de fuseau horaire spécifique, bien que sa valeur soit le plus souvent considérée par rapport à l'UTC. Qu'est-ce qui vous fait penser que c'est l'heure locale?
Pour être précis: la valeur entre a java.util.Dateest le nombre de millisecondes depuis l'époque Unix, qui s'est produite à minuit le 1er janvier 1970, UTC. La même époque pourrait également être décrite dans d'autres fuseaux horaires, mais la description traditionnelle est en termes d'UTC. Comme il s'agit d'un nombre de millisecondes depuis une époque fixe, la valeur à l'intérieurjava.util.Date est la même partout dans le monde à un instant particulier, quel que soit le fuseau horaire local.
Je soupçonne que le problème est que vous l'affichez via une instance de Calendar qui utilise le fuseau horaire local, ou peut-être en utilisant Date.toString()qui utilise également le fuseau horaire local, ou unSimpleDateFormat instance, qui, par défaut, utilise également le fuseau horaire local.
Si ce n'est pas le problème, veuillez publier un exemple de code.
Je recommanderais cependant d'utiliser Joda-Time de toute façon, qui offre une API beaucoup plus claire.
C'est probablement un problème de pilote. Vous devrez peut-être définir votre connexion sur UTC, ou quelque chose comme ça. J'ai déjà rencontré des problèmes comme celui-ci, mais le problème n'est pas dans java.util.Date.
Jon Skeet
13
Behrang, selon stackoverflow.com/questions/4123534/… , le pilote MySQL JDBC convertit une donnée java.util.Timestamp(ou java.util.Date) dans le fuseau horaire du serveur.
Derek Mahar
5
@Monsieur. Cat: Comment déterminez-vous cela? Est-ce en écrivant System.out.println(new Date())? Si c'est le cas, vous devez savoir que c'est la toString()méthode qui applique le fuseau horaire là-bas ... si ce n'est pas le cas, veuillez donner plus de détails.
Jon Skeet
8
@KanagaveluSugumar: toString()utilise toujours le fuseau horaire par défaut. date.getTime()renvoie définitivement des millisecondes depuis l'époque Unix, en UTC. Il est plus juste de dire que Datelui - même n'a pas de fuseau horaire - c'est juste un instant dans le temps, qui pourrait être considéré dans plusieurs fuseaux horaires. Mais lorsque vous créez une instance, cela ne dépend pas de votre fuseau horaire.
Jon Skeet
6
@Jemenake: En fait, cela ne s'est pas produit à minuit à Greenwich, car le Royaume-Uni était à l'heure UTC + 1 à l'époque. Juste l'un des bits étranges de l'histoire. Mais je comprends votre argument - il vaut mieux dire "new Date (). GetTime () renvoie les millisecondes depuis l'époque Unix, qui était minuit au début du 1er janvier 1970, UTC". Ainsi, l'UTC fait partie de l'épinglage de l'époque à un instant particulier dans le temps, pas une partie du résultat.
Jon Skeet
325
tl; dr
Instant.now()// Capture the current moment in UTC.
Générez une chaîne pour représenter cette valeur:
Instant.now().toString()
2016-09-13T23: 30: 52.123Z
Détails
Comme l'a indiqué la bonne réponse de Jon Skeet , un objet java.util.Date n'a pas de fuseau horaire † . Mais son toStringimplémentation applique le fuseau horaire par défaut de la JVM lors de la génération de la représentation String de cette valeur date-heure. Confus pour le programmeur naïf, une date semble avoir un fuseau horaire mais pas.
Les java.util.Date, j.u.Calendaret les java.text.SimpleDateFormatclasses avec Java sont notoirement gênants. Évite-les. Utilisez plutôt l'une de ces bibliothèques de date-heure compétentes:
Java 8 apporte un excellent nouveau package java.time. * Pour remplacer les anciennes classes java.util.Date/Calendar.
Obtenir l'heure actuelle en UTC / GMT est un simple aller simple…
Instant instant =Instant.now();
Cette Instantclasse est le bloc de construction de base dans java.time, représentant un moment sur la timeline en UTC avec une résolution de nanosecondes .
Dans Java 8, l'instant actuel est capturé avec une résolution allant jusqu'à quelques millisecondes seulement. Java 9 apporte une nouvelle implémentation de Clockcapture du moment actuel jusqu'à la pleine capacité en nanosecondes de cette classe, selon la capacité du matériel d'horloge de votre ordinateur hôte.
Sa toStringméthode génère une représentation String de sa valeur en utilisant un format ISO 8601 spécifique . Ce format génère zéro, trois, six ou neuf chiffres ( millisecondes , microsecondes ou nanosecondes ) selon les besoins pour représenter la fraction de seconde.
Si vous souhaitez une mise en forme plus flexible ou d'autres fonctionnalités supplémentaires, appliquez un décalage par rapport à UTC de zéro, pour que l'UTC lui-même ( ZoneOffset.UTCconstant ) obtienne un OffsetDateTime.
OffsetDateTime now =OffsetDateTime.now(ZoneOffset.UTC );
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*cours.
Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .
En utilisant la bibliothèque gratuite et gratuite Joda-Time 3rd-source, vous pouvez obtenir la date-heure actuelle en une seule ligne de code.
Joda-Time a inspiré les nouvelles classes java.time. * De Java 8, mais a une architecture différente. Vous pouvez utiliser Joda-Time dans les anciennes versions de Java. Joda-Time continue de fonctionner dans Java 8 et continue d'être activement entretenu (depuis 2014). Cependant, l'équipe Joda-Time conseille la migration vers java.time.
System.out.println("UTC/GMT date-time in ISO 8601 format: "+new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ));
Exemple de code plus détaillé (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 );
Dump sur console…
System.out.println("Local time in ISO 8601 format: "+ now );System.out.println("Same moment in UTC (Zulu): "+ zulu );
Lors de l'exécution ...
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
Pour plus d'exemples de code faisant un travail de fuseau horaire, voir ma réponse à une question similaire.
Fuseau horaire
Je vous recommande de toujours spécifier un fuseau horaire plutôt que de vous fier implicitement au fuseau horaire par défaut de la JVM (qui peut changer à tout moment!). Une telle confiance semble être une cause courante de confusion et de bugs dans le travail date-heure.
Lors de l'appel, now()passez le fuseau horaire souhaité / attendu à attribuer. Utilisez la DateTimeZoneclasse.
DateTimeZone zoneMontréal =DateTimeZone.forID("America/Montreal");DateTime now =DateTime.now( zoneMontréal );
Lisez à propos de l' ISO 8601 formats. Java.time et Joda-Time utilisent les formats sensibles de cette norme comme valeurs par défaut pour l'analyse et la génération de chaînes.
† En fait, java.util.Date ne une zone de temps, enfoui au plus profond sous des couches de code source. Dans la plupart des cas, ce fuseau horaire est ignoré. Donc, en raccourci, nous disons que java.util.Date n'a pas de fuseau horaire. De plus, ce fuseau horaire enfoui n'est pas celui utilisé par la toStringméthode de Date ; cette méthode utilise le fuseau horaire par défaut de la JVM. Raison de plus pour éviter cette classe déroutante et s'en tenir à Joda-Time et java.time.
Comment obtenir cela avec Pure Java 8 2014-01-21T15:34:29.933-08:00dans l'exemple que vous avez utilisénew org.joda.time.DateTime()
GOXR3PLUS
1
@ GOXR3PLUS ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() Nous obtenons l'heure actuelle pour un fuseau horaire spécifié. Ensuite, éliminez tous les micros / nanos. Ensuite, nous nous convertissons à un simple décalage par rapport à UTC (nombre d'heures-minutes-secondes) plutôt qu'à un fuseau horaire complet (un historique des changements passés, présents et futurs du décalage utilisé par les personnes d'un région particulière). Enfin, nous générons du texte représentant la valeur dans celle OffsetDateTimeselon le format standard ISO 8601 utilisé par défaut dans sa toStringméthode.
Basil Bourque
Merci d'avoir donné cette explication détaillée, également +1 pour les supports Android :) @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()));
Pourquoi analysez-vous avec dateFormatLocal après avoir utilisé le format dateFormatGmt ... n'a pas de sens en le lisant. Je suis sûr que cela fonctionne, mais vous vous demandez simplement?
MindWire
2
setTimeZone l'a fait (je suppose que vous pouvez également utiliser getTimeZone ("UTC") comme GMT?)
rogerdpack
6
mais le temps dépend du temps réglé par l'appareil. Si l'utilisateur a réglé le mauvais moment sur son appareil, vous vous tromperez UTC .Corrigez-moi si je me trompe
Basavaraj Hampali
@BasavarajHampali mais dans le monde d'aujourd'hui, la plupart des appareils sont connectés à Internet, ce qui corrige l'heure incorrecte
Akshat Agarwal
3
Il n'y a pas de décalage horaire entre le temps universel coordonné (UTC) et le temps moyen de Greenwich (GMT)
slott
86
Cela renvoie définitivement l'heure UTC: sous forme d'objets String et Date!
Dans ma réponse, j'ai oublié de montrer comment DATEFORMAT est défini: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Someone Somewhere
21
Veuillez éviter de démarrer les noms de méthode avec des majuscules en Java. Voir les conventions de codage Java pour les noms de méthode.
Florian Schrofner
2
Comme je suis redirigé vers cette réponse, l'appel new Date()ne renverra jamais l'heure UTC correcte, si l'heure de l'appareil est incorrecte.
Sanoop
cette méthode obtient-elle du temps dépend du calendrier de l'appareil?
Arnold Brown
Une chose à noter. Toute solution qui a besoin d'obtenir une date ou un horodatage en UTC, il semble que la clé est de ne pas réutiliser le SimpleDateFormat, mais plutôt d'en utiliser un pour obtenir l'UTC dans une chaîne, puis de créer un autre UTC lors de la conversion de la chaîne en une date ou Objet d'horodatage. J'ai remarqué que si vous essayez de réutiliser le même SimpleDateFormat, l'objet Date / Timestamp résultant retournera au fuseau horaire local au lieu de UTC.
Oui, une solution agréable et propre. Cela m'inquiète, si c'est inefficace de créer un nouvel objet Date au lieu de simplement obtenir une instance de Calendar?
Beemo
Il sera optimisé par JVM et HotSpot exécutera le code x86 le plus efficace possible
Antonio
17
Calendrier aGMTCalendar = Calendar.getInstance (TimeZone.getTimeZone ("GMT")); Ensuite, toutes les opérations effectuées à l'aide de l'objet aGMTCalendar seront effectuées avec le fuseau horaire GMT et aucune heure d'été ou décalage fixe ne sera appliqué.
java.util.Dateest toujours en UTC. Qu'est-ce qui vous fait penser que c'est l'heure locale? Je soupçonne que le problème est que vous l'affichez via une instance de Calendar qui utilise le fuseau horaire local, ou éventuellement en utilisant
Date.toString()également le fuseau horaire local.
affiche les heures GMT au lieu des heures locales - notez que getTime.getHours() manque car cela créerait un Date()objet, qui stocke théoriquement la date en GMT, mais rend les heures dans le fuseau horaire local.
Je n'avais pas vu cette réponse auparavant, mais si vous lisez la documentation de la Date.getHours()méthode obsolète , elle est très claire: "La valeur renvoyée est un nombre (0 à 23) représentant l'heure dans la journée qui contient ou commence par le instant dans le temps représenté par cet objet Date, tel qu'il est interprété dans le fuseau horaire local . " (Je souligne.) C'est la getHours()méthode qui interprète la valeur dans le fuseau horaire local - elle ne fait pas partie de l'état de l' Dateobjet lui-même.
Jon Skeet
2
Comme Jon Skeet l'a correctement déclaré, un objet java.util.Date n'a pas de fuseau horaire . Mais de façon confuse, les méthodes toStringet getHoursappliquer le fuseau horaire par défaut à leur sortie. Ainsi, les programmeurs naïfs sont facilement dupes car il semble qu'une date ait un fuseau horaire mais en fait pas.
Basil Bourque
7
Si vous voulez un objet Date avec des champs ajustés pour UTC, vous pouvez le faire comme ceci avec Joda Time :
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));
Vous travaillez trop dur. Joda-Time peut le faire en une seule ligne de code. Voir ma propre réponse sur cette question. Appelez la .toDateTimeméthode et passez la constante pour le fuseau horaire UTC.
Basil Bourque
1
DateTime utcDate = new DateTime (). ToDateTime (DateTimeZone.UTC)
Ensuite, toutes les opérations effectuées à l'aide de l'objet aGMTCalendar seront effectuées avec le fuseau horaire GMT et aucune heure d'été ou décalage fixe ne sera appliqué. Je pense que l'affiche précédente est correcte que l'objet Date () renvoie toujours un GMT ce n'est que lorsque vous allez faire quelque chose avec l'objet date qu'il est converti en fuseau horaire local.
Vous pouvez demander à d' cal.get(Calendar.DATE);autres constantes du calendrier d'autres détails.
La date et l'horodatage sont obsolètes en Java. Classe d'agenda ce n'est pas le cas.
Exemple de code pour afficher l'heure système dans un fuseau horaire spécifique et un format spécifique.
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);}}
Production
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
L'appel de getTime () à cet effet lui fait perdre les informations de fuseau horaire et renvoie l'heure locale.
RealCasually
3
Conversion de l'heure actuelle en 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
Vous faites trop de travail ici. (a) Le formateur que vous définissez est déjà intégré dans un DateTime par défaut; il suffit d'appeler toStringun DateTime pour obtenir ce modèle de chaîne ISO 8601 . (b) Beaucoup trop de code pour convertir entre les fuseaux horaires. Appelez simplement "toDateTime" et passez un objet de fuseau horaire. Comme ceci: myDateTime.toDateTime( DateTimeZone.UTC ). Pour un fuseau horaire spécifique, instanciez et passez un objet de fuseau horaire basé sur un nom propre , appelez myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Basil Bourque
2
Cela a fonctionné pour moi, renvoie l'horodatage en GMT!
Utilisez cette classe pour obtenir toujours le bon temps UTC à partir d'un serveur NTP en ligne:
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);}}
Et utilisez-le avec:
long now =0;
NTP_UTC_Time client =new NTP_UTC_Time();if(client.requestTime("pool.ntp.org",2000)){
now = client.getNtpTime();}
Si vous avez besoin de l'heure UTC "maintenant" comme fonction d'utilisation de DateTimeString:
Pour faire simple. Un objet de calendrier stocke des informations sur le fuseau horaire mais lorsque vous exécutez cal.getTime (), les informations de fuseau horaire seront perdues. Donc, pour les conversions de fuseau horaire, je conseillerai d'utiliser les classes DateFormat ...
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));}}
Production:
UTC Time is:22-01-201813:14:35
Vous pouvez modifier le format de date selon vos besoins.
S'il vous plaît, n'enseignez pas aux jeunes à utiliser ce qui est depuis longtemps obsolète et notoirement gênant SimpleDateFormat. Aujourd'hui, nous avons tellement mieux dans java.timel'API moderne de date et d'heure Java . De plus, que fournissez-vous qui ne figure pas déjà dans les réponses de Dan, Antonio et d'autres?
Ole VV
2
(a) Comment cette réponse ajoute-t-elle de la valeur aux dizaines de réponses existantes? (b) Les classes gênantes utilisées ici ont été remplacées il y a des années par les classes java.time modernes . Suggérer leur utilisation en 2018 est un mauvais conseil.
Basil Bourque
0
Utilisez le package java.time et incluez ci-dessous le code-
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
(A) Si vous utilisez un décalage ( ZoneOffset) plutôt qu'un fuseau horaire ( ZoneId), le OffsetDateTimeest plus approprié que ZonedDateTime. (B) LocalDateTimene doit pas être utilisé pour capturer l'instant actuel car il n'a pas de concept de fuseau horaire ou de décalage par rapport à UTC. (C) D'autres réponses préexistantes ont couvert ce matériel et ont fait un meilleur travail. Je ne vois pas comment cette réponse ajoute de la valeur.
Date
ne détient pas de fuseau horaire, donc "mais dans le fuseau horaire local" n'est pas correct (ou au mieux inexact). Voir Tout sur java.util.Date .Réponses:
java.util.Date
n'a pas de fuseau horaire spécifique, bien que sa valeur soit le plus souvent considérée par rapport à l'UTC. Qu'est-ce qui vous fait penser que c'est l'heure locale?Pour être précis: la valeur entre a
java.util.Date
est le nombre de millisecondes depuis l'époque Unix, qui s'est produite à minuit le 1er janvier 1970, UTC. La même époque pourrait également être décrite dans d'autres fuseaux horaires, mais la description traditionnelle est en termes d'UTC. Comme il s'agit d'un nombre de millisecondes depuis une époque fixe, la valeur à l'intérieurjava.util.Date
est la même partout dans le monde à un instant particulier, quel que soit le fuseau horaire local.Je soupçonne que le problème est que vous l'affichez via une instance de Calendar qui utilise le fuseau horaire local, ou peut-être en utilisant
Date.toString()
qui utilise également le fuseau horaire local, ou unSimpleDateFormat
instance, qui, par défaut, utilise également le fuseau horaire local.Si ce n'est pas le problème, veuillez publier un exemple de code.
Je recommanderais cependant d'utiliser Joda-Time de toute façon, qui offre une API beaucoup plus claire.
la source
java.util.Timestamp
(oujava.util.Date
) dans le fuseau horaire du serveur.System.out.println(new Date())
? Si c'est le cas, vous devez savoir que c'est latoString()
méthode qui applique le fuseau horaire là-bas ... si ce n'est pas le cas, veuillez donner plus de détails.toString()
utilise toujours le fuseau horaire par défaut.date.getTime()
renvoie définitivement des millisecondes depuis l'époque Unix, en UTC. Il est plus juste de dire queDate
lui - même n'a pas de fuseau horaire - c'est juste un instant dans le temps, qui pourrait être considéré dans plusieurs fuseaux horaires. Mais lorsque vous créez une instance, cela ne dépend pas de votre fuseau horaire.tl; dr
Générez une chaîne pour représenter cette valeur:
Détails
Comme l'a indiqué la bonne réponse de Jon Skeet , un objet java.util.Date n'a pas de fuseau horaire † . Mais son
toString
implémentation applique le fuseau horaire par défaut de la JVM lors de la génération de la représentation String de cette valeur date-heure. Confus pour le programmeur naïf, une date semble avoir un fuseau horaire mais pas.Les
java.util.Date
,j.u.Calendar
et lesjava.text.SimpleDateFormat
classes avec Java sont notoirement gênants. Évite-les. Utilisez plutôt l'une de ces bibliothèques de date-heure compétentes:java.time (Java 8)
Java 8 apporte un excellent nouveau package java.time. * Pour remplacer les anciennes classes java.util.Date/Calendar.
Obtenir l'heure actuelle en UTC / GMT est un simple aller simple…
Cette
Instant
classe est le bloc de construction de base dans java.time, représentant un moment sur la timeline en UTC avec une résolution de nanosecondes .Dans Java 8, l'instant actuel est capturé avec une résolution allant jusqu'à quelques millisecondes seulement. Java 9 apporte une nouvelle implémentation de
Clock
capture du moment actuel jusqu'à la pleine capacité en nanosecondes de cette classe, selon la capacité du matériel d'horloge de votre ordinateur hôte.Sa
toString
méthode génère une représentation String de sa valeur en utilisant un format ISO 8601 spécifique . Ce format génère zéro, trois, six ou neuf chiffres ( millisecondes , microsecondes ou nanosecondes ) selon les besoins pour représenter la fraction de seconde.Si vous souhaitez une mise en forme plus flexible ou d'autres fonctionnalités supplémentaires, appliquez un décalage par rapport à UTC de zéro, pour que l'UTC lui-même (
ZoneOffset.UTC
constant ) obtienne unOffsetDateTime
.Dump sur console…
Lors de l'exécution ...
À propos de java.time
Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que
java.util.Date
,Calendar
, etSimpleDateFormat
.Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .
Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de
java.sql.*
cours.Où obtenir les classes java.time?
Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme
Interval
,YearWeek
,YearQuarter
et plus .Joda-Time
MISE À JOUR: Le projet Joda-Time , maintenant en mode maintenance , conseille la migration vers les classes java.time .
En utilisant la bibliothèque gratuite et gratuite Joda-Time 3rd-source, vous pouvez obtenir la date-heure actuelle en une seule ligne de code.
Joda-Time a inspiré les nouvelles classes java.time. * De Java 8, mais a une architecture différente. Vous pouvez utiliser Joda-Time dans les anciennes versions de Java. Joda-Time continue de fonctionner dans Java 8 et continue d'être activement entretenu (depuis 2014). Cependant, l'équipe Joda-Time conseille la migration vers java.time.
Exemple de code plus détaillé (Joda-Time 2.3)…
Dump sur console…
Lors de l'exécution ...
Pour plus d'exemples de code faisant un travail de fuseau horaire, voir ma réponse à une question similaire.
Fuseau horaire
Je vous recommande de toujours spécifier un fuseau horaire plutôt que de vous fier implicitement au fuseau horaire par défaut de la JVM (qui peut changer à tout moment!). Une telle confiance semble être une cause courante de confusion et de bugs dans le travail date-heure.
Lors de l'appel,
now()
passez le fuseau horaire souhaité / attendu à attribuer. Utilisez laDateTimeZone
classe.Cette classe contient une constante pour le fuseau horaire UTC .
Si vous voulez vraiment utiliser le fuseau horaire par défaut de la JVM, faites un appel explicite pour que votre code soit auto-documenté.
ISO 8601
Lisez à propos de l' ISO 8601 formats. Java.time et Joda-Time utilisent les formats sensibles de cette norme comme valeurs par défaut pour l'analyse et la génération de chaînes.
† En fait, java.util.Date ne une zone de temps, enfoui au plus profond sous des couches de code source. Dans la plupart des cas, ce fuseau horaire est ignoré. Donc, en raccourci, nous disons que java.util.Date n'a pas de fuseau horaire. De plus, ce fuseau horaire enfoui n'est pas celui utilisé par la
toString
méthode de Date ; cette méthode utilise le fuseau horaire par défaut de la JVM. Raison de plus pour éviter cette classe déroutante et s'en tenir à Joda-Time et java.time.la source
DateTime.now().toDateTime(DateTimeZone.UTC)
était ce que je cherchais! Merci!DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
2014-01-21T15:34:29.933-08:00
dans l'exemple que vous avez utilisénew org.joda.time.DateTime()
ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString()
Nous obtenons l'heure actuelle pour un fuseau horaire spécifié. Ensuite, éliminez tous les micros / nanos. Ensuite, nous nous convertissons à un simple décalage par rapport à UTC (nombre d'heures-minutes-secondes) plutôt qu'à un fuseau horaire complet (un historique des changements passés, présents et futurs du décalage utilisé par les personnes d'un région particulière). Enfin, nous générons du texte représentant la valeur dans celleOffsetDateTime
selon le format standard ISO 8601 utilisé par défaut dans satoString
méthode.la source
Cela renvoie définitivement l'heure UTC: sous forme d'objets String et Date!
la source
static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
new Date()
ne renverra jamais l'heure UTC correcte, si l'heure de l'appareil est incorrecte.la source
En fait, pas le temps, mais sa représentation pourrait être modifiée.
Le temps est le même en tout point de la Terre, mais notre perception du temps peut être différente selon le lieu.
la source
Faux!
et
reviendra en même temps. Idem pour
la source
Ce code imprime l'heure actuelle UTC.
Résultat
la source
Cela fonctionne pour obtenir des millisecondes UTC dans Android.
la source
c.add(Calendar.MILLISECOND, (-utcOffset))
obtenir le calendrier avec le fuseau horaire utcVoici ce qui semble incorrect dans la réponse de Jon Skeet . Il a dit:
Cependant, le code:
donne les heures locales, pas GMT (heures UTC), en utilisant non
Calendar
et nonSimpleDateFormat
du tout.C'est pourquoi il semble que quelque chose soit incorrect.
En rassemblant les réponses, le code:
affiche les heures GMT au lieu des heures locales - notez que
getTime.getHours()
manque car cela créerait unDate()
objet, qui stocke théoriquement la date en GMT, mais rend les heures dans le fuseau horaire local.la source
Date.getHours()
méthode obsolète , elle est très claire: "La valeur renvoyée est un nombre (0 à 23) représentant l'heure dans la journée qui contient ou commence par le instant dans le temps représenté par cet objet Date, tel qu'il est interprété dans le fuseau horaire local . " (Je souligne.) C'est lagetHours()
méthode qui interprète la valeur dans le fuseau horaire local - elle ne fait pas partie de l'état de l'Date
objet lui-même.toString
etgetHours
appliquer le fuseau horaire par défaut à leur sortie. Ainsi, les programmeurs naïfs sont facilement dupes car il semble qu'une date ait un fuseau horaire mais en fait pas.Si vous voulez un objet Date avec des champs ajustés pour UTC, vous pouvez le faire comme ceci avec Joda Time :
la source
.toDateTime
méthode et passez la constante pour le fuseau horaire UTC.Vous pouvez utiliser:
Ensuite, toutes les opérations effectuées à l'aide de l'objet aGMTCalendar seront effectuées avec le fuseau horaire GMT et aucune heure d'été ou décalage fixe ne sera appliqué. Je pense que l'affiche précédente est correcte que l'objet Date () renvoie toujours un GMT ce n'est que lorsque vous allez faire quelque chose avec l'objet date qu'il est converti en fuseau horaire local.
la source
la source
Vous pouvez directement l'utiliser
la source
Avec:
Ensuite,
cal
ayez la date et l'heure actuelles.Vous pouvez également obtenir la date et l'heure actuelles du fuseau horaire avec:
Vous pouvez demander à d'
cal.get(Calendar.DATE);
autres constantes du calendrier d'autres détails.La date et l'horodatage sont obsolètes en Java. Classe d'agenda ce n'est pas le cas.
la source
Voici une autre suggestion pour obtenir un objet GMT Timestamp:
la source
Voici une autre façon d'obtenir l'heure GMT au format String
la source
Voici mon implémentation de toUTC:
Il y a probablement plusieurs façons de l'améliorer, mais cela fonctionne pour moi.
la source
Exemple de code pour afficher l'heure système dans un fuseau horaire spécifique et un format spécifique.
Production
la source
Pour simplifier, pour créer un
Date
dans,UTC
vous pouvez utiliserCalendar
:Ce qui va construire une nouvelle instance pour
Calendar
utiliser le "UTC"TimeZone
.Si vous avez besoin d'un
Date
objet de ce calendrier, vous pouvez simplement l'utilisergetTime()
.la source
Conversion de l'heure actuelle en UTC:
la source
toString
un DateTime pour obtenir ce modèle de chaîne ISO 8601 . (b) Beaucoup trop de code pour convertir entre les fuseaux horaires. Appelez simplement "toDateTime" et passez un objet de fuseau horaire. Comme ceci:myDateTime.toDateTime( DateTimeZone.UTC )
. Pour un fuseau horaire spécifique, instanciez et passez un objet de fuseau horaire basé sur un nom propre , appelezmyDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) )
.Cela a fonctionné pour moi, renvoie l'horodatage en GMT!
la source
Utilisez cette classe pour obtenir toujours le bon temps UTC à partir d'un serveur NTP en ligne:
Et utilisez-le avec:
Si vous avez besoin de l'heure UTC "maintenant" comme fonction d'utilisation de DateTimeString:
et l'utiliser avec:
la source
la source
Pour faire simple. Un objet de calendrier stocke des informations sur le fuseau horaire mais lorsque vous exécutez cal.getTime (), les informations de fuseau horaire seront perdues. Donc, pour les conversions de fuseau horaire, je conseillerai d'utiliser les classes DateFormat ...
la source
voici ma mise en œuvre:
la source
Si vous voulez éviter d'analyser la date et que vous voulez juste un horodatage en GMT, vous pouvez utiliser:
la source
Si vous utilisez l'heure Joda et que vous voulez l'heure actuelle en millisecondes sans votre décalage local, vous pouvez utiliser ceci:
la source
Production:
Vous pouvez modifier le format de date selon vos besoins.
la source
SimpleDateFormat
. Aujourd'hui, nous avons tellement mieux dansjava.time
l'API moderne de date et d'heure Java . De plus, que fournissez-vous qui ne figure pas déjà dans les réponses de Dan, Antonio et d'autres?Utilisez le package java.time et incluez ci-dessous le code-
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
ou
LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );
selon le besoin de votre application.
la source
ZoneOffset
) plutôt qu'un fuseau horaire (ZoneId
), leOffsetDateTime
est plus approprié queZonedDateTime
. (B)LocalDateTime
ne doit pas être utilisé pour capturer l'instant actuel car il n'a pas de concept de fuseau horaire ou de décalage par rapport à UTC. (C) D'autres réponses préexistantes ont couvert ce matériel et ont fait un meilleur travail. Je ne vois pas comment cette réponse ajoute de la valeur.