Problème de décalage horaire avec un Calendar

Problème de décalage horaire avec un Calendar - Java - Programmation

Marsh Posté le 07-12-2011 à 18:27:56    

Bonjour
 
Je rencontre un pb avec les Calendar de Java.
 
Dans mon appli, je reçois une date d'un système externe. Cette date est récupérée sous forme de Calendar.
Or, je me rends compte que les champs ne correspondent pas à l'heure exacte reçue.
On voit dans la trace suivante que "HOUR_OF_DAY=15,MINUTE=56,SECOND=39". Or, lorsque je formate la date pour l'afficher j'obtiens "16:56:39"
 

Code :
  1. maDate = java.util.GregorianCalendar[time=1323446199105,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo
  2. [id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,
  3. YEAR=2011,MONTH=11,WEEK_OF_YEAR=49,WEEK_OF_MONTH=2,DAY_OF_MONTH=9,DAY_OF_YEAR=343,DAY_OF_WEEK=6,
  4. DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=3,HOUR_OF_DAY=15,MINUTE=56,SECOND=39,MILLISECOND=105,ZONE_OFFSET=0,DST_OFFSET=0]
  5. maDate time = 1323446199105
  6. maDateFormattee = 09-12-2011 16:56:39


 
Cela me pose un problème car je dois modifier cette heure à 20h.
Or, lorsque je positionne l'heure à 20h avec "maDate.set(Calendar.HOUR_OF_DAY, 20);"
j'obtiens également 1h de décalage, et l'heure affichée est 21h.
 
Pour quelle raison y a-t-il une heure de décalage entre l'heure affichée et le Calendar ?
Est-ce du aux locales ?...
Comment peut-on récupérer ce décalage pour ajuster l'heure que je vais positionner ? Visiblement, l'offset du TimeZone est à 0... Je ne peux donc même pas me baser dessus...
 
Merci d'avance pour votre aide.


Message édité par flexx35 le 07-12-2011 à 19:06:43
Reply

Marsh Posté le 07-12-2011 à 18:27:56   

Reply

Marsh Posté le 07-12-2011 à 19:20:39    

http://www.javaworld.com/javaworld [...] -time.html
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-12-2011 à 19:27:42    

Merci pour ta réponse.
 
En fait, maintenant, pour afficher la date, j'utilise tout simplement la classe Date : maDate.getTime().toString()
 

Code :
  1. maDate = java.util.GregorianCalendar[time=1323451647070,areFieldsSet=true,areAllFeldsSet=true,lenient=true,
  2. zone=sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,
  3. minimalDaysInFirstWeek=4,ERA=1,YEAR=2011,MONTH=11,WEEK_OF_YEAR=49,WEEK_OF_MONTH=2,DAY_OF_MONTH=9,DAY_OF_YEAR=343,
  4. DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=27,SECOND=27,MILLISECOND=70,ZONE_OFFSET=0,DST_OFFSET=0]
  5. maDate = Fri Dec 09 18:27:27 CET 2011
  6. TimeZone = TimeZone = sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDalight=false,transitions=0,lastRule=null]


 
On voit donc toujours que "HOUR_OF_DAY=17,MINUTE=27,SECOND=27"
alors que la date est "Fri Dec 09 18:27:27 CET 2011"
 
Le TimeZone montre un offset à 0 et ZONE_OFFSET=0,DST_OFFSET=0.
Je ne sais pas comment faire pour récupérer le décalage (à part faire une bidouille pour comparer l'heure récupérée avec Date et l'heure présente dans HOUR_OF_DAY...).
 
Par contre, en local sur ma machine, quand je fais des tests avec la classe Calendar, j'obtiens un "ZoneInfo[id="Europe/Paris",offset=3600000,..." avec un offset d'une heure. Mais pas sur le serveur...
 
 
Edit :
 
Je viens de faire un nouveau test en mettant la date de mon serveur au 1er Juiller à 13h. On est donc en heure d'été.
 
