Come posso ottenere la data e l'ora correnti in UTC o GMT in Java?


479

Quando creo un nuovo Dateoggetto, questo viene inizializzato all'ora corrente ma nel fuso orario locale. Come posso ottenere la data e l'ora correnti in GMT?


So che questi tipi di argomenti sono completamente discussi, ma ho scoperto che il pacchetto commons-lang gestisce davvero bene questi problemi comuni di Java. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Scopri i vari pacchetti che hanno.

Quale ora locale vuoi e con quale precisione. La maggior parte dei fusi orari sono definiti rispetto all'UTC con un offset fisso misurato in SI secondi, ma la relazione di GMT che si basa sull'osservazione solare e un secondo (leggermente) di lunghezza variabile è più complessa. I due differiscono per un massimo di 0,9 secondi.
MC0e,

1
A Datenon contiene un fuso orario, quindi "ma nel fuso orario locale" non è corretto (o, nella migliore delle ipotesi, impreciso). Vedi Tutto su java.util.Data .
Ole VV

Risposte:


409

java.util.Datenon ha un fuso orario specifico, sebbene il suo valore sia più comunemente pensato in relazione a UTC. Cosa ti fa pensare che sia nell'ora locale?

Per essere precisi: il valore all'interno di a java.util.Dateè il numero di millisecondi dall'epoca di Unix, avvenuta a mezzanotte del 1 gennaio 1970, UTC. La stessa epoca potrebbe essere descritta anche in altri fusi orari, ma la descrizione tradizionale è in termini di UTC. Dato che è un numero di millisecondi da un'epoca fissa, il valore all'interno java.util.Dateè lo stesso in tutto il mondo in qualsiasi istante particolare, indipendentemente dal fuso orario locale.

Ho il sospetto che il problema sia che lo stai visualizzando tramite un'istanza di Calendar che utilizza il fuso orario locale, o possibilmente utilizzando il Date.toString()quale utilizza anche il fuso orario locale o SimpleDateFormatun'istanza che, per impostazione predefinita, utilizza anche il fuso orario locale.

Se questo non è il problema, si prega di inviare un codice di esempio.

Consiglio comunque di usare Joda-Time , che offre un'API molto più chiara.


5
Quindi questo è probabilmente un problema di driver. Potrebbe essere necessario impostare la connessione su UTC o qualcosa del genere. Ho visto problemi come questo prima, ma il problema non è in java.util.Date.
Jon Skeet,

13
Behrang, secondo stackoverflow.com/questions/4123534/… , il driver MySQL JDBC converte un dato java.util.Timestamp(o java.util.Date) fuso orario nel server.
Derek Mahar,

5
@Sig. Cat: Come lo stai determinando? È scrivendo System.out.println(new Date())? In tal caso, dovresti essere consapevole del fatto che è il toString()metodo che applica il fuso orario lì ... in caso contrario, fornisci maggiori dettagli.
Jon Skeet,

8
@KanagaveluSugumar: toString()utilizza sempre il fuso orario predefinito. date.getTime()restituisce sicuramente millisecondi dall'epoca di Unix, in UTC. È più preciso affermare che di per Datesé non ha affatto un fuso orario - è solo un istante nel tempo, che potrebbe essere considerato in più fusi orari. Ma quando crei un'istanza, non dipende dal tuo fuso orario.
Jon Skeet,

6
@Jemenake: In realtà non è successo quando era mezzanotte a Greenwich, perché al momento il Regno Unito era in UTC + 1. Solo uno dei pezzi strani della storia. Ma prendo il punto - è meglio dire "nuova data (). GetTime () restituisce i millisecondi dall'epoca di Unix, che era mezzanotte all'inizio del 1 gennaio 1970, UTC". Quindi l'UTC fa parte del fissare l'epoca a un particolare istante nel tempo, non parte del risultato.
Jon Skeet,

325

tl; dr

Instant.now()   // Capture the current moment in UTC. 

Genera una stringa per rappresentare quel valore:

Instant.now().toString()  

2016-09-13T23: 30: 52.123Z

Dettagli

Come affermato dalla risposta corretta di Jon Skeet , un oggetto java.util.Date non ha fuso orario . Ma la sua toStringimplementazione applica il fuso orario predefinito della JVM quando genera la rappresentazione String di quel valore data-ora. Confusamente per il programmatore ingenuo, un Date sembra avere un fuso orario ma non lo è.

