yyyy - localdatetime java example
¿Por qué Java 8 ZonedDateTime piensa que 24:01 es una representación de cadena de tiempo válida? (1)
tl; dr
- Cambiar el patrón de formato de
kk
aHH
. - Su adición de un minuto es irrelevante.
2018-06-18 24:01
... se convierte en:
2018-06-18 00:01
Consejo: al realizar la depuración, use el formato estándar ISO 8601 predeterminado para generar una String
.
ZonedDateTime.now(
ZoneId.of( "Africa/Tunis" )
)
.truncatedTo( ChronoUnit.DAYS )
.with(
TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY )
)
.toString()
2018-06-18T00: 00 + 01: 00 [África / Túnez]
k
= 1-24 hora (en realidad, 24-23)
La respuesta eliminada por Jorn Vernee fue correcta: está utilizando k
que se documenta como la hora del día utilizando un reloj de 24 horas que va del 1 al 24.
Lo que no está tan claro en el documento es que la primera hora se cuenta como 24, en lugar de 0. Por lo tanto, podría decirse que el día va de 24 a 23, es decir, 24, 1, 2, 3, … , 22, 23
. El valor 24
representa la primera hora del día, no la última.
Aquí hay un ejemplo simple que usa la hora del día solo para demostrar este comportamiento.
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
Tenga en cuenta que este comportamiento kk
de java.time donde toda la primera hora del día se etiqueta 24
en inusual, no estándar y no se utiliza comúnmente. Ver Wikipedia . Aparentemente, este estilo se usa ocasionalmente en algunos contextos especiales donde el horario comercial se extiende más allá de la medianoche, como la transmisión.
En cuanto a lo que esperabas ...
debería ser 00:01 en una representación de reloj de 24 horas.
Si desea 0-23, use "H", como se documenta .
Primero, mire la salida con formato ISO 8601 predeterminada.
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 [América / Los_Angeles]
2018-06-24T00: 01-07: 00 [América / Los_Angeles]
Ahora, tu formato personalizado. Cambie su patrón de formato de kk
a 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
Semana
Algunas otras notas ...
Si está tratando de representar la semana, no es necesario agregar un minuto. La mejor práctica en general para representar un lapso de tiempo es el enfoque semiabierto donde el comienzo es inclusivo mientras que el final es exclusivo . Entonces, una semana comienza en el primer momento de un lunes y se extiende hasta, pero no incluye, el primer momento del siguiente lunes.
Además, recomiendo siempre pasar un ZoneId
explícitamente now
incluso si ese es ZoneId.systemDefault
para que sus intenciones sean nítidas.
Ajustarse al lunes tiene el problema de qué hacer si hoy ya es lunes. Utilice cualquiera de este par de implementaciones de TemporalAdjuster
encontradas en TemporalAdjusters
para especificar su elección de comportamiento:
Código de ejemplo.
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 ) ;
Para el rastreo y la depuración, siempre genere una Cadena que represente el valor de sus objetos de fecha y hora utilizando el formato estándar ISO 8601 en lugar de un formato personalizado como se ve en su pregunta. Las clases java.time utilizan los formatos estándar de forma predeterminada en sus métodos toString
.
String outputStart = weekStart.toString() ;
String outputStop = weekStop.toString() ;
2018-06-18T00: 00 + 01: 00 [África / Túnez]
2018-06-25T00: 00 + 01: 00 [África / Túnez]
Si desea valores de solo fecha, use LocalDateTime
.
Puede representar su rango de tiempo en un solo objeto utilizando las clases LocalDateRange
o Interval
encontradas en el proyecto ThreeTen-Extra .
Último consejo: deje que java.time haga el trabajo pesado utilizando los métodos DateTimeFormatter.ofLocalized…
para localizar automáticamente las cadenas generadas usando una configuración Locale
específica para determinar el lenguaje humano y las normas culturales de formato.
Necesito obtener dos instancias de ZonedDateTime que representan el comienzo y el final de la semana actual.
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);
Salida:
2018-06-18 24:01
2018-06-24 24:01
¿Qué representa esta cadena? ¿Es 1 minuto después de la medianoche, la mañana de 2018-06-18? Si es así, ¿por qué es 24:01 un tiempo válido? Pensé que debería ser 00:01 en una representación de reloj de 24 horas.
Edit: ¿y hay una manera de formatear esto para mostrar 00:01 en lugar de eso, sin transformar la cadena en una nueva cadena?