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?

Behrang
la source
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.

Jon Skeet
la source
5
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.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…

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

Dump sur console…

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

Lors de l'exécution ...

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

Tableau des types de date-heure en Java, à la fois modernes et hérités.


À 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, et SimpleDateFormat.

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?

Tableau de la bibliothèque java.time à utiliser avec quelle version de Java ou Android

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 .


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.

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

Cette classe contient une constante pour le fuseau horaire UTC .

DateTime now = DateTime.now( DateTimeZone.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é.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

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

Basil Bourque
la source
2
DateTime.now().toDateTime(DateTimeZone.UTC)était ce que je cherchais! Merci!
Managarm
1
@Managarm Vous pouvez raccourcir cela à: DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
Basil Bourque
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 = 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()) );
Dan
la source
11
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!

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;
}
Quelqu'un quelque part
la source
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.
Brian Begun
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());
Ahmad Nadeem
la source
52

En fait, pas le temps, mais sa représentation pourrait être modifiée.

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

Le temps est le même en tout point de la Terre, mais notre perception du temps peut être différente selon le lieu.

Antonio
la source
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é.

Faux!

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

et

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

reviendra en même temps. Idem pour

new Date(); //it's not GMT.
simpatico
la source
17

Ce code imprime l'heure actuelle UTC.

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

Résultat

2013-10-26 14:37:48 UTC
Adam
la source
14

Cela fonctionne pour obtenir des millisecondes UTC dans Android.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
moberme
la source
7
vous avez seulement besoin de soustraire le décalage?
tevch
c.add(Calendar.MILLISECOND, (-utcOffset))obtenir le calendrier avec le fuseau horaire utc
Shanavas M
10

Voici ce qui semble incorrect dans la réponse de Jon Skeet . Il a dit:

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.

Cependant, le code:

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

donne les heures locales, pas GMT (heures UTC), en utilisant non Calendaret non SimpleDateFormatdu tout.

C'est pourquoi il semble que quelque chose soit incorrect.

En rassemblant les réponses, le code:

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

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.

Dana Wilson
la source
6
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 = 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));
huljas
la source
1
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)
Maciej Miklas
6

Vous pouvez utiliser:

Calendar 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é. 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.

mjh2007
la source
6
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
Justin
la source
Veuillez ajouter quelques explications à votre réponse, en quoi est-elle différente de tant d'autres réponses?
akjoshi
cette méthode obtient-elle du temps dépend du calendrier de l'appareil?
Arnold Brown
6

Vous pouvez directement l'utiliser

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

Avec:

Calendar cal = Calendar.getInstance();

Ensuite, calayez la date et l'heure actuelles.
Vous pouvez également obtenir la date et l'heure actuelles du fuseau horaire avec:

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

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.

user2427
la source
6
Certaines méthodes et constructeurs de Date et Timestamp sont obsolètes, mais les classes elles-mêmes ne le sont pas.
Powerlord
5

Voici une autre suggestion pour obtenir un objet GMT Timestamp:

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));
}
René
la source
5

Voici une autre façon d'obtenir l'heure GMT au format String

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());
shahtapa
la source
5

Voici mon implémentation de toUTC:

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

Il y a probablement plusieurs façons de l'améliorer, mais cela fonctionne pour moi.

Ashallar
la source
3

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;

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

}

Production

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
so_mv
la source
3

Pour simplifier, pour créer un Datedans, UTCvous pouvez utiliser Calendar:

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

Ce qui va construire une nouvelle instance pour Calendarutiliser le "UTC" TimeZone.

Si vous avez besoin d'un Dateobjet de ce calendrier, vous pouvez simplement l'utiliser getTime().

Ovidiu Latcu
la source
5
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 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
Mon Dieu
la source
1
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!

    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();
    }
Bogdan
la source
2

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

}

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:

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 "";
     }
    } 

et l'utiliser avec:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
Ingo
la source
En une seule ligne <br/> <pre> <code> Calendar utcTime = Calendar.getInstance (). Add (Calendar.MILLISECOND, -time.getTimeZone (). GetOffset (time.getTimeInMillis ())); </pre> < / code>
Harun
1
Oui, mais cela appelle l'heure locale de l'appareil, qui pourrait être modifiée manuellement par l'utilisateur en une fausse DateTime
Ingo
2
public static void main(String args[]){
    LocalDate date=LocalDate.now();  
    System.out.println("Current date = "+date);
}
Arjun Singh
la source
1

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

Hitesh
la source
1

voici ma mise en œuvre:

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();    
}
Gal Rom
la source
1

Si vous voulez éviter d'analyser la date et que vous voulez juste un horodatage en GMT, vous pouvez utiliser:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));
Matthias van der Vlies
la source
0

Si vous utilisez l'heure Joda et que vous voulez l'heure actuelle en millisecondes sans votre décalage local, vous pouvez utiliser ceci:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
Managarm
la source
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));
    }
}

Production:

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

Vous pouvez modifier le format de date selon vos besoins.

santoshlokhande
la source
1
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 );

ou

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

selon le besoin de votre application.

Comme si
la source
(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.
Basil Bourque