¿Cómo puedo obtener la fecha y hora actuales en UTC o GMT en Java?

479

Cuando creo un nuevo Dateobjeto, se inicializa a la hora actual pero en la zona horaria local. ¿Cómo puedo obtener la fecha y hora actuales en GMT?

Behrang
fuente
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.

Jon Skeet
fuente
55
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.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 ...

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 );

Volcado a la consola ...

System.out.println( "now.toString(): " + now );

Cuando corres ...

now.toString(): 2014-01-21T23:42:03.522Z

Tabla de tipos de fecha y hora en Java, tanto modernos como heredados.


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, y SimpleDateFormat.

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?

Tabla de qué biblioteca java.time usar con qué versión de Java o Android

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.

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 );

Esa clase tiene una constante para la zona horaria UTC .

DateTime now = DateTime.now( DateTimeZone.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.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

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 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.

Albahaca Bourque
fuente
2
DateTime.now().toDateTime(DateTimeZone.UTC)fue lo que estaba buscando! ¡Gracias!
Managarm
1
@Managarm Puede acortar eso a: DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
Basil Bourque
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 = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

//Local time zone   
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
Dan
fuente
11
¿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!

static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

public static Date getUTCdatetimeAsDate() {
    // note: doesn't check for null
    return stringDateToDate(getUTCdatetimeAsString());
}

public static String getUTCdatetimeAsString() {
    final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    final String utcTime = sdf.format(new Date());

    return utcTime;
}

public static Date stringDateToDate(String StrDate) {
    Date dateToReturn = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);

    try {
        dateToReturn = (Date)dateFormat.parse(StrDate);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return dateToReturn;
}
Alguien en alguna parte
fuente
En mi respuesta, olvidé mostrar cómo se define DATEFORMAT: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Someone Somewhere
21
Evite iniciar nombres de métodos con mayúsculas en Java. Consulte las convenciones de codificación de Java para los nombres de los métodos.
Florian Schrofner
2
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.
Brian comenzó
65
    Calendar c = Calendar.getInstance();
    System.out.println("current: "+c.getTime());

    TimeZone z = c.getTimeZone();
    int offset = z.getRawOffset();
    if(z.inDaylightTime(new Date())){
        offset = offset + z.getDSTSavings();
    }
    int offsetHrs = offset / 1000 / 60 / 60;
    int offsetMins = offset / 1000 / 60 % 60;

    System.out.println("offset: " + offsetHrs);
    System.out.println("offset: " + offsetMins);

    c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
    c.add(Calendar.MINUTE, (-offsetMins));

    System.out.println("GMT Time: "+c.getTime());
Ahmad Nadeem
fuente
52

En realidad no es el tiempo, pero su representación podría cambiarse.

SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));

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.

Antonio
fuente
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

¡Incorrecto!

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
aGMTCalendar.getTime(); //or getTimeInMillis()

y

Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();

Volveremos al mismo tiempo. Idem para

new Date(); //it's not GMT.
simpatico
fuente
17

Este código imprime la hora actual UTC.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;


public class Test
{
    public static void main(final String[] args) throws ParseException
    {
        final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        f.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(f.format(new Date()));
    }
}

Resultado

2013-10-26 14:37:48 UTC
Adán
fuente
14

Esto funciona para obtener milisegundos UTC en Android.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
moberme
fuente
77
solo necesitas restar el desplazamiento?
tevch
c.add(Calendar.MILLISECOND, (-utcOffset))obtener Calendario con zona horaria utc
Shanavas M
10

Aquí está lo que parece ser incorrecto en la respuesta de Jon Skeet . Él dijo:

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.

Sin embargo, el código:

System.out.println(new java.util.Date().getHours() + " hours");

da las horas locales, no GMT (horas UTC), usando no Calendary no SimpleDateFormaten absoluto.

Por eso parece que algo es incorrecto.

Al juntar las respuestas, el código:

System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
                           .get(Calendar.HOUR_OF_DAY) + " Hours");

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.

Dana Wilson
fuente
66
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 = new Date();
System.out.println("Local: " + local);
DateTimeZone zone = DateTimeZone.getDefault();
long utc = zone.convertLocalToUTC(local.getTime(), false);
System.out.println("UTC: " + new Date(utc));
huljas
fuente
1
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)
Maciej Miklas
6

Puedes usar:

Calendar 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. 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.

mjh2007
fuente
6
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
Justin
fuente
Agregue alguna explicación a su respuesta, ¿en qué se diferencia de tantas otras respuestas?
akjoshi
¿Este método obtiene tiempo depende del calendario del dispositivo?
Arnold Brown el
6

Puedes usar esto directamente

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
nithinreddy
fuente
5