I java.util.Date, j.u.Calendare java.text.SimpleDateFormatle classi Java in bundle con sono notoriamente fastidiosi. Evitali. Utilizzare invece una di queste librerie di data e ora competenti:

java.time (Java 8)

Java 8 offre un nuovo eccellente pacchetto java.time. * Per soppiantare le vecchie classi java.util.Date/Calendar.

Ottenere l'ora corrente in UTC / GMT è un semplice one-liner ...

Instant instant = Instant.now();

Quella Instantclasse è il blocco base di java.time, che rappresenta un momento sulla linea temporale in UTC con una risoluzione di nanosecondi .

In Java 8, il momento attuale viene acquisito con una risoluzione fino a millisecondi. Java 9 porta una nuova implementazione di Clockacquisizioni del momento attuale fino alla piena capacità di nanosecondi di questa classe, a seconda della capacità dell'hardware di clock del tuo computer host.

Il suo toStringmetodo genera una rappresentazione String del suo valore usando uno specifico formato ISO 8601 . Quel formato genera cifre a zero, tre, sei o nove cifre ( millisecondi , microsecondi o nanosecondi ) secondo necessità per rappresentare la frazione di secondo.

Se desideri una formattazione più flessibile o altre funzionalità aggiuntive, applica uno scostamento da UTC pari a zero, affinché UTC stesso ( ZoneOffset.UTCcostante ) ottenga un OffsetDateTime.

OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );

Dump per console ...

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

Quando eseguito ...

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

Tabella dei tipi di data e ora in Java, sia moderni che legacy.


Informazioni su java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date, Calendar, e SimpleDateFormat.

Per saperne di più, consulta il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Il progetto Joda-Time , ora in modalità manutenzione , consiglia la migrazione alle classi java.time .

Puoi scambiare oggetti java.time direttamente con il tuo database. Utilizzare un driver JDBC conforme a JDBC 4.2 o successivo. Non c'è bisogno di stringhe, non c'è bisogno di java.sql.*classi.

Dove ottenere le classi java.time?

Tabella della libreria java.time da utilizzare con la versione di Java o Android

Il progetto ThreeTen-Extra estende java.time con classi aggiuntive. Questo progetto è un banco di prova per possibili aggiunte future a java.time. Si possono trovare alcune classi utili, come per esempio Interval, YearWeek, YearQuartere altro .


Joda-Time

AGGIORNAMENTO: il progetto Joda-Time , ora in modalità manutenzione , consiglia la migrazione alle classi java.time .

Utilizzando la libreria gratuita open source di terze parti di Joda-Time , è possibile ottenere la data-ora corrente in una sola riga di codice.

Joda-Time ha ispirato le nuove classi java.time. * In Java 8, ma ha un'architettura diversa. È possibile utilizzare Joda-Time nelle versioni precedenti di Java. Joda-Time continua a funzionare in Java 8 e continua a essere attivamente mantenuto (dal 2014). Tuttavia, il team di Joda-Time consiglia la migrazione a java.time.

System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );

Codice di esempio più dettagliato (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 );

Dump per console ...

System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );

Quando eseguito ...

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

Per ulteriori esempi di codice che funzionano con il fuso orario, vedere la mia risposta a una domanda simile.

Fuso orario

Ti consiglio di specificare sempre un fuso orario piuttosto che fare affidamento implicito sul fuso orario predefinito corrente della JVM (che può cambiare in qualsiasi momento!). Tale dipendenza sembra essere una causa comune di confusione e bug nel lavoro di data e ora.

Quando si chiama, now()passare il fuso orario desiderato / previsto da assegnare. Usa la DateTimeZoneclasse.

DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );

Quella classe contiene una costante per il fuso orario UTC .

DateTime now = DateTime.now( DateTimeZone.UTC );

Se si desidera veramente utilizzare l'attuale fuso orario predefinito della JVM, effettuare una chiamata esplicita in modo che il codice sia autocompattante.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

ISO 8601

Leggi i formati ISO 8601 . Sia java.time che Joda-Time usano i formati sensibili di quello standard come valori predefiniti sia per l'analisi che per la generazione di stringhe.


In realtà, java.util.Date ha un fuso orario, sepolta sotto strati di codice sorgente. Ai fini più pratici, quel fuso orario viene ignorato. Quindi, come abbreviazione, diciamo che java.util.Date non ha fuso orario. Inoltre, quel fuso orario sepolto non è quello usato dal toStringmetodo Date ; quel metodo usa l'attuale fuso orario predefinito della JVM. Un motivo in più per evitare questa classe confusa e rimanere con Joda-Time e java.time.


2
DateTime.now().toDateTime(DateTimeZone.UTC)era quello che stavo cercando! Grazie!
Managarm,

1
@Managarm Puoi accorciarlo a: DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
Basil Bourque l'

Come ottenerlo con Pure Java 8 2014-01-21T15:34:29.933-08:00nell'esempio che hai usatonew org.joda.time.DateTime()
GOXR3PLUS

1
@ GOXR3PLUS ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() Otteniamo il momento corrente per un fuso orario specificato. Quindi, eliminare tutti i micros / nanos. Quindi convertiamo ad avere solo un semplice offset da UTC (numero di ore-minuti-secondi) piuttosto che un fuso orario completo (una storia di cambiamenti passati, presenti e futuri nell'offset usato dalle persone di un regione particolare). Infine, generiamo testo che rappresenta il valore in quello OffsetDateTimesecondo il formato ISO 8601 standard usato di default nel suo toStringmetodo.
Basil Bourque,

Grazie per aver fornito questa spiegazione dettagliata, anche +1 per i supporti 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()) );

11
Perché analizzare dateFormatLocal dopo aver usato il formato dateFormatGmt ... non ha senso leggerlo. Sono sicuro che funziona, ma mi chiedo solo?
MindWire,

2
setTimeZone ha fatto (suppongo che tu possa usare anche getTimeZone ("UTC") stessa cosa di GMT?)
rogerdpack

6
ma il tempo dipende dal tempo impostato del dispositivo. Se l'utente ha impostato l'ora sbagliata sul suo dispositivo, allora sbaglierai UTC. Correggimi se sbaglio
Basavaraj Hampali

@BasavarajHampali ma nel mondo di oggi la maggior parte dei dispositivi sono collegati a Internet che corregge i tempi errati
Akshat Agarwal

3
Non c'è nessuna differenza di fuso orario tra Coordinated Universal Time (UTC) e Greenwich Mean Time (GMT)
slott

86

Questo sicuramente restituisce l'ora UTC: come oggetti String e 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;
}

Nella mia risposta ho dimenticato di mostrare come è definito DATEFORMAT: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Someone Somewhere

21
Evitare di iniziare i nomi dei metodi con maiuscole in Java. Vedere le convenzioni di codifica Java per i nomi dei metodi.
Florian Schrofner,

2
Come reindirizzato a questa risposta, Calling new Date()non restituirà mai l'ora UTC corretta, se l'ora del dispositivo è errata.
Sanoop,

questo metodo ottiene tempo dipende dal calendario del dispositivo?
Arnold Brown,

Una cosa da notare. Qualsiasi soluzione che debba ottenere una data o un timestamp in UTC, sembra che la chiave sia non riutilizzare SimpleDateFormat, ma piuttosto usarne uno per ottenere UTC in una stringa, quindi creare un altro UTC quando si converte la stringa in una data o oggetto Timestamp. Ho notato che se si tenta di riutilizzare lo stesso SimpleDateFormat, l'oggetto Date / Timestamp risultante tornerà al fuso orario locale anziché UTC.
Brian ha iniziato il

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

52

In realtà non è il momento, ma la sua rappresentazione potrebbe essere cambiata.

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

Il tempo è lo stesso in qualsiasi punto della Terra, ma la nostra percezione del tempo potrebbe essere diversa a seconda della posizione.


Sì, soluzione piacevole e pulita. Mi preoccupa solo se è inefficace creare un nuovo oggetto Date invece di ottenere semplicemente l'istanza di Calendar?
Beemo,

Sarà ottimizzato da JVM e HotSpot eseguirà il codice x86 più efficace possibile
Antonio,

17

Calendar aGMTCalendar = Calendar.getInstance (TimeZone.getTimeZone ("GMT")); Quindi tutte le operazioni eseguite utilizzando l'oggetto aGMTCalendar verranno eseguite con il fuso orario GMT e non saranno applicate l'ora legale o gli offset fissi applicati

Sbagliato!

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

e

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

tornerà allo stesso tempo. Idem per

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

17

Questo codice stampa l'ora corrente 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()));
    }
}

Risultato

2013-10-26 14:37:48 UTC

14

Questo funziona per ottenere millisecondi UTC in Android.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;

7
solo tu devi sottrarre l'offset?
martedì

c.add(Calendar.MILLISECOND, (-utcOffset))per ottenere il Calendario con fuso orario
utc

10

Ecco cosa sembra errato nella risposta di Jon Skeet . Egli ha detto:

java.util.Dateè sempre in UTC. Cosa ti fa pensare che sia nell'ora locale? Ho il sospetto che il problema sia che lo stai visualizzando tramite un'istanza di Calendar che utilizza il fuso orario locale, o possibilmente utilizzando Date.toString()che utilizza anche il fuso orario locale.

Tuttavia, il codice:

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

fornisce le ore locali, non GMT (ore UTC), utilizzando no Calendare no SimpleDateFormat.

Ecco perché sembra che qualcosa non sia corretto.

Mettendo insieme le risposte, il codice:

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

mostra le ore GMT anziché le ore locali - nota che getTime.getHours()manca perché creerebbe un Date()oggetto, che teoricamente memorizza la data in GMT, ma restituisce le ore nel fuso orario locale.


6
Non avevo mai visto questa risposta prima, ma se leggi la documentazione per il Date.getHours()metodo obsoleto , lo rende molto chiaro: "Il valore restituito è un numero (da 0 a 23) che rappresenta l'ora entro il giorno che contiene o inizia con il istante nel tempo rappresentato da questo oggetto Date, come interpretato nel fuso orario locale . " (Enfasi mia.) È il getHours()metodo che interpreta il valore all'interno del fuso orario locale - non fa parte dello stato Datedell'oggetto stesso.
Jon Skeet,

2
Come correttamente affermato da Jon Skeet, un oggetto java.util.Date non ha fuso orario . Ma confusamente, i metodi toStringe getHoursapplicano il fuso orario predefinito al loro output. Quindi, i programmatori ingenui vengono facilmente ingannati come sembra che una data abbia un fuso orario, ma in realtà no.
Basil Bourque,

7

Se vuoi un oggetto Date con campi regolati per UTC puoi farlo in questo modo 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));

1
Stai lavorando troppo duramente. Joda-Time può farlo in una singola riga di codice. Vedi la mia risposta su questa domanda. Chiamare il .toDateTimemetodo e passare la costante per il fuso orario UTC.
Basil Bourque,

1
DateTime utcDate = new DateTime (). ToDateTime (DateTimeZone.UTC)
Maciej Miklas,

6

Puoi usare:

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

Quindi tutte le operazioni eseguite utilizzando l'oggetto aGMTCalendar verranno eseguite con il fuso orario GMT e non verranno applicate l'ora legale o gli offset fissi. Penso che il poster precedente sia corretto che l'oggetto Date () restituisca sempre un GMT non è fino a quando non si va a fare qualcosa con l'oggetto data che viene convertito nel fuso orario locale.


6
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));

Per favore, aggiungi qualche spiegazione alla tua risposta, in che cosa differisce da tante altre risposte?
Akjoshi il

questo metodo ottiene tempo dipende dal calendario del dispositivo?
Arnold Brown,

6

Puoi usarlo direttamente

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

5

Con:

Calendar cal = Calendar.getInstance();

Quindi calavere la data e l'ora correnti.
È inoltre possibile ottenere la data e l'ora correnti per il fuso orario con:

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

Potresti chiedere cal.get(Calendar.DATE);o altre costanti del Calendario su altri dettagli.
Data e ora sono obsoleti in Java. La classe del calendario non lo è.


6
Alcuni metodi e costruttori di Date e Timestamp sono obsoleti, ma le classi stesse non lo sono.
Powerlord,

5

Ecco un altro suggerimento per ottenere un oggetto Timestamp GMT:

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

5

Ecco un altro modo per ottenere l'ora GMT in formato String

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

5

Ecco la mia implementazione di toUTC:

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

Probabilmente ci sono diversi modi per migliorarlo, ma funziona per me.


3

Codice di esempio per il rendering dell'ora di sistema in un fuso orario specifico e un formato specifico.

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

}

Produzione

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

3

Solo per rendere questo più semplice, per creare un Datein UTCpuoi usare Calendar:

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

Che costruirà una nuova istanza per l' Calendarutilizzo di "UTC" TimeZone.

Se hai bisogno di un Dateoggetto da quel calendario, puoi semplicemente usarlo getTime().


5
Chiamare getTime () su questo fa perdere le informazioni sul fuso orario e restituire l'ora locale.
RealCasually,

3

Conversione dell'ora corrente in 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

1
Stai facendo troppo lavoro qui. (a) Il modello di formattazione definito è già incorporato in un DateTime per impostazione predefinita; basta chiamare toStringun DateTime per ottenere quel modello di stringa ISO 8601 . (b) Troppo codice da convertire tra i fusi orari. Basta chiamare "toDateTime" e passare un oggetto fuso orario. Come questo: myDateTime.toDateTime( DateTimeZone.UTC ). Per un fuso orario specifico, creare un'istanza e passare un oggetto fuso orario in base a un nome proprio , chiamare myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Basil Bourque,

2

Questo ha funzionato per me, restituisce il timestamp in 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();
    }

2

Usa questa classe per ottenere sempre l'ora UTC corretta da un server NTP online:

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

}

E usalo con:

        long now = 0;

        NTP_UTC_Time client = new NTP_UTC_Time();

        if (client.requestTime("pool.ntp.org", 2000)) {              
          now = client.getNtpTime();
        }

Se hai bisogno dell'ora UTC "adesso" come DateTimeString usa la funzione:

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 "";
     }
    } 

e usalo con:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);

A riga singola <br/> <pre> <code> Calendar utcTime = Calendar.getInstance (). Add (Calendar.MILLISECOND, -time.getTimeZone (). GetOffset (time.getTimeInMillis ())); </pre> < / code>
Harun,

1
Sì, ma questo chiama l'ora del dispositivo locale, che potrebbe essere modificata manualmente dall'utente in un DateTime falso
Ingo

2
public static void main(String args[]){
    LocalDate date=LocalDate.now();  
    System.out.println("Current date = "+date);
}

1

Per dirla semplice. Un oggetto calendario memorizza informazioni sul fuso orario ma quando si esegue cal.getTime (), le informazioni sul fuso orario andranno perse. Quindi, per le conversioni del fuso orario, consiglierò di usare le classi DateFormat ...


1

questa è la mia implementazione:

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

1

Se vuoi evitare di analizzare la data e vuoi solo un timestamp in GMT, puoi usare:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));

0

Se stai usando l'ora di Joda e vuoi l'ora corrente in millisecondi senza il tuo offset locale puoi usare questo:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());

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

Produzione:

UTC Time is: 22-01-2018 13:14:35

È possibile modificare il formato della data secondo necessità.


1
Per favore, non insegnare ai giovani a usare il vecchio obsoleto e notoriamente problematico SimpleDateFormat. Oggi abbiamo molto meglio nella java.timemoderna API di data e ora di Java . Inoltre cosa stai fornendo che non è già nelle risposte di Dan, Antonio e altri?
Ole VV,

2
(a) In che modo questa risposta aggiunge valore alle dozzine di risposte esistenti? (b) Le classi problematiche utilizzate qui sono state soppiantate anni fa dalle moderne classi java.time . Suggerire il loro uso nel 2018 è un cattivo consiglio.
Basil Bourque,

0

Usa il pacchetto java.time e includi sotto il codice-

ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );

o

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

a seconda delle esigenze dell'applicazione.


(A) Se si utilizza un offset ( ZoneOffset) anziché un fuso orario ( ZoneId), OffsetDateTimeè più appropriato di ZonedDateTime. (B) LocalDateTimenon dovrebbe essere usato per catturare il momento attuale in quanto non ha il concetto di fuso orario o offset da UTC. (C) Altre risposte preesistenti hanno coperto questo materiale e fatto un lavoro migliore. Non vedo come questa risposta aggiunga valore.
Basil Bourque,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.