4 votes

Décalage horaire - résultat étrange

J'ai un code très simple qui calcule la différence entre deux temps :

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

public class JavaApplication8 {
    private static final SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm:ss.SSS");

    public static void main(String[] args) throws InterruptedException {
        Date start = GregorianCalendar.getInstance().getTime();
        Thread.sleep(100);
        Date end   = GregorianCalendar.getInstance().getTime();

        long diff = end.getTime() - start.getTime();
        System.out.println(timeFormat.format(diff));
    }
}

mais il imprime 01:00:00.100 au lieu de 00:00:00.100 Pourquoi ?

5voto

Selvaraj Points 706

Autre façon de résoudre ce problème. En fait, la différence de temps que vous avez n'est pas en millisecondes de l'heure actuelle. C'est juste une différence de temps, donc faites une simple division de ce que vous pouvez avoir heures:minutes:secondes. Et c'est assez rapide.

Date start = GregorianCalendar.getInstance().getTime();
        Thread.sleep(100);
        Date end = GregorianCalendar.getInstance().getTime();

        long longVal = end.getTime() - start.getTime();

        long hours = longVal / 3600000;
        long mins = (longVal % 3600) / 60000;
        long secs = longVal % 60000;

        System.out.println(hours + " " + mins + " " + secs);

4voto

Rohit Jain Points 90368

C'est un problème de fuseau horaire. DateFormat.format() formatera par défaut la date dans votre fuseau horaire par défaut, ce qui semble être UTC+1 .

Vous devez définir le fuseau horaire pour timeFormat a UTC :

timeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(timeFormat.format(diff));

Vous devez également utiliser HH au lieu de hh dans votre DateFormat. hh est pour l'horloge de 12 heures.

new SimpleDateFormat("HH:mm:ss.SSS");

Mise à jour :

Mais il y a un autre problème majeur. Actuellement, vous essayez de formater une durée, ce que vous ne devriez pas faire. L'API Java Date n'a pas de concept de période ou de durée.

La valeur que vous obtenez par le formatage n'est rien d'autre que le nombre de millisecondes (équivalent à la différence) depuis l'époque. Il renvoie un Date à la place. Le résultat peut sembler correct, mais techniquement, la différence entre deux dates désigne une période ou une durée, ce qui n'est pas la même chose que la date (qui désigne un instant particulier du temps).

Vous devriez envisager de déménager à Joda Time pour cette tâche, qui possède des classes représentant ces concepts comme Period , Instant y Duration .

4voto

stefan.schwetschke Points 5143

Vous avez mélangé deux concepts :

  • Vous mesurez un intervalle de temps (différence entre DEUX points dans le temps).
  • Vous imprimez une date (UN seul moment dans le temps).

Les deux ne sont pas compatibles, vous obtiendrez toujours des effets aussi étranges. Dans votre cas, comme indiqué dans les autres commentaires, le fuseau horaire est mélangé. Le concept de fuseau horaire n'existe que pour les dates (point dans le temps), mais n'a aucun sens pour les intervalles.

Vous pouvez utiliser la bibliothèque Jodatime ou la JSR 310 : Date and Time API (à venir avec Java 8 je pense).

Avec Jodatime, vous pouvez explicitement construire un intervalle :

DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);
Period period = new Period(start, end);

et ensuite le formater avec un PeriodFormatter

PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder()
   .appendDays()
   .appendSuffix(" day", " days")
    .appendSeparator(" and ")
    .appendMinutes()
    .appendSuffix(" minute", " minutes")
    .appendSeparator(" and ")
    .appendSeconds()
    .appendSuffix(" second", " seconds")
    .toFormatter();

System.out.println(daysHoursMinutes.print(period));

En séparant les concepts d'UN point dans le temps et du temps entre DEUX points dans le temps, vous pouvez vous assurer qu'il n'y a pas d'autres surprises (par exemple, les secondes intercalaires).

0voto

m0skit0 Points 10269

Parce que votre fuseau horaire est GMT+1.

Si vous lisez la documentation vous trouverez ce que getTime() fait :

Renvoie le nombre de millisecondes depuis le 1er janvier 1970, 00:00:00 GMT représenté par cet objet Date.

Donc 100 ms signifie January 1, 1970, 00:00:00.100 GMT qui est January 1, 1970, 01:00:00.100 GMT+1 .

Vous pouvez simplement définir le fuseau horaire dans lequel vous souhaitez que votre heure soit convertie :

timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));

Et vous voulez un format de type 24 heures : HH:mm:ss.SSS sinon, il affichera 12 heures au lieu de 00 heure.

EDIT : comme jarnbjo Vous essayez d'appliquer un formateur de date à un intervalle de temps, ce qui ne fonctionnera évidemment pas comme vous le souhaitez. Il n'existe pas de formateur d'intervalle de temps dans l'API Java. Vous devrez écrire le vôtre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X