studio - Obtener fecha objeto en formato UTC en Java
timezone java (5)
He escrito el siguiente código. Quiero obtener el objeto Date en formato UTC.
Puedo obtener la cadena de fecha esperada en UTC utilizando SimpleDateFormat
. Pero usando el mismo objeto SimpleDateFormat
, no puedo obtener el objeto en formato UTC. Está devolviendo objeto con formato IST.
Después de buscar, encontré que el objeto Fecha no almacena información de marca de tiempo.
¿Cómo puedo obtener objeto de fecha en formato UTC?
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class dddd {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Input - "+1393572325000L);
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date= new Date(1393572325000L);
String dateString = formatter.format(date);
System.out.println("Converted UTC TIME (using Format method) : "+dateString);
Date date2 =null;
try {
date2 = formatter.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("Parsed Date Object (using Parse method) : "+date2);
System.out.println("Expected Date Object : Fri Feb 28 07:25:25 UTC 2014");
}
}
Esto imprime siguiente salida:
Input - 1393572325000
Converted UTC TIME (using Format method) : 2014-02-28 07:25:25
Parsed Date Object (using Parse method) : Fri Feb 28 12:55:25 IST 2014
Expected Date Object : Fri Feb 28 07:25:25 UTC 2014
tl; dr
Instant.ofEpochMilli ( 1_393_572_325_000L )
.toString()
2014-02-28T07: 25: 25Z
Detalles
(a) Parece estar confundido en cuanto a lo que es una fecha. Como dijo la respuesta de JB Nizet , una Fecha rastrea el número de milisegundos desde la epoch Unix (primer momento de 1970) en la zona horaria UTC (es decir, sin desplazamiento de zona horaria). Así que una fecha no tiene zona horaria † . Y no tiene "formato". Creamos representaciones de cadena a partir del valor de una fecha, pero la fecha en sí no es una cadena y no tiene una cadena .
(b) Usted se refiere a un "formato UTC". UTC no es un formato, no he oído hablar de. UTC es el punto de origen de las zonas horarias. Las zonas horarias al este del Observatorio Real en Greenwich, Londres, están algunas horas y minutos por delante de UTC. Las zonas horarias hacia el oeste están detrás de UTC.
Parece que te refieres a las cadenas con formato ISO 8601 . Está utilizando el formato opcional, omitiendo (1) la T
desde el centro y (2) el desplazamiento desde UTC al final. A menos que presente la cadena a un usuario en la interfaz de usuario de su aplicación, le sugiero que generalmente se adhiera al formato habitual:
-
2014-02-27T23:03:14+05:30
-
2014-02-27T23:03:14Z
(''Z'' para Zulu, o UTC, con un desplazamiento de +00: 00)
(c) Evite los códigos de zona horaria de 3 o 4 letras. No son ni estandarizados ni únicos. "IST", por ejemplo, puede significar la hora estándar india o la hora estándar irlandesa .
(d) Ponga algo de esfuerzo en buscar antes de publicar. Habrías encontrado todas tus respuestas.
(e) Evite las clases java.util.Date & Calendar incluidas con Java. Son notoriamente problemáticos. Utilice la biblioteca Joda-Time o el nuevo paquete java.time de Java 8 (inspirado en Joda-Time, definido por JSR 310).
java.time
Las clases java.time utilizan formatos estándar ISO 8601 por defecto al analizar y generar cadenas.
OffsetDateTime odt = OffsetDateTime.parse( "2014-02-27T23:03:14+05:30" );
Instant instant = Instant.parse( "2014-02-27T23:03:14Z" );
Analice su cuenta de milisegundos desde la época del primer momento de 1970 en UTC.
Instant instant = Instant.ofEpochMilli ( 1_393_572_325_000L );
instant.toString (): 2014-02-28T07: 25: 25Z
Ajuste ese Instant
en una zona horaria deseada.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString (): 2014-02-28T02: 25: 25-05: 00 [América / Montreal]
Acerca de java.time
El marco java.time está integrado en Java 8 y java.time posteriores. Estas clases sustituyen a las antiguas y problemáticas clases de fecha y hora como java.util.Date
, java.util.Calendar y SimpleDateFormat
.
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Para obtener más información, consulte el Tutorial de Oracle . Y busca para muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No se necesitan cadenas, no se necesitan clases java.sql.*
.
¿Dónde obtener las clases java.time?
- Java SE 8 , Java SE 9 , Java SE 10 y posteriores
- Incorporado.
- Parte de la API de Java estándar con una implementación en paquete.
- Java 9 agrega algunas características menores y correcciones.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad de java.time está respaldada 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 terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí como Interval
, YearWeek
, YearQuarter
, y more .
Tiempo de joda
ACTUALIZACIÓN: El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Joda-Time usa ISO 8601 como sus valores por defecto.
Un objeto DateTime
Joda-Time conoce su zona horaria asignada, a diferencia de un objeto java.util.Date.
En general, es mejor especificar una zona horaria explícitamente en lugar de depender de la zona horaria predeterminada.
Código de ejemplo
long input = 1393572325000L;
DateTime dateTimeUtc = new DateTime( input, DateTimeZone.UTC );
DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZoneIreland = DateTimeZone.forID( "Europe/Dublin" );
DateTime dateTimeIndia = dateTimeUtc.withZone( timeZoneIndia );
DateTime dateTimeIreland = dateTimeIndia.withZone( timeZoneIreland );
// Use a formatter to create a String representation. The formatter can adjust time zone if you so desire.
DateTimeFormatter formatter = DateTimeFormat.forStyle( "FM" ).withLocale( Locale.CANADA_FRENCH ).withZone( DateTimeZone.forID( "America/Montreal" ) );
String output = formatter.print( dateTimeIreland );
Volcar a la consola ...
// All three of these date-time objects represent the *same* moment in the timeline of the Universe.
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeIreland: " + dateTimeIreland );
System.out.println( "output for Montréal: " + output );
Cuando se ejecuta ...
dateTimeUtc: 2014-02-28T07:25:25.000Z
dateTimeIndia: 2014-02-28T12:55:25.000+05:30
dateTimeIreland: 2014-02-28T07:25:25.000Z
output for Montréal: vendredi 28 février 2014 02:25:25
† En realidad, java.util.Date tiene una zona horaria. Esa zona horaria está asignada profundamente en su código fuente. Sin embargo, la clase ignora esa zona horaria para la mayoría de los propósitos prácticos. Y su método toString
aplica la zona horaria predeterminada actual de la JVM en lugar de esa zona horaria interna. ¿Confuso? Sí. Esta es una de las muchas razones para evitar las antiguas clases java.util.Date/.Calendar. Utilice java.time y / o Joda-Time en su lugar.
En java 8, es muy fácil obtener la marca de tiempo en UTC mediante el uso de java 8 java.time.Instant library:
Instant.now();
Esa pequeña palabra de código devolverá la marca de tiempo UTC.
Puede restar la diferencia de zona horaria a partir de ahora.
final Calendar calendar = Calendar.getInstance();
final int utcOffset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
final long tempDate = new Date().getTime();
return new Date(tempDate - utcOffset);
Una fecha no tiene ninguna zona horaria. Lo que está viendo es solo el formato de la fecha con el método Date.toString()
, que usa su zona horaria local, siempre, para transformar la fecha Date.toString()
la zona horaria en una cadena que pueda comprender.
Si desea mostrar la fecha independiente de la zona horaria como una cadena usando la zona horaria UTC, entonces use un SimpleDateFormat con la zona horaria UTC (como ya lo está haciendo en su pregunta).
En otros términos, la zona horaria no es una propiedad de la fecha. Es una propiedad del formato utilizado para transformar la fecha en una cadena.
final Date currentTime = new Date();
final SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC time: " + sdf.format(currentTime));