Con:

Calendar cal = Calendar.getInstance();

Luego caltenga la fecha y hora actuales.
También puede obtener la fecha y hora actual para la zona horaria con:

Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));

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.

usuario2427
fuente
66
Ciertos métodos y constructores de fecha y marca de tiempo están en desuso, pero las clases mismas no lo están.
Powerlord
5

Aquí otra sugerencia para obtener un objeto GMT Timestamp:

import java.sql.Timestamp;
import java.util.Calendar;

...

private static Timestamp getGMT() {
   Calendar cal = Calendar.getInstance();
   return new Timestamp(cal.getTimeInMillis()
                       -cal.get(Calendar.ZONE_OFFSET)
                       -cal.get(Calendar.DST_OFFSET));
}
René
fuente
5

Aquí hay otra forma de obtener la hora GMT en formato de cadena

String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString =  sdf.format(new Date());
shahtapa
fuente
5

Aquí está mi implementación de toUTC:

    public static Date toUTC(Date date){
    long datems = date.getTime();
    long timezoneoffset = TimeZone.getDefault().getOffset(datems);
    datems -= timezoneoffset;
    return new Date(datems);
}

Probablemente hay varias formas de mejorarlo, pero funciona para mí.

Ashallar
fuente
3

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;

public class TimZoneTest {
    public static void 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") );


    }

    public static String 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 = new SimpleDateFormat(format);
        date_format_gmt.setTimeZone(tz);
        return date_format_gmt.format(date);
    }

}

Salida

10/08/2011 21: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
so_mv
fuente
3

Sólo para hacerlo mas simple, para crear una Dateen la UTCque se puede utilizar Calendar:

Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Lo cual construirá una nueva instancia para Calendarusar el "UTC" TimeZone.

Si necesita un Dateobjeto de ese calendario, puede usarlo getTime().

Ovidiu Latcu
fuente
55
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 Zone

DateTime currDateTime = new DateTime(); //Current DateTime

long 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
Dios mío
fuente
1
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!

    Date currDate;
    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

    long currTime = 0;
    try {

        currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
        currTime = currDate.getTime();
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
Bogdan
fuente
2

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
{
private static final String TAG = "SntpClient";

private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;

private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;

// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

private long mNtpTime;

public boolean requestTime(String host, int timeout) {
    try {
        DatagramSocket socket = new DatagramSocket();
        socket.setSoTimeout(timeout);
        InetAddress address = InetAddress.getByName(host);
        byte[] buffer = new byte[NTP_PACKET_SIZE];
        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

        buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

        writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

        socket.send(request);

        // read the response
        DatagramPacket response = new DatagramPacket(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);
        return false;
    }

    return true;
}


public long getNtpTime() {
    return mNtpTime;
}


/**
 * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
 */
private long 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 values
    int 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).
 */    
private long 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
 */    
private void 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:

private String get_UTC_Datetime_from_timestamp(long timeStamp){

    try{

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();

        int tzt = tz.getOffset(System.currentTimeMillis());

        timeStamp -= tzt;

        // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
        DateFormat sdf = new SimpleDateFormat();
        Date netDate = (new Date(timeStamp));
        return sdf.format(netDate);
    }
    catch(Exception ex){
        return "";
     }
    } 

y úsalo con:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
Ingo
fuente
En una sola línea <br/> <pre> <code> Calendar utcTime = Calendar.getInstance (). Add (Calendar.MILLISECOND, -time.getTimeZone (). GetOffset (time.getTimeInMillis ())); </pre> < / code>
Harun
1
Sí, pero esto llama a la hora local del dispositivo, que podría cambiar manualmente del usuario a una fecha y hora falsa
Ingo
2
public static void main(String args[]){
    LocalDate date=LocalDate.now();  
    System.out.println("Current date = "+date);
}
Arjun Singh
fuente
1

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 ...

Hitesh
fuente
1

Esta es mi implementación:

public static String GetCurrentTimeStamp()
{
    Calendar cal=Calendar.getInstance();
    long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
    return new java.sql.Timestamp(System.currentTimeMillis()+offset).toString();    
}
Gal rom
fuente
1

Si desea evitar analizar la fecha y solo desea una marca de tiempo en GMT, puede usar:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));
Matthias van der Vlies
fuente
0

Si está usando el tiempo joda y desea el tiempo actual en milisegundos sin su desplazamiento local , puede usar esto:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
Managarm
fuente
0
public class CurrentUtcDate 
{
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("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-2018 13:14:35

Puede cambiar el formato de fecha según sea necesario.

santoshlokhande
fuente
1
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 );

o

LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );

Dependiendo de su aplicación necesita.

Como si
fuente
(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.
Basil Bourque