Convertir LocalDateTime a LocalDateTime en UTC

82

Convierta LocalDateTime a LocalDateTime en UTC.

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}

Busqué en la red. Pero no obtuve una solución

Sarika. S
fuente
4
¿Encontraste el javadoc para LocalDateTime? Dice: "Esta clase no almacena ni representa una zona horaria. En cambio, es una descripción de la fecha, como se usa para los cumpleaños, combinada con la hora local como se ve en un reloj de pared. No puede representar un instante en el línea de tiempo sin información adicional como un desplazamiento o una zona horaria ".
aro_tech
1
Su pregunta no tiene sentido; debe explicar el contexto de este método y lo que está tratando de lograr. Parece que tiene un malentendido fundamental de lo que representan las diversas clases de API.
assylias
3
Si le importan las zonas horarias, debe usar ZonedDateTime, que tiene métodos de conversión entre zonas horarias conZoneSameLocal () y withZoneSameInstant ()
JodaStephen
Ya. Entendí. Gracias
Sarika.

Respuestas:

104

Yo personalmente prefiero

LocalDateTime.now(ZoneOffset.UTC);

ya que es la opción más legible.

slorinc
fuente
19
¿No crea esto un nuevo tiempo (ahora)? La pregunta original era sobre la conversión de una hora conocida a UTC
Evvo
73

Hay una forma aún más sencilla

LocalDateTime.now(Clock.systemUTC())
Leon Radley
fuente
21
Agradable, pero no responde a la pregunta original.
eirirlar
2
Esta respuesta convierte una fecha UTC en LocalDate. La pregunta original era cómo convertir un LocalDate en una fecha UTC.
Cypress Frankenfeld
57

LocalDateTime no contiene información de zona. ZonedDatetime lo hace.

Si desea convertir LocalDateTime a UTC, debe ajustar por puño ZonedDateTime.

Puede convertir como el siguiente.

LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.toLocalTime());

ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());

ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));

System.out.println(utcZoned.toLocalTime());
Fatih Arslan
fuente
2
Esto es correcto, aunque técnicamente no está envuelto. ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))mientras que conciso todavía transmite suficiente significado para no necesitar la variable de instancia zonificada.
Brett Ryan
19
ZoneOffset.UTCes un buen reemplazo paraZoneI‌​d.of("UTC")
ycomp
2
Para UTC, OffsetDateTimees más apropiado que ZonedDateTime. Uso: OffsetDateTime.now( ZoneOffset.UTC )omyInstant.atOffset( ZoneOffset.UTC )
Basil Bourque
15

Utilice el siguiente. Toma la fecha y hora local y la convierte a UTC utilizando la zona horaria. No es necesario que cree su función.

ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());

Si necesita obtener la parte LocalDateTime de ZonedDateTime, puede usar lo siguiente.

nowUTC.toLocalDateTime();

Aquí hay un método estático que uso en mi aplicación para insertar la hora UTC en mysql ya que no puedo agregar un valor predeterminado UTC_TIMESTAMP a una columna de fecha y hora.

public static LocalDateTime getLocalDateTimeInUTC(){
    ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);

    return nowUTC.toLocalDateTime();
}
patelb
fuente
14

Aquí hay una pequeña clase de utilidad simple que puede usar para convertir la fecha y hora local de una zona a otra, incluido un método de utilidad directamente para convertir una fecha y hora local de la zona actual a UTC (con el método principal para que pueda ejecutarlo y ver los resultados de una prueba simple):

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public final class DateTimeUtil {
    private DateTimeUtil() {
        super();
    }

    public static void main(final String... args) {
        final LocalDateTime now = LocalDateTime.now();
        final LocalDateTime utc = DateTimeUtil.toUtc(now);

        System.out.println("Now: " + now);
        System.out.println("UTC: " + utc);
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
        final ZonedDateTime zonedtime = time.atZone(fromZone);
        final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
        return converted.toLocalDateTime();
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone) {
        return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
    }

    public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
        return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
    }

    public static LocalDateTime toUtc(final LocalDateTime time) {
        return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
    }
}
ManoDestra
fuente
También agregue: final LocalDateTime backToLocal = DateTimeUtil.toZone (utc, ZoneOffset.UTC, ZoneId.systemDefault ()); System.out.println ("Volver a local:" + backToLocal);
rjdkolb
7

¿Pregunta?

Mirando las respuestas y la pregunta, parece que la pregunta se ha modificado significativamente. Entonces, para responder a la pregunta actual:

Convierta LocalDateTime a LocalDateTime en UTC.

¿Zona horaria?

LocalDateTimeno almacena ninguna información sobre la zona horaria, básicamente contiene los valores de año, mes, día, hora, minuto, segundo y unidades más pequeñas. Entonces, una pregunta importante es: ¿Cuál es la zona horaria del original LocalDateTime? También podría ser UTC, por lo que no es necesario realizar ninguna conversión.

Zona horaria predeterminada del sistema

Teniendo en cuenta que hizo la pregunta de todos modos, probablemente quiso decir que la hora original está en la zona horaria predeterminada de su sistema y desea convertirla a UTC. Porque generalmente LocalDateTimese crea un objeto usando LocalDateTime.now()que devuelve la hora actual en la zona horaria predeterminada del sistema. En este caso, la conversión sería la siguiente:

LocalDateTime convertToUtc(LocalDateTime time) {
    return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

Un ejemplo del proceso de conversión:

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 10:39 // [toLocalDateTime] losing the timezone information

Zona horaria explícita

En cualquier otro caso, cuando especificas explícitamente la zona horaria del tiempo para convertir, la conversión sería la siguiente:

LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
    return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

Un ejemplo del proceso de conversión:

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 09:39 // [toLocalDateTime] losing the timezone information

El atZone()método

El resultado del atZone()método depende del tiempo transcurrido como argumento, porque considera todas las reglas de la zona horaria, incluido el horario de verano (DST). En los ejemplos, la hora era el 25 de febrero, en Europa esto significa horario de invierno (sin horario de verano).

Si usáramos una fecha diferente, digamos el 25 de agosto del año pasado, el resultado sería diferente, considerando el horario de verano:

2018-08-25 11:39 // [time] original LocalDateTime without a timezone
2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2018-08-25 08:39 // [toLocalDateTime] losing the timezone information

La hora GMT no cambia. Por lo tanto, se ajustan las compensaciones en las otras zonas horarias. En este ejemplo, el horario de verano de Estonia es GMT + 3 y el horario de invierno GMT + 2.

Además, si especifica una hora dentro de la transición de cambio de reloj hacia atrás una hora. Por ejemplo, el 28 de octubre de 2018 a las 03:30 para Estonia, esto puede significar dos horarios diferentes:

2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]

Sin especificar el desplazamiento manualmente (GMT + 2 o GMT + 3), la hora 03:30de la zona horaria Europe/Tallinnpuede significar dos horas UTC diferentes y dos desplazamientos diferentes.

Resumen

Como puede ver, el resultado final depende de la zona horaria del tiempo transcurrido como argumento. Debido a que la zona horaria no se puede extraer del LocalDateTimeobjeto, debe saber usted mismo de qué zona horaria proviene para convertirlo a UTC.

anddero
fuente
1
¡gracias por la información sobre LocalDateTime no almacena ninguna información sobre la zona horaria! LocalDateTime does not store any information about the time-zone, it just basically holds the values of year, month, day, hour, minute, second, and smaller units.
LiuWenbin_NO.
5

tldr: simplemente no hay forma de hacer eso; si está intentando hacer eso, se equivoca LocalDateTime .

La razón es que LocalDateTime no registra la zona horaria después de que se crean las instancias. No puede convertir una fecha y hora sin zona horaria en otra fecha y hora basada en una zona horaria específica.

De hecho, LocalDateTime.now () nunca debe llamarse en el código de producción a menos que su propósito sea obtener resultados aleatorios. Cuando construye una instancia LocalDateTime como esa, esta instancia contiene la fecha y la hora ÚNICAMENTE en función de la zona horaria del servidor actual, lo que significa que este fragmento de código generará un resultado diferente si está ejecutando un servidor con una configuración de zona horaria diferente.

LocalDateTime puede simplificar el cálculo de fechas. Si desea un tiempo de datos real y universalmente utilizable, use ZonedDateTime o OffsetDateTime: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html .

Andrew Feng
fuente
LocalDateTime no registra la zona horaria, pero puede tener este conocimiento de otro lugar y agregar esta información a su LocalDateTimes antes de la conversión.
Tristan
0

Intente esto usando este método.

convierta su LocalDateTimea ZonedDateTimeusando el método of y pase la zona horaria predeterminada del sistema o puede usar ZoneId de su zona comoZoneId.of("Australia/Sydney");

LocalDateTime convertToUtc(LocalDateTime dateTime) {
  ZonedDateTime dateTimeInMyZone = ZonedDateTime.
                                        of(dateTime, ZoneId.systemDefault());

  return dateTimeInMyZone
                  .withZoneSameInstant(ZoneOffset.UTC)
                  .toLocalDateTime();
  
}

Para volver a convertir a la fecha y hora local de su zona, utilice:

LocalDateTime convertFromUtc(LocalDateTime utcDateTime){
    return ZonedDateTime.
            of(utcDateTime, ZoneId.of("UTC"))
            .toOffsetDateTime()
            .atZoneSameInstant(ZoneId.systemDefault())
            .toLocalDateTime();
}
Habeeb Okunade
fuente
-1

puedes implementar un ayudante haciendo algo como eso:

public static LocalDateTime convertUTCFRtoUTCZ(LocalDateTime dateTime) {
    ZoneId fr = ZoneId.of("Europe/Paris");
    ZoneId utcZ = ZoneId.of("Z");
    ZonedDateTime frZonedTime = ZonedDateTime.of(dateTime, fr);
    ZonedDateTime utcZonedTime = frZonedTime.withZoneSameInstant(utcZ);
    return utcZonedTime.toLocalDateTime();
}
ddinh
fuente
UTC fr a UTC Z? no significa nada. UTC = Z, UTC <> fr
Tristán
-2
public static String convertFromGmtToLocal(String gmtDtStr, String dtFormat, TimeZone lclTimeZone) throws Exception{
        if (gmtDtStr == null || gmtDtStr.trim().equals("")) return null;
        SimpleDateFormat format = new SimpleDateFormat(dtFormat);
        format.setTimeZone(getGMTTimeZone());
        Date dt = format.parse(gmtDtStr);
        format.setTimeZone(lclTimeZone);
        return

formato.format (dt); }

Ganesh
fuente
1
Por favor, no enseñe a los jóvenes a utilizar la SimpleDateFormatclase obsoleta y notoriamente problemática . Al menos no como primera opción. Y no sin reserva alguna. Hoy tenemos mucho mejor en java.timela API moderna de fecha y hora de Java y su DateTimeFormatter.
Ole VV