27 votes

Pourquoi Java 8 ZonedDateTime pense que 24:01 est une représentation de chaîne de temps valide?

J'ai besoin d'obtenir deux instances ZonedDateTime représentant le début et la fin de la semaine en cours.

 ZonedDateTime currentDateTime = ZonedDateTime.now();
ZonedDateTime startOfThisWeek = currentDateTime.with(DayOfWeek.MONDAY).truncatedTo(ChronoUnit.DAYS).plusMinutes(1);
ZonedDateTime endOfThisWeek = startOfThisWeek.plusDays(6);
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd kk:mm");
String startweek = startOfThisWeek.format(df);
String endweek = endOfThisWeek.format(df);
System.out.println(startweek);
System.out.println(endweek);
 

Production:

 2018-06-18 24:01
2018-06-24 24:01
 

Que représente cette chaîne? Est-ce 1 minute après minuit, le matin du 18/06/2018? Si oui, pourquoi 24:01 est-il une heure valide? Je pensais qu'il devrait être 00:01 dans une représentation d'horloge de 24 heures.

Edit: et existe-t-il un moyen de formater cela pour afficher 00:01 à la place sans transformer la chaîne en une nouvelle chaîne?

37voto

Basil Bourque Points 8938

tl;dr

  • Modifier la mise en forme du motif à partir d' kk de HH.
  • Votre plus d'une minute n'est pas pertinent.

2018-06-18 24:01

...devient:

2018-06-18 00:01

Astuce: Lors du débogage, utilisez la valeur par défaut standard ISO 8601 format dans la génération d' String.

ZonedDateTime.now( 
    ZoneId.of( "Africa/Tunis" ) 
)
.truncatedTo( ChronoUnit.DAYS )
.with( 
    TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) 
)
.toString()

2018-06-18T00:00+01:00[Africa/Tunis]

k = 1-24 heures (en fait, 24-23)

L' supprimé Réponse par Jorn Vernee était correcte: à l'aide d' k qui est documenté comme représentant l'heure de la journée à l'aide d'une horloge de 24 heures allant de 1 à 24.

Ce n'est pas si clair dans la doc, c'est que la première heure est comptée comme 24, au lieu de 0. Alors il serait peut-être mieux indiqué pour dire que cette journée se déroule à partir de 24-23, qui est, 24, 1, 2, 3, … , 22, 23. La valeur 24 représente la première heure de la journée, pas la dernière.

Voici un exemple simple d'utilisation de temps de jour seulement pour illustrer ce comportement.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "kk:mm" );
LocalTime lt = LocalTime.MIN;
String output = lt.format( f );

System.out.println( lt.toString() );  // Standard ISO 8601 format, 00-24.
System.out.println( output );         // `kk` format is 24, 1 , 2, … , 22 , 23.

00:00

24:00

Notez que ce kk comportement de java.le temps où l'ensemble de la première heure de la journée est étiqueté 24 inhabituels, non-standard, et n'est généralement pas utilisé. Voir Wikipedia. Apparemment, ce style est utilisé occasionnellement dans certains contextes où les heures s'étendre au-delà de minuit, tels que la radiodiffusion.

Quant à ce qui vous attend...

il convient de 00:01 à 24 heures de représentation.

Si vous voulez 0-23, utiliser le "H", comme documenté.

Tout d'abord, regardez la valeur par défaut ISO 8601 sortie formatée.

ZonedDateTime currentDateTime = ZonedDateTime.now();
ZonedDateTime startOfThisWeek = currentDateTime.with( DayOfWeek.MONDAY ).truncatedTo( ChronoUnit.DAYS ).plusMinutes( 1 );
ZonedDateTime endOfThisWeek = startOfThisWeek.plusDays( 6 );
System.out.println( startOfThisWeek );
System.out.println( endOfThisWeek );

2018-06-18T00:01 à 07:00[America/Los_Angeles]

2018-06-24T00:01 à 07:00[America/Los_Angeles]

Maintenant, votre format personnalisé. Changer votre format de kk de HH.

DateTimeFormatter df = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" );
String startweek = startOfThisWeek.format( df );
String endweek = endOfThisWeek.format( df );
System.out.println( startweek );
System.out.println( endweek );

2018-06-18 00:01

2018-06-24 00:01

Semaine

Certains autres notes...

Si vous êtes en essayant de représenter la semaine, il n'est pas nécessaire d'ajouter une minute. Généralement les meilleures pratiques en représentant un laps de temps est la Demi-approche Ouverte où le début est inclusive alors que la fin est exclusif. Une semaine commence le premier moment de un lundi et se poursuit jusqu'à, mais ne comprennent pas, le premier moment de le lundi suivant.

Aussi, je recommande toujours le passage d'un ZoneId explicitement now même si ZoneId.systemDefault pour faire vos intentions crystal-clair.

Réglage de lundi a la question de savoir quoi faire si aujourd'hui, c'est déjà lundi. Utiliser de cette paire de TemporalAdjuster des implémentations trouvé en TemporalAdjusters de spécifier votre choix de comportement:

Exemple de code.

ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "Africa/Tunis" ) ) ;  // Or `ZoneId.systemDefault()`.
ZonedDateTime weekStart = now.truncatedTo( ChronoUnit.DAYS ).with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) );
ZonedDateTime weekStop = weekStart.plusWeeks( 1L ) ;

Pour le suivi et le débogage, toujours générer une Chaîne de caractères représentant la valeur de votre date-heure d'objets en utilisant la norme ISO 8601 format plutôt qu'un format personnalisé comme vu votre Question. Le java.temps classes utilisent les formats standard par défaut dans leur toString méthodes.

String outputStart = weekStart.toString() ;
String outputStop = weekStop.toString() ;

2018-06-18T00:00+01:00[Africa/Tunis]

2018-06-25T00:00+01:00[Africa/Tunis]

Si vous voulez de date uniquement les valeurs, utilisez l' LocalDateTime.

Vous pouvez représenter votre plage de temps dans un seul objet à l'aide de l' LocalDateRange ou Interval classes trouvées dans le ThreeTen-Extra projet.

Dernier conseil: Laissez java.le temps de faire le gros du travail en utilisant DateTimeFormatter.ofLocalized… méthodes pour localiser automatiquement générés chaînes à l'aide d'un certain Locale pour déterminer le langage humain et les normes culturelles de la mise en forme.

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