System.currentTimeMillis () renvoie-t-il l'heure UTC?

93

Je veux obtenir l'heure UTC actuelle en millis. J'ai cherché sur Google et j'ai obtenu des réponses indiquant que System.currentTimeMillis () renvoie l'heure UTC. mais ce n'est pas le cas. Si je fais ce qui suit:

long t1 = System.currentTimeMillis();
long t2 = new Date().getTime();
long t3 = Calendar.getInstance().getTimeInMillis();

les trois temps sont presque identiques (la différence est en millisecondes en raison des appels).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

et cette heure n'est pas l'heure UTC mais c'est mon fuseau horaire. Comment puis-je obtenir l'heure UTC actuelle dans Android?

g. révolution
la source
4
Renvoie l'heure système actuelle en millisecondes depuis le 1er janvier 1970 00:00:00 UTC
Blackbelt
3
long t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt
3
Le lien ci-dessus dit "Voir la description de la classe Date pour une discussion des légères divergences qui peuvent survenir entre" l'heure de l'ordinateur "et le temps universel coordonné (UTC)." et dans la documentation java.util.Date, vous trouvez: "Bien que la classe Date soit destinée à refléter le temps universel coordonné (UTC), elle peut ne pas le faire exactement, selon l'environnement hôte de la machine virtuelle Java" -> donc elle peut être possible que votre machine renvoie une heure non UTC
Marco Forberg
4
@ g.revolution: C'est "le nombre de millisecondes depuis le 1er janvier 1970 00:00:00 UTC" - comment vous attendez-vous à ce que cela s'ajuste pour un fuseau horaire? Votre fuseau horaire local n'affecte pas le nombre de millisecondes écoulées depuis cette époque.
Jon Skeet

Réponses:

132

Les trois lignes que vous avez affichées donneront le nombre de millisecondes depuis l'époque Unix, qui est un point fixe dans le temps, non affecté par votre fuseau horaire local.

Vous dites "cette heure n'est pas l'heure UTC" - je suppose que vous l'avez diagnostiqué incorrectement. Je suggérerais d'utiliser epochconverter.com pour cela. Par exemple, dans votre exemple:

1372060916 = Mon, 24 Jun 2013 08:01:56 GMT

Nous ne savons pas quand vous avez généré cette valeur, mais à moins que ce ne soit réellement à 8 h 01 UTC, c'est un problème avec votre horloge système.

Ni System.currentTimeMillisla valeur dans un Datelui-même ne sont affectées par le fuseau horaire. Cependant, vous devez être conscient que n'utilisez le fuseau horaire local, qui fourvoie de nombreux développeurs en pensant qu'un est intrinsèquement associé à un fuseau horaire - ce n'est pas, il est juste un instant dans le temps, sans fuseau horaire associé ou même système de calendrier.Date.toString() Date

Jon Skeet
la source
6
Donc, fondamentalement, c'est-à-dire que cette fonction renvoie la même valeur si elle est appelée en même temps à partir de différents fuseaux horaires, quelle que soit l'horloge de l'hôte, n'est-ce pas?
Phillip
14
Mec, cela me fait souhaiter que le monde adopte (pourrait) un seul fuseau horaire. Qui se soucie si le numéro sur l'horloge est 00h00 ou 08h00 lorsque la grande chose brillante apparaît dans le ciel? Les innombrables heures de temps par ailleurs productif gaspillé sur cette relique historique font bouillir mon sang ...
corsiKa
À ce propos, notez que l'appel sous-jacent à la fonction d'horloge du système d'exploitation a une «dérive» documentée de plusieurs millisecondes. Java a un «minuteur haute performance» si l'intention est d'obtenir une durée très précise d'une opération (chronométrage quand une tâche démarre et se termine, le delta étant le temps écoulé). Voir: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague
@JonSkeet si toString () utilise en interne le fuseau horaire, comment pourrais-je construire une chaîne à partir de celui-ci sans fuseau horaire. En fait, je génère un fichier sur le serveur REST dont le nom de fichier correspond exactement à la valeur de l'heure de minuit, ex "1551139200.json" (26 février 2019 à minuit) et qui doit être accessible à partir de l'application Android une fois que System.currentTimeMillis () de l'appareil renvoie l'heure exacte.
kiranking le
@kiranking: Utilisez Date.getTime()pour trouver le temps en millisecondes depuis l'époque Unix, divisez par 1000 (car ce nom de fichier est en secondes depuis l'époque Unix) et formatez simplement cet entier sous forme de chaîne.
Jon Skeet
3

Je peux confirmer que les trois appels pourraient dépendre de l'heure locale, compte tenu de l'époque, et non de la Date.toString()méthode ou d'une méthode similaire. Je les ai vus dépendre de l'heure locale sur des appareils spécifiques exécutant Android 2.3. Je ne les ai pas testés avec d'autres appareils et versions Android. Dans ce cas, l'heure locale a été réglée manuellement.

Le seul moyen fiable d'obtenir une heure UTC indépendante est de demander une mise à jour de l'emplacement à l'aide du GPS_PROVIDER. La getTime()valeur d'un emplacement récupéré NETWORK_PROVIDERdépend également de l'heure locale. Une autre option consiste à envoyer un ping à un serveur qui renvoie un horodatage UTC, par exemple.

Donc, ce que je fais est le suivant:

public static String getUTCstring(Location location) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String date = sdf.format(new Date(location.getTime()));
    // Append the string "UTC" to the date
    if(!date.contains("UTC")) {
        date += " UTC";
    }
    return date;
}
jlhonora
la source
1
System.currentTimeMillis () renvoie une valeur basée sur UTC. Quant à la «précision» ou l'exactitude de l'horloge du système d'exploitation, bien que cela affecte certainement le résultat, elle n'est en aucun cas liée à la valeur du fuseau horaire du système ou de l'environnement Java.
Darrell Teague
@DarrellTeague J'insiste, j'ai vu des valeurs différentes dans un appareil Huawei spécifique. Donc non, il ne renvoie pas toujours l'heure UTC correcte (en
ignorant les
La question du PO portait sur l'utilisation d'un fuseau horaire de classe Java. Ce n'était pas une question de matériel ou de précision de la valeur de temps renvoyée. En termes simples, la JVM tire son heure de l '"horloge système" (abstraite) d'exploitation (qui varie selon le système d'exploitation en termes de fonctionnement). Voir aussi: drdobbs.com/embedded-systems / ... et implémentations "C" sur les systèmes d'exploitation chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague