util - ¿Hay alguna forma de convertir ZoneId a ZoneOffset en java 8?
timezone getavailableids() (6)
Tengo un segundo de época y un zoneId, por método1.Se puede convertir a LocalDateTime con zoneId predeterminado del sistema, pero no encuentro la forma de convertir el segundo de época a LocalDateTime por método2, porque no hay
ZoneOffset.systemDefault
. Creo Es oscuro.
import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}
val epochSecond = System.currentTimeMillis() / 1000
LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault())//method1
LocalDateTime.ofEpochSecond(epochSecond, 0, ZoneOffset.MAX)//method2
tl; dr
ZonedDateTime.now(
ZoneId.of( "America/Montreal" )
)
... de la zona horaria predeterminada actual ...
ZonedDateTime.now(
ZoneId.systemDefault()
)
Detalles
La respuesta de Stanislav Bshkyrtsev responde correcta y directamente a su pregunta.
Pero, hay problemas más grandes involucrados, como se sugiere en la Respuesta de Jon Skeet .
LocalDateTime
No encuentro la forma de convertir epoch second a LocalDateTime
LocalDateTime
deliberadamente no tiene un concepto de zona horaria o desplazamiento desde UTC.
No es probable lo que quieres.
El
Local…
significa
cualquier
localidad, no una localidad en particular.
Esta clase
no
representa un momento, solo momentos
potenciales
en un rango de aproximadamente 26-27 horas (el rango de zonas horarias en todo el mundo).
Instant
No es necesario comenzar con segundos de época si está intentando obtener la hora actual.
Obtenga el
Instant
actual.
La clase
Instant
representa un momento en la línea de tiempo en
UTC
con una resolución de
nanoseconds
(hasta nueve (9) dígitos de una fracción decimal).
Instant instant = Instant.now();
Dentro de ese
Instant
hay un recuento de
nanoseconds
de la época.
Pero en realidad no nos importa.
ZonedDateTime
Si desea ver ese momento a través de la lente del reloj de pared de una región en particular, aplique un
ZoneId
para obtener un
ZonedDateTime
.
ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );
Como atajo, puede hacerlo directamente a
ZonedDateTime
.
ZonedDateTime zdt = ZonedDateTime.now( z );
Un
ZonedDateTime
tiene un
Instant
dentro de él.
Llame a
zdt.toInstant()
para obtener el mismo momento en el tiempo que un valor básico en
UTC
.
El mismo número de nanosegundos desde la época en ambos sentidos, como
ZonedDateTime
o como
Instant
.
Segundos desde la época dada
Si recibe un recuento de segundos desde la época, y la época es el primer momento de 1970 en
UTC
(
1970-01-01T00:00:00Z
), entonces
1970-01-01T00:00:00Z
ese número en
Instant
.
long secondsSinceEpoch = 1_484_063_246L ;
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch ) ;
Sobre java.time
El marco
java.time
está integrado en Java 8 y
java.time
posteriores.
Estas clases suplantan a las antiguas y problemáticas clases de fecha y hora
legacy
, como
java.util.Date
,
Calendar
y
SimpleDateFormat
.
Para obtener más información, consulte el Tutorial de Oracle . Y busque para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Puede intercambiar objetos
java.time
directamente con su base de datos.
Utilice un
controlador JDBC
compatible con
JDBC 4.2
o posterior.
No necesita cadenas, no necesita clases
java.sql.*
.
¿Dónde obtener las clases java.time?
-
Java SE 8
,
Java SE 9
,
Java SE 10
,
Java SE 11
y versiones posteriores: parte de la API Java estándar con una implementación integrada.
- Java 9 agrega algunas características menores y correcciones.
-
Java SE 6
y
Java SE 7
- La mayor parte de la funcionalidad java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
-
Android
- Versiones posteriores de las implementaciones de paquetes de Android de las clases java.time .
- Para Android anterior (<26), el proyecto ThreeTen-Backport adapta ThreeTen-Backport (mencionado anteriormente). Vea Cómo usar ThreeTenABP ...
El proyecto
ThreeTen-Extra
extiende java.time con clases adicionales.
Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time.
Puede encontrar algunas clases útiles aquí, como
Interval
,
YearWeek
,
YearQuarter
y
more
.
Así es como puede obtener
ZoneOffset
desde
ZoneId
:
Instant instant = Instant.now(); //can be LocalDateTime
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);
NB:
ZoneId
puede tener un desplazamiento diferente según el punto en el tiempo y el historial del lugar en particular.
Por lo tanto, elegir diferentes instantes daría como resultado diferentes compensaciones.
Como dice la documentation , "Esto está destinado principalmente a conversiones de bajo nivel en lugar del uso general de la aplicación".
Ir a través de
Instant
tiene mucho sentido para mí: su segunda época es efectivamente una representación diferente de un
Instant
, así que conviértalo en un
Instant
y luego conviértalo en una zona horaria particular.
Espero que las dos primeras líneas de mi solución a continuación sean útiles.
Mi problema era que tenía un
LocalDateTime
y el nombre de una zona horaria, y necesitaba un
instant
para poder construir un
java.util.Date
, porque eso es lo que MongoDB quería.
Mi código es Scala, pero aquí está tan cerca de Java que creo que no debería haber ningún problema para entenderlo:
val zid = ZoneId.of(tzName) // "America/Los_Angeles"
val zo: ZoneOffset = zid.getRules.getOffset(localDateTime) // ⇒ -07:00
// 2017-03-16T18:03
val odt = OffsetDateTime.of(localDateTime, zo) // ⇒ 2017-03-16T18:03:00-07:00
val instant = odt.toInstant // ⇒ 2017-03-17T01:03:00Z
val issued = Date.from(instant)
Lo siguiente devuelve la cantidad de tiempo en milisegundos para agregar a UTC para obtener la hora estándar en esta zona horaria:
TimeZone.getTimeZone(ZoneId.of("Europe/Amsterdam")).getRawOffset()
No hay mapeo uno a uno. Un ZoneId define una extensión geográfica en la que se utiliza un conjunto de ZoneOffsets diferentes a lo largo del tiempo. Si la zona horaria utiliza el horario de verano, su ZoneOffset será diferente entre verano e invierno.
Además, las reglas del horario de verano pueden haber cambiado con el tiempo, por lo que ZoneOffset podría ser diferente, por ejemplo, 13/10/2015 en comparación con 13/10/1980.
Por lo tanto, solo puede encontrar ZoneOffset para un ZoneId en un instante en particular.
Ver también https://en.wikipedia.org/wiki/Tz_database