zoneid yyyy ofpattern localdatetime example datetimeformatter java datetime java-8

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 a HH .
  • 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?