Sé que este tipo de temas se discuten por completo, pero descubrí que el paquete commons-lang realmente maneja bien estos problemas comunes de Java. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Echa un vistazo a los diversos paquetes que tienen.
¿Qué hora local desea y con qué precisión? La mayoría de las zonas horarias se definen en relación con UTC con un desplazamiento fijo medido en segundos SI , pero la relación de GMT que se basa en la observación solar y un segundo (ligeramente) de longitud variable es más compleja. Los dos difieren en hasta 0.9 segundos.
mc0e
1
A Dateno tiene una zona horaria, así que "pero en la zona horaria local" no es correcto (o inexacto en el mejor de los casos). Ver todo sobre java.util.Date .
Ole VV
Respuestas:
409
java.util.Dateno tiene una zona horaria específica, aunque su valor se piensa más comúnmente en relación con UTC. ¿Qué te hace pensar que es en hora local?
Para ser precisos: el valor dentro de a java.util.Datees el número de milisegundos desde la época de Unix, que ocurrió a la medianoche del 1 de enero de 1970, UTC. La misma época también podría describirse en otras zonas horarias, pero la descripción tradicional es en términos de UTC. Como es una cantidad de milisegundos desde una época fija, el valor dentro java.util.Datees el mismo en todo el mundo en cualquier instante en particular, independientemente de la zona horaria local.
Sospecho que el problema es que lo está mostrando a través de una instancia de Calendar que usa la zona horaria local, o posiblemente usando Date.toString()que también usa la zona horaria local, o una SimpleDateFormatinstancia, que, por defecto, también usa la zona horaria local.
Si este no es el problema, publique un código de muestra.
Sin embargo, recomendaría que use Joda-Time de todos modos, que ofrece una API mucho más clara.
Entonces eso es probablemente un problema del controlador. Es posible que deba configurar su conexión a UTC, o algo así. He visto problemas como este antes, pero el problema no está en java.util.Date.
Jon Skeet
13
Behrang, de acuerdo con stackoverflow.com/questions/4123534/… , el controlador JDBC de MySQL convierte un determinado java.util.Timestamp(o java.util.Date) a la zona horaria del servidor.
Derek Mahar
55
@Señor. Cat: ¿Cómo estás determinando eso? ¿Es por escrito System.out.println(new Date())? Si es así, debe tener en cuenta que es el toString()método el que aplica la zona horaria allí ... si no es así, brinde más detalles.
Jon Skeet
8
@KanagaveluSugumar: toString()siempre usa la zona horaria predeterminada. date.getTime()definitivamente devuelve milisegundos desde la época de Unix, en UTC. Es más exacto decir que en Datesí mismo no tiene una zona horaria en absoluto, es solo un instante en el tiempo, que podría considerarse en múltiples zonas horarias. Pero cuando crea una instancia, no depende de su zona horaria.
Jon Skeet
66
@Jemenake: En realidad no sucedió cuando era medianoche en Greenwich, porque el Reino Unido estaba en UTC + 1 en ese momento. Solo uno de los pedazos extraños de la historia. Pero entiendo su punto: es mejor decir "new Date (). GetTime () devuelve los milisegundos desde la época de Unix, que era la medianoche al comienzo del 1 de enero de 1970, UTC". Entonces, el UTC es parte de fijar la época a un instante particular en el tiempo, no parte del resultado.
Jon Skeet
325
tl; dr
Instant.now()// Capture the current moment in UTC.
Genere una cadena para representar ese valor:
Instant.now().toString()
2016-09-13T23: 30: 52.123Z
Detalles
Como dijo la respuesta correcta de Jon Skeet , un objeto java.util.Date no tiene zona horaria † . Pero su toStringimplementación aplica la zona horaria predeterminada de la JVM al generar la representación de cadena de ese valor de fecha y hora. Confusamente para el programador ingenuo, una Fecha parece tener una zona horaria pero no la tiene.
Las java.util.Date, j.u.Calendary java.text.SimpleDateFormatlas clases que vienen con Java son notoriamente molesto. Evítales. En su lugar, use cualquiera de estas bibliotecas de fecha y hora competentes:
Java 8 trae un excelente nuevo paquete java.time. * Para suplantar las antiguas clases java.util.Date/Calendar.
Obtener la hora actual en UTC / GMT es una línea simple ...
Instant instant =Instant.now();
Esa Instantclase es el bloque de construcción básico en java.time, que representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos .
En Java 8, el momento actual se captura con solo una resolución de hasta milisegundos. Java 9 ofrece una nueva implementación de Clockcapturas del momento actual hasta la capacidad completa de nanosegundos de esta clase, dependiendo de la capacidad del hardware del reloj de la computadora host.
Su toStringmétodo genera una representación de cadena de su valor utilizando un formato ISO 8601 específico . Ese formato genera cero, tres, seis o nueve dígitos dígitos ( milisegundos , microsegundos o nanosegundos ) según sea necesario para representar la fracción de segundo.
Si desea un formato más flexible u otras características adicionales, aplique un desplazamiento desde UTC de cero, para que UTC mismo ( ZoneOffset.UTCconstante ) obtenga un OffsetDateTime.
OffsetDateTime now =OffsetDateTime.now(ZoneOffset.UTC );
Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener 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 hay necesidad de cadenas, no hay necesidad de java.sql.*clases.
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .
Utilizando la biblioteca gratuita de código abierto de terceros de Joda-Time , puede obtener la fecha y hora actual en una sola línea de código.
Joda-Time inspiró las nuevas clases java.time. * En Java 8, pero tiene una arquitectura diferente. Puede usar Joda-Time en versiones anteriores de Java. Joda-Time continúa trabajando en Java 8 y continúa manteniéndose activamente (a partir de 2014). Sin embargo, el equipo de Joda-Time aconseja la migración a java.time.
System.out.println("UTC/GMT date-time in ISO 8601 format: "+new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ));
Código de ejemplo más detallado (Joda-Time 2.3) ...
org.joda.time.DateTime now =new org.joda.time.DateTime();// Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
Volcado a la consola ...
System.out.println("Local time in ISO 8601 format: "+ now );System.out.println("Same moment in UTC (Zulu): "+ zulu );
Cuando corres ...
Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
Para obtener más ejemplos de código que funcionan en zonas horarias, consulte mi respuesta a una pregunta similar.
Zona horaria
Le recomiendo que siempre especifique una zona horaria en lugar de depender implícitamente de la zona horaria predeterminada actual de la JVM (¡que puede cambiar en cualquier momento!). Tal confianza parece ser una causa común de confusión y errores en el trabajo de fecha y hora.
Al llamar, now()pase la zona horaria deseada / esperada que se asignará. Usa la DateTimeZoneclase.
DateTimeZone zoneMontréal =DateTimeZone.forID("America/Montreal");DateTime now =DateTime.now( zoneMontréal );
Si realmente desea utilizar la zona horaria predeterminada actual de la JVM, realice una llamada explícita para que su código se documente automáticamente.
Lea sobre los formatos ISO 8601 . Tanto java.time como Joda-Time usan los formatos sensibles de ese estándar como sus valores predeterminados para analizar y generar cadenas.
† En realidad, java.util.Date hace tener una zona horaria, profundamente enterrado bajo capas de código fuente. Para los propósitos más prácticos, esa zona horaria se ignora. Entonces, como taquigrafía, decimos que java.util.Date no tiene zona horaria. Además, esa zona horaria enterrada no es la utilizada por el toStringmétodo de Date ; ese método usa la zona horaria predeterminada actual de la JVM. Razón de más para evitar esta clase confusa y seguir con Joda-Time y java.time.
Cómo obtener esto con Pure Java 8 2014-01-21T15:34:29.933-08:00en el ejemplo que usónew org.joda.time.DateTime()
GOXR3PLUS el
1
@ GOXR3PLUS ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() Obtenemos el momento actual para una zona horaria específica. Luego, corte cualquier micros / nanos. Luego, pasamos a tener un mero desplazamiento desde UTC (número de horas-minutos-segundos) en lugar de una zona horaria completa (un historial de cambios pasados, presentes y futuros en el desplazamiento utilizado por las personas de un región particular). Por último, generamos texto que representa el valor OffsetDateTimesegún el formato estándar ISO 8601 utilizado por defecto en su toStringmétodo.
Basil Bourque
Gracias por dar esta explicación detallada, también +1 para los soportes de Android :) @BasilBourque
mochadwi
271
SimpleDateFormat dateFormatGmt =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));//Local time zone SimpleDateFormat dateFormatLocal =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");//Time in GMTreturn dateFormatLocal.parse( dateFormatGmt.format(newDate()));
¿Por qué analizar con dateFormatLocal después de usar el formato dateFormatGmt ... no tiene sentido al leerlo? Estoy seguro de que funciona, pero me pregunto?
MindWire
2
setTimeZone lo hizo (supongo que también puedes usar getTimeZone ("UTC") lo mismo que GMT?)
rogerdpack
66
pero el tiempo depende del tiempo establecido por el dispositivo. Si el usuario ha configurado una hora incorrecta en su dispositivo, obtendrá un UTC incorrecto. Corríjame si estoy equivocado
Basavaraj Hampali
@BasavarajHampali, pero en el mundo de hoy la mayoría de los dispositivos están conectados a Internet, lo que corrige el tiempo incorrecto
Akshat Agarwal
3
No hay diferencia horaria entre la hora universal coordinada (UTC) y la hora media de Greenwich (GMT)
slott
86
Esto definitivamente devuelve la hora UTC: ¡como objetos String y Date!
Como se me redirigió a esta respuesta, Llamar new Date()nunca devolverá la hora UTC correcta, si la hora del dispositivo es incorrecta.
Sanoop
¿Este método obtiene tiempo depende del calendario del dispositivo?
Arnold Brown el
Una cosa a tener en cuenta. Cualquier solución que necesite obtener una fecha o marca de tiempo en UTC, parece que la clave es no reutilizar SimpleDateFormat, sino usar una para obtener UTC en una cadena, luego crear otra UTC al convertir la cadena en una fecha u Objeto de marca de tiempo. Me di cuenta de que si intenta reutilizar el mismo SimpleDateFormat, el Objeto de fecha / hora resultante volverá a la zona horaria local en lugar de UTC.
Sí, solución agradable y limpia. Simplemente me preocupa, ¿es ineficaz crear un nuevo objeto Date en lugar de simplemente obtener la instancia de Calendar?
Beemo
Será optimizado por JVM y HotSpot ejecutará el código x86 más efectivo posible
Antonio
17
Calendario aGMTCalendar = Calendar.getInstance (TimeZone.getTimeZone ("GMT")); Luego, todas las operaciones realizadas con el objeto aGMTCalendar se realizarán con la zona horaria GMT y no se aplicará el horario de verano ni las compensaciones fijas
java.util.Datesiempre está en UTC. ¿Qué te hace pensar que es en hora local? Sospecho que el problema es que lo está mostrando a través de una instancia de Calendar que usa la zona horaria local, o posiblemente usando la
Date.toString()que también usa la zona horaria local.
muestra las horas GMT en lugar de las horas locales; tenga en cuenta que getTime.getHours()falta porque eso crearía un Date()objeto, que teóricamente almacena la fecha en GMT, pero devuelve las horas en la zona horaria local.
No había visto esta respuesta antes, pero si lees la documentación del Date.getHours()método en desuso , deja muy claro: "El valor devuelto es un número (del 0 al 23) que representa la hora dentro del día que contiene o comienza con el instantáneo en el tiempo representado por este objeto Date, tal como se interpreta en la zona horaria local ". (El énfasis es mío). Es el getHours()método que interpreta el valor dentro de la zona horaria local; no es parte del estado del Dateobjeto en sí.
Jon Skeet
2
Como Jon Skeet declaró correctamente, un objeto java.util.Date no tiene zona horaria . Pero de manera confusa, los métodos toStringy getHoursaplicar la zona horaria predeterminada a su salida. Por lo tanto, los programadores ingenuos se engañan fácilmente, ya que parece que una fecha tiene una zona horaria, pero en realidad no.
Basil Bourque
7
Si desea un objeto Date con campos ajustados para UTC, puede hacerlo así con Joda Time :
import org.joda.time.DateTimeZone;import java.util.Date;...Date local =newDate();System.out.println("Local: "+ local);DateTimeZone zone =DateTimeZone.getDefault();long utc = zone.convertLocalToUTC(local.getTime(),false);System.out.println("UTC: "+newDate(utc));
Estás trabajando muy duro. Joda-Time puede hacer esto en una sola línea de código. Vea mi propia respuesta a esta pregunta. Llame al .toDateTimemétodo y pase la constante para la zona horaria UTC.
Basil Bourque
1
DateTime utcDate = new DateTime (). ToDateTime (DateTimeZone.UTC)
Luego, todas las operaciones realizadas con el objeto aGMTCalendar se realizarán con la zona horaria GMT y no se aplicará el horario de verano ni las compensaciones fijas. Creo que el póster anterior es correcto que el objeto Date () siempre devuelve un GMT, no es hasta que va a hacer algo con el objeto de fecha que se convierte a la zona horaria local.
Puede preguntar cal.get(Calendar.DATE);u otro calendario constante sobre otros detalles.
La fecha y la marca de tiempo están en desuso en Java. Clase de calendario no lo es.
Código de muestra para representar la hora del sistema en una zona horaria específica y un formato específico.
import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;publicclassTimZoneTest{publicstaticvoid main (String[] args){//<GMT><+/-><hour>:<minutes>// Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.System.out.println(my_time_in("GMT-5:00","MM/dd/yyyy HH:mm:ss"));System.out.println(my_time_in("GMT+5:30","'at' HH:mm a z 'on' MM/dd/yyyy"));System.out.println("---------------------------------------------");// Alternate format System.out.println(my_time_in("America/Los_Angeles","'at' HH:mm a z 'on' MM/dd/yyyy"));System.out.println(my_time_in("America/Buenos_Aires","'at' HH:mm a z 'on' MM/dd/yyyy"));}publicstaticString my_time_in(String target_time_zone,String format){TimeZone tz =TimeZone.getTimeZone(target_time_zone);Date date =Calendar.getInstance().getTime();SimpleDateFormat date_format_gmt =newSimpleDateFormat(format);
date_format_gmt.setTimeZone(tz);return date_format_gmt.format(date);}}
Salida
10/08/201121:07:21
at 07:37 AM GMT+05:30 on 10/09/2011
at 19:07 PM PDT on 10/08/2011
at 23:07 PM ART on 10/08/2011
Llamar a getTime () sobre esto hace que pierda la información de zona horaria y regrese la hora local.
RealCasually
3
Conversión de fecha y hora actual en UTC:
DateTimeFormatter formatter =DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");DateTimeZone dateTimeZone =DateTimeZone.getDefault();//Default Time ZoneDateTime currDateTime =newDateTime();//Current DateTimelong utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(),false);String currTime = formatter.print(utcTime);//UTC time converted to string from long in format of formatter
currDateTime = formatter.parseDateTime(currTime);//Converted to DateTime in UTC
Estás haciendo demasiado trabajo aquí. (a) El patrón de formateador que defina ya está integrado en un DateTime de forma predeterminada; simplemente llame toStringa un DateTime para obtener ese patrón de cadena ISO 8601 . (b) Demasiado código para convertir entre zonas horarias. Simplemente llame a "toDateTime" y pase un objeto de zona horaria. De esta manera: myDateTime.toDateTime( DateTimeZone.UTC ). Para una zona horaria específica, cree una instancia y pase un objeto de zona horaria basado en un nombre propio , llame myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Basil Bourque
2
¡Esto funcionó para mí, devuelve la marca de tiempo en GMT!
Use esta clase para obtener el tiempo UTC correcto de un servidor NTP en línea:
import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;class NTP_UTC_Time
{privatestaticfinalString TAG ="SntpClient";privatestaticfinalint RECEIVE_TIME_OFFSET =32;privatestaticfinalint TRANSMIT_TIME_OFFSET =40;privatestaticfinalint NTP_PACKET_SIZE =48;privatestaticfinalint NTP_PORT =123;privatestaticfinalint NTP_MODE_CLIENT =3;privatestaticfinalint NTP_VERSION =3;// Number of seconds between Jan 1, 1900 and Jan 1, 1970// 70 years plus 17 leap daysprivatestaticfinallong OFFSET_1900_TO_1970 =((365L*70L)+17L)*24L*60L*60L;privatelong mNtpTime;publicboolean requestTime(String host,int timeout){try{DatagramSocket socket =newDatagramSocket();
socket.setSoTimeout(timeout);InetAddress address =InetAddress.getByName(host);byte[] buffer =newbyte[NTP_PACKET_SIZE];DatagramPacket request =newDatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0]= NTP_MODE_CLIENT |(NTP_VERSION <<3);
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
socket.send(request);// read the responseDatagramPacket response =newDatagramPacket(buffer, buffer.length);
socket.receive(response);
socket.close();
mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);}catch(Exception e){// if (Config.LOGD) Log.d(TAG, "request time failed: " + e);returnfalse;}returntrue;}publiclong getNtpTime(){return mNtpTime;}/**
* Reads an unsigned 32 bit big endian number from the given offset in the buffer.
*/privatelong read32(byte[] buffer,int offset){byte b0 = buffer[offset];byte b1 = buffer[offset+1];byte b2 = buffer[offset+2];byte b3 = buffer[offset+3];// convert signed bytes to unsigned valuesint i0 =((b0 &0x80)==0x80?(b0 &0x7F)+0x80: b0);int i1 =((b1 &0x80)==0x80?(b1 &0x7F)+0x80: b1);int i2 =((b2 &0x80)==0x80?(b2 &0x7F)+0x80: b2);int i3 =((b3 &0x80)==0x80?(b3 &0x7F)+0x80: b3);return((long)i0 <<24)+((long)i1 <<16)+((long)i2 <<8)+(long)i3;}/**
* Reads the NTP time stamp at the given offset in the buffer and returns
* it as a system time (milliseconds since January 1, 1970).
*/privatelong readTimeStamp(byte[] buffer,int offset){long seconds = read32(buffer, offset);long fraction = read32(buffer, offset +4);return((seconds - OFFSET_1900_TO_1970)*1000)+((fraction *1000L)/0x100000000L);}/**
* Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
*/privatevoid writeTimeStamp(byte[] buffer,int offset){int ofs = offset++;for(int i=ofs;i<(ofs+8);i++)
buffer[i]=(byte)(0);}}
Y úsalo con:
long now =0;
NTP_UTC_Time client =new NTP_UTC_Time();if(client.requestTime("pool.ntp.org",2000)){
now = client.getNtpTime();}
Si necesita la hora UTC "ahora" como función de uso DateTimeString:
En pocas palabras. Un objeto de calendario almacena información sobre la zona horaria, pero cuando realiza cal.getTime (), la información de la zona horaria se perderá. Entonces, para las conversiones de zona horaria, aconsejaré usar las clases DateFormat ...
publicstaticStringGetCurrentTimeStamp(){Calendar cal=Calendar.getInstance();long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .returnnew java.sql.Timestamp(System.currentTimeMillis()+offset).toString();}
publicclassCurrentUtcDate{publicstaticvoid main(String[] args){Date date =newDate();SimpleDateFormat dateFormat =newSimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));System.out.println("UTC Time is: "+ dateFormat.format(date));}}
Salida:
UTC Time is:22-01-201813:14:35
Puede cambiar el formato de fecha según sea necesario.
Por favor, no les enseñe a los jóvenes a usar el desactualizado y notoriamente problemático SimpleDateFormat. Hoy tenemos mucho mejor en java.timela moderna API de fecha y hora de Java . Además, ¿qué está proporcionando que no esté en las respuestas de Dan, Antonio y otros?
Ole VV
2
(a) ¿Cómo agrega valor esta Respuesta a las docenas de Respuestas existentes? (b) Las clases problemáticas utilizadas aquí fueron suplantadas hace años por las modernas clases java.time . Sugerir su uso en 2018 es un mal consejo.
Basil Bourque
0
Utilice el paquete java.time e incluya el siguiente código:
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
(A) Si usa un desplazamiento ( ZoneOffset) en lugar de una zona horaria ( ZoneId), OffsetDateTimees más apropiado que ZonedDateTime. (B) LocalDateTimeno debe usarse para capturar el momento actual ya que no tiene un concepto de zona horaria o desplazamiento desde UTC. (C) Otras respuestas preexistentes han cubierto este material y han hecho un mejor trabajo. No veo cómo esta respuesta agrega valor.
Date
no tiene una zona horaria, así que "pero en la zona horaria local" no es correcto (o inexacto en el mejor de los casos). Ver todo sobre java.util.Date .Respuestas:
java.util.Date
no tiene una zona horaria específica, aunque su valor se piensa más comúnmente en relación con UTC. ¿Qué te hace pensar que es en hora local?Para ser precisos: el valor dentro de a
java.util.Date
es el número de milisegundos desde la época de Unix, que ocurrió a la medianoche del 1 de enero de 1970, UTC. La misma época también podría describirse en otras zonas horarias, pero la descripción tradicional es en términos de UTC. Como es una cantidad de milisegundos desde una época fija, el valor dentrojava.util.Date
es el mismo en todo el mundo en cualquier instante en particular, independientemente de la zona horaria local.Sospecho que el problema es que lo está mostrando a través de una instancia de Calendar que usa la zona horaria local, o posiblemente usando
Date.toString()
que también usa la zona horaria local, o unaSimpleDateFormat
instancia, que, por defecto, también usa la zona horaria local.Si este no es el problema, publique un código de muestra.
Sin embargo, recomendaría que use Joda-Time de todos modos, que ofrece una API mucho más clara.
fuente
java.util.Timestamp
(ojava.util.Date
) a la zona horaria del servidor.System.out.println(new Date())
? Si es así, debe tener en cuenta que es eltoString()
método el que aplica la zona horaria allí ... si no es así, brinde más detalles.toString()
siempre usa la zona horaria predeterminada.date.getTime()
definitivamente devuelve milisegundos desde la época de Unix, en UTC. Es más exacto decir que enDate
sí mismo no tiene una zona horaria en absoluto, es solo un instante en el tiempo, que podría considerarse en múltiples zonas horarias. Pero cuando crea una instancia, no depende de su zona horaria.tl; dr
Genere una cadena para representar ese valor:
Detalles
Como dijo la respuesta correcta de Jon Skeet , un objeto java.util.Date no tiene zona horaria † . Pero su
toString
implementación aplica la zona horaria predeterminada de la JVM al generar la representación de cadena de ese valor de fecha y hora. Confusamente para el programador ingenuo, una Fecha parece tener una zona horaria pero no la tiene.Las
java.util.Date
,j.u.Calendar
yjava.text.SimpleDateFormat
las clases que vienen con Java son notoriamente molesto. Evítales. En su lugar, use cualquiera de estas bibliotecas de fecha y hora competentes:java.time (Java 8)
Java 8 trae un excelente nuevo paquete java.time. * Para suplantar las antiguas clases java.util.Date/Calendar.
Obtener la hora actual en UTC / GMT es una línea simple ...
Esa
Instant
clase es el bloque de construcción básico en java.time, que representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos .En Java 8, el momento actual se captura con solo una resolución de hasta milisegundos. Java 9 ofrece una nueva implementación de
Clock
capturas del momento actual hasta la capacidad completa de nanosegundos de esta clase, dependiendo de la capacidad del hardware del reloj de la computadora host.Su
toString
método genera una representación de cadena de su valor utilizando un formato ISO 8601 específico . Ese formato genera cero, tres, seis o nueve dígitos dígitos ( milisegundos , microsegundos o nanosegundos ) según sea necesario para representar la fracción de segundo.Si desea un formato más flexible u otras características adicionales, aplique un desplazamiento desde UTC de cero, para que UTC mismo (
ZoneOffset.UTC
constante ) obtenga unOffsetDateTime
.Volcado a la consola ...
Cuando corres ...
Sobre java.time
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como
java.util.Date
,Calendar
, ySimpleDateFormat
.Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow 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 hay necesidad de cadenas, no hay necesidad de
java.sql.*
clases.¿Dónde obtener las clases java.time?
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como
Interval
,YearWeek
,YearQuarter
, y más .Joda-Time
ACTUALIZACIÓN: El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Utilizando la biblioteca gratuita de código abierto de terceros de Joda-Time , puede obtener la fecha y hora actual en una sola línea de código.
Joda-Time inspiró las nuevas clases java.time. * En Java 8, pero tiene una arquitectura diferente. Puede usar Joda-Time en versiones anteriores de Java. Joda-Time continúa trabajando en Java 8 y continúa manteniéndose activamente (a partir de 2014). Sin embargo, el equipo de Joda-Time aconseja la migración a java.time.
Código de ejemplo más detallado (Joda-Time 2.3) ...
Volcado a la consola ...
Cuando corres ...
Para obtener más ejemplos de código que funcionan en zonas horarias, consulte mi respuesta a una pregunta similar.
Zona horaria
Le recomiendo que siempre especifique una zona horaria en lugar de depender implícitamente de la zona horaria predeterminada actual de la JVM (¡que puede cambiar en cualquier momento!). Tal confianza parece ser una causa común de confusión y errores en el trabajo de fecha y hora.
Al llamar,
now()
pase la zona horaria deseada / esperada que se asignará. Usa laDateTimeZone
clase.Esa clase tiene una constante para la zona horaria UTC .
Si realmente desea utilizar la zona horaria predeterminada actual de la JVM, realice una llamada explícita para que su código se documente automáticamente.
ISO 8601
Lea sobre los formatos ISO 8601 . Tanto java.time como Joda-Time usan los formatos sensibles de ese estándar como sus valores predeterminados para analizar y generar cadenas.
† En realidad, java.util.Date hace tener una zona horaria, profundamente enterrado bajo capas de código fuente. Para los propósitos más prácticos, esa zona horaria se ignora. Entonces, como taquigrafía, decimos que java.util.Date no tiene zona horaria. Además, esa zona horaria enterrada no es la utilizada por el
toString
método de Date ; ese método usa la zona horaria predeterminada actual de la JVM. Razón de más para evitar esta clase confusa y seguir con Joda-Time y java.time.fuente
DateTime.now().toDateTime(DateTimeZone.UTC)
fue lo que estaba buscando! ¡Gracias!DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
2014-01-21T15:34:29.933-08:00
en el ejemplo que usónew org.joda.time.DateTime()
ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString()
Obtenemos el momento actual para una zona horaria específica. Luego, corte cualquier micros / nanos. Luego, pasamos a tener un mero desplazamiento desde UTC (número de horas-minutos-segundos) en lugar de una zona horaria completa (un historial de cambios pasados, presentes y futuros en el desplazamiento utilizado por las personas de un región particular). Por último, generamos texto que representa el valorOffsetDateTime
según el formato estándar ISO 8601 utilizado por defecto en sutoString
método.fuente
Esto definitivamente devuelve la hora UTC: ¡como objetos String y Date!
fuente
static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
new Date()
nunca devolverá la hora UTC correcta, si la hora del dispositivo es incorrecta.fuente
En realidad no es el tiempo, pero su representación podría cambiarse.
El tiempo es el mismo en cualquier punto de la Tierra, pero nuestra percepción del tiempo podría ser diferente dependiendo de la ubicación.
fuente
¡Incorrecto!
y
Volveremos al mismo tiempo. Idem para
fuente
Este código imprime la hora actual UTC.
Resultado
fuente
Esto funciona para obtener milisegundos UTC en Android.
fuente
c.add(Calendar.MILLISECOND, (-utcOffset))
obtener Calendario con zona horaria utcAquí está lo que parece ser incorrecto en la respuesta de Jon Skeet . Él dijo:
Sin embargo, el código:
da las horas locales, no GMT (horas UTC), usando no
Calendar
y noSimpleDateFormat
en absoluto.Por eso parece que algo es incorrecto.
Al juntar las respuestas, el código:
muestra las horas GMT en lugar de las horas locales; tenga en cuenta que
getTime.getHours()
falta porque eso crearía unDate()
objeto, que teóricamente almacena la fecha en GMT, pero devuelve las horas en la zona horaria local.fuente
Date.getHours()
método en desuso , deja muy claro: "El valor devuelto es un número (del 0 al 23) que representa la hora dentro del día que contiene o comienza con el instantáneo en el tiempo representado por este objeto Date, tal como se interpreta en la zona horaria local ". (El énfasis es mío). Es elgetHours()
método que interpreta el valor dentro de la zona horaria local; no es parte del estado delDate
objeto en sí.toString
ygetHours
aplicar la zona horaria predeterminada a su salida. Por lo tanto, los programadores ingenuos se engañan fácilmente, ya que parece que una fecha tiene una zona horaria, pero en realidad no.Si desea un objeto Date con campos ajustados para UTC, puede hacerlo así con Joda Time :
fuente
.toDateTime
método y pase la constante para la zona horaria UTC.Puedes usar:
Luego, todas las operaciones realizadas con el objeto aGMTCalendar se realizarán con la zona horaria GMT y no se aplicará el horario de verano ni las compensaciones fijas. Creo que el póster anterior es correcto que el objeto Date () siempre devuelve un GMT, no es hasta que va a hacer algo con el objeto de fecha que se convierte a la zona horaria local.
fuente
fuente
Puedes usar esto directamente
fuente
Con:
Luego
cal
tenga la fecha y hora actuales.También puede obtener la fecha y hora actual para la zona horaria con:
Puede preguntar
cal.get(Calendar.DATE);
u otro calendario constante sobre otros detalles.La fecha y la marca de tiempo están en desuso en Java. Clase de calendario no lo es.
fuente
Aquí otra sugerencia para obtener un objeto GMT Timestamp:
fuente
Aquí hay otra forma de obtener la hora GMT en formato de cadena
fuente
Aquí está mi implementación de toUTC:
Probablemente hay varias formas de mejorarlo, pero funciona para mí.
fuente
Código de muestra para representar la hora del sistema en una zona horaria específica y un formato específico.
Salida
fuente
Sólo para hacerlo mas simple, para crear una
Date
en laUTC
que se puede utilizarCalendar
:Lo cual construirá una nueva instancia para
Calendar
usar el "UTC"TimeZone
.Si necesita un
Date
objeto de ese calendario, puede usarlogetTime()
.fuente
Conversión de fecha y hora actual en UTC:
fuente
toString
a un DateTime para obtener ese patrón de cadena ISO 8601 . (b) Demasiado código para convertir entre zonas horarias. Simplemente llame a "toDateTime" y pase un objeto de zona horaria. De esta manera:myDateTime.toDateTime( DateTimeZone.UTC )
. Para una zona horaria específica, cree una instancia y pase un objeto de zona horaria basado en un nombre propio , llamemyDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) )
.¡Esto funcionó para mí, devuelve la marca de tiempo en GMT!
fuente
Use esta clase para obtener el tiempo UTC correcto de un servidor NTP en línea:
Y úsalo con:
Si necesita la hora UTC "ahora" como función de uso DateTimeString:
y úsalo con:
fuente
fuente
En pocas palabras. Un objeto de calendario almacena información sobre la zona horaria, pero cuando realiza cal.getTime (), la información de la zona horaria se perderá. Entonces, para las conversiones de zona horaria, aconsejaré usar las clases DateFormat ...
fuente
Esta es mi implementación:
fuente
Si desea evitar analizar la fecha y solo desea una marca de tiempo en GMT, puede usar:
fuente
Si está usando el tiempo joda y desea el tiempo actual en milisegundos sin su desplazamiento local , puede usar esto:
fuente
Salida:
Puede cambiar el formato de fecha según sea necesario.
fuente
SimpleDateFormat
. Hoy tenemos mucho mejor enjava.time
la moderna API de fecha y hora de Java . Además, ¿qué está proporcionando que no esté en las respuestas de Dan, Antonio y otros?Utilice el paquete java.time e incluya el siguiente código:
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
o
LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );
Dependiendo de su aplicación necesita.
fuente
ZoneOffset
) en lugar de una zona horaria (ZoneId
),OffsetDateTime
es más apropiado queZonedDateTime
. (B)LocalDateTime
no debe usarse para capturar el momento actual ya que no tiene un concepto de zona horaria o desplazamiento desde UTC. (C) Otras respuestas preexistentes han cubierto este material y han hecho un mejor trabajo. No veo cómo esta respuesta agrega valor.