J'obtiens ceci :
maDate = java.util.GregorianCalendar[time=1311161769991,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo
[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2011,MONTH=6,
WEEK_OF_YEAR=29,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=201,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,
AM_PM=0,HOUR=11,HOUR_OF_DAY=11,MINUTE=36,SECOND=9,MILLISECOND=991,ZONE_OFFSET=0,DST_OFFSET=0]
 
et maDate = Wed Jul 20 13:36:09 CEST 2011
 
On retrouve donc une différence de 2h en heure d'été, et 1h en heure d'hiver.
 
Je voudrais donc juste savoir comment récupérer ce décalage horaire automatiquement à partir du TimeZone (ou du Calendar).
Parce que là j'ai que des offset à 0...
 
 
 


Message édité par flexx35 le 07-12-2011 à 19:58:50
Reply

Marsh Posté le 07-12-2011 à 21:33:40    

>> On retrouve donc une différence de 2h en heure d'été, et 1h en heure d'hiver.  
C'est typiquement le décalage de l'heure locale par rapport à l'heure GMT, ça.
Je sais pas comment tu formates ta date, mais à priori, il faut faire l'inverse de ce qui est fait ici:

Code :
  1. import java.util.*;
  2. import java.text.*;
  3. public class CurrentTimeToGMT{
  4.  public static void main(String args[]){
  5.    Date date = new Date();
  6.    DateFormat gmtFormat = new SimpleDateFormat();
  7.    TimeZone gmtTime = TimeZone.getTimeZone("GMT" );
  8.    gmtFormat.setTimeZone(gmtTime);
  9.    System.out.println("Current Time: "+date);
  10.    System.out.println("GMT Time: " + gmtFormat.format(date));
  11.  
  12.  }
  13. }


A+,


Message édité par gilou le 07-12-2011 à 21:39:27

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-12-2011 à 21:38:11    

Oui bien sûr, mais sais-tu comment récupérer cette valeur du décalage horaire  ? Les offsets sont à 0...

Reply

Marsh Posté le 07-12-2011 à 21:45:33    

DateFormat localFormat = new SimpleDateFormat();
TimeZone localTime = TimeZone.getTimeZone("GMT+01" );
localFormat.setTimeZone(localTime);
et utiliser cela pour formater ta date, non?
System.out.println(localFormat.format(date));
Comme j'ai dit, je sais pas comment tu obtiens ta date formatée.
A+,


Message édité par gilou le 07-12-2011 à 21:49:54

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-12-2011 à 22:12:44    

Merci pour ton aide.
 
En fait, pour tracer la date, j'utilise simplement : monCalendar.getTime().toString()
 
Je récupère un objet Date en appelant la méthode getTime() sur le Calendar, puis je l'affiche avec toString().
 
Ce qui m'étonne donc c'est d'avoir un Calendar avec un HOUR à 8 par exemple, et une date issue du calendar (avec getTime) à 9, alors que les offset sont à 0.
 
Donc ça s'est sur le serveur, mais quand je fais un test dans un main en local j'obtiens ceci :
 

Code :
  1. Calendar monCalendar = Calendar.getInstance();
  2. System.out.println("monCalendar (objet Calendar) = " + monCalendar.toString());
  3. System.out.println("monCalendar (objet Date obtenue avec getTime) = " + monCalendar.getTime().toString());
  4. monCalendar (objet Calendar) = java.util.GregorianCalendar[time=1323291836775,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.
  5. ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone
  6. [id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,
  7. startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],
  8. firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2011,MONTH=11,WEEK_OF_YEAR=49,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=341,
  9. DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=10,HOUR_OF_DAY=22,MINUTE=3,SECOND=56,MILLISECOND=775,ZONE_OFFSET=3600000,DST_OFFSET=0]
  10. monCalendar (objet Date obtenue avec getTime) = Wed Dec 07 22:03:56 CET 2011


 
Donc là je n'ai pas de différence entre HOUR_OF_DAY qui vaut 22 et l'heure retournée par l'objet Date.
En en plus, on voit que l'offset est à 3600000.

Reply

Marsh Posté le 07-12-2011 à 23:37:56    

ZONE_OFFSET=3600000 en millisecondes, soit 1h ça signifie qu'il y a un décalage d'une heure par rapport a l'heure GMT, ce qui est normal puisque tu es en zone Europe/Paris; en heure d'hiver
 
Pour en revenir a ton problème initial: ta date
>> [id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,
YEAR=2011,MONTH=11,WEEK_OF_YEAR=49,WEEK_OF_MONTH=2,DAY_OF_MONTH=9,DAY_OF_YEAR=343,DAY_OF_WEEK=6,
DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=3,HOUR_OF_DAY=15,MINUTE=56,SECOND=39,MILLISECOND=105,ZONE_OFFSET=0,DST_OFFSET=0]
Elle est en zone GMT, donc ZONE_OFFSET=0, DST_OFFSET=0 c'est cohérent.
Si tu fais
>> Or, lorsque je positionne l'heure à 20h avec "maDate.set(Calendar.HOUR_OF_DAY, 20);"  
tu positionnes l'heure de ta date (donc toujours dans le systeme GMT, qui est celui de ta date) a 20.
Et quand tu formates et que tu as 21h, c'est parce que quelque chose dans le formatage doit convertir cela en heure locale.
 
>>  En fait, pour tracer la date, j'utilise simplement : monCalendar.getTime().toString()  
C'est le toString qui tient compte de la zone locale et fait les conversions necessaires.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-12-2011 à 10:17:17    

Alors, finalement, je m'en suis sorti en créant un nouveau Calendar à partir de l'ancien et en changeant l'heure de ce nouveau Calendar.
 
Apparemment, pas mal de gens ont eu des problèmes similaires avec les Calendar et m'ont conseillé d'utiliser joda-time.
 
Merci en tous les cas pour votre aide.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed