Como posso obter a data e hora atuais no UTC ou GMT em Java?


479

Quando crio um novo Dateobjeto, ele é inicializado no horário atual, mas no fuso horário local. Como posso obter a data e hora atuais no GMT?


Sei que esses tipos de tópicos são completamente discutidos, mas achei que o pacote commons-lang realmente lida bem com esses problemas comuns de java. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Confira os vários pacotes que eles possuem.

Que hora local você deseja e com que precisão. A maioria dos fusos horários é definida em relação ao UTC com um deslocamento fixo medido em segundos SI , mas a relação do GMT, que é baseada na observação solar e um segundo comprimento (ligeiramente) variável, é mais complexa. Os dois diferem em até 0,9 segundos.
Mc0e

1
A Datenão possui um fuso horário, portanto, "mas no fuso horário local" não está correto (ou impreciso, na melhor das hipóteses). Veja Tudo sobre java.util.Date .
Ole VV

Respostas:


409

java.util.Datenão possui fuso horário específico, embora seu valor seja mais comumente considerado em relação ao UTC. O que faz você pensar que é na hora local?

Para ser preciso: o valor em a java.util.Dateé o número de milissegundos desde a época do Unix, que ocorreu à meia-noite de 1º de janeiro de 1970, UTC. A mesma época também pode ser descrita em outros fusos horários, mas a descrição tradicional é em termos de UTC. Como há vários milissegundos desde uma época fixa, o valor interno java.util.Dateé o mesmo em todo o mundo a qualquer momento, independentemente do fuso horário local.

Suspeito que o problema é que você o está exibindo por meio de uma instância do Calendário que usa o fuso horário local, ou possivelmente usando Date.toString()também o fuso horário local, ou uma SimpleDateFormatinstância que, por padrão, também usa o fuso horário local.

Se este não for o problema, publique um código de exemplo.

No entanto, eu recomendaria que você usasse o Joda-Time de qualquer maneira, o que oferece uma API muito mais clara.


5
Então isso é provavelmente um problema de driver. Pode ser necessário definir sua conexão como UTC ou algo assim. Já vi problemas como esse antes, mas o problema não está no java.util.Date.
Jon Skeet

13
Behrang, de acordo com o stackoverflow.com/questions/4123534/… , o driver MySQL JDBC converte um dado java.util.Timestamp(ou java.util.Date) no fuso horário do servidor.
Derek Mahar

5
@Senhor. Cat: Como você está determinando isso? É por escrito System.out.println(new Date())? Nesse caso, você deve estar ciente de que é o toString()método que está aplicando o fuso horário lá ... caso contrário, forneça mais detalhes.
9119 Jon Skeet

8
@KanagaveluSugumar: toString()sempre usa o fuso horário padrão. date.getTime()definitivamente retorna milissegundos desde a época do Unix, no UTC. É mais preciso dizer que Dateele próprio não possui um fuso horário - é apenas um instante no tempo, que pode ser considerado em vários fusos horários. Mas quando você cria uma instância, isso não depende do seu fuso horário.
Jon Skeet

6
@Jemenake: Na verdade, isso não aconteceu quando era meia-noite em Greenwich, porque o Reino Unido estava no UTC + 1 na época. Apenas um dos trechos estranhos da história. Mas eu entendo o seu ponto - é melhor dizer que "new Date (). GetTime () retorna os milissegundos desde a época do Unix, que era meia-noite no início de 1º de janeiro de 1970, UTC". Portanto, o UTC faz parte da fixação da época em um determinado instante no tempo, não faz parte do resultado.
Jon Skeet

325

tl; dr

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

Gere uma String para representar esse valor:

Instant.now().toString()  

2016-09-13T23: 30: 52.123Z

Detalhes

Como a resposta correta de Jon Skeet afirmou, um objeto java.util.Date não tem fuso horário . Mas sua toStringimplementação aplica o fuso horário padrão da JVM ao gerar a representação String desse valor de data e hora. Confuso para o programador ingênuo, uma Data parece ter um fuso horário, mas não possui.

Os java.util.Date, j.u.Calendare java.text.SimpleDateFormataulas empacotados com Java são notoriamente problemático. Evite-os. Em vez disso, use uma destas bibliotecas de data e hora competentes:

java.time (Java 8)

O Java 8 traz um excelente novo pacote java.time. * Para substituir as antigas classes java.util.Date/Calendar.

Obter horário atual no UTC / GMT é uma linha simples…

Instant instant = Instant.now();

Essa Instantclasse é o bloco de construção básico em java.time, representando um momento na linha do tempo no UTC com uma resolução de nanossegundos .

No Java 8, o momento atual é capturado com resolução de até milissegundos. O Java 9 traz uma nova implementação de Clockcaptura do momento atual até a capacidade total de nanossegundos dessa classe, dependendo da capacidade do hardware do relógio do computador host.

Seu toStringmétodo gera uma representação String de seu valor usando um formato ISO 8601 específico . Esse formato gera zero, três, seis ou nove dígitos ( milissegundos , microssegundos ou nanossegundos ) conforme necessário para representar a fração de segundo.

Se você deseja formatação mais flexível ou outros recursos adicionais, aplique um deslocamento de UTC igual a zero, para que o próprio UTC ( ZoneOffset.UTCconstante ) obtenha a OffsetDateTime.

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

Despejar no console…

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

Quando correr ...

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

Tabela de tipos de data e hora em Java, modernos e herdados.


Sobre java.time

A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date, Calendar, e SimpleDateFormat.

Para saber mais, consulte o Tutorial Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .

Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de java.sql.*classes.

Onde obter as classes java.time?

Tabela de qual biblioteca java.time a ser usada com qual versão do Java ou Android

O projeto ThreeTen-Extra estende o java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval, YearWeek, YearQuarter, e mais .


Joda-Time

ATUALIZAÇÃO: O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para o java.time classes .

Usando o tempo de Joda biblioteca gratuita de código aberto terceiros, você pode obter a data e hora atual em apenas uma linha de código.

O Joda-Time inspirou as novas classes java.time. * No Java 8, mas tem uma arquitetura diferente. Você pode usar o Joda-Time em versões mais antigas do Java. O Joda-Time continua trabalhando no Java 8 e continua sendo mantido ativamente (a partir de 2014). No entanto, a equipe Joda-Time aconselha a migração para 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 exemplo mais detalhado (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 );

Despejar no console…

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

Quando correr ...

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 obter mais exemplos de código executando trabalhos de fuso horário, consulte minha resposta para uma pergunta semelhante.

Fuso horário

Eu recomendo que você sempre especifique um fuso horário em vez de depender implicitamente do fuso horário padrão atual da JVM (que pode mudar a qualquer momento!). Essa confiança parece ser uma causa comum de confusão e bugs no trabalho de data e hora.

Ao chamar, now()passe o fuso horário desejado / esperado a ser atribuído. Use a DateTimeZoneclasse.

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

Essa classe mantém uma constante para o fuso horário UTC .

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

Se você realmente deseja usar o fuso horário padrão atual da JVM, faça uma chamada explícita para que seu código seja auto-documentado.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

ISO 8601

Leia sobre os formatos ISO 8601 . O java.time e o Joda-Time usam os formatos sensíveis desse padrão como padrão para analisar e gerar strings.


Na verdade, java.util.Date faz ter um fuso horário, enterrada sob camadas de código-fonte. Para fins mais práticos, esse fuso horário é ignorado. Portanto, como abreviação, dizemos que java.util.Date não tem fuso horário. Além disso, esse fuso horário oculto não é o utilizado pelo toStringmétodo de Date ; esse método usa o fuso horário padrão atual da JVM. Mais uma razão para evitar essa classe confusa e ficar com Joda-Time e java.time.


2
DateTime.now().toDateTime(DateTimeZone.UTC)era o que eu estava procurando! Obrigado!
Managarm

1
@Managarm Você pode abreviá-lo para: DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
Basil Bourque

Como obter este com Pure Java 8 2014-01-21T15:34:29.933-08:00no exemplo que você usounew org.joda.time.DateTime()
GOXR3PLUS

1
@ GOXR3PLUS Obtemos ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() o momento atual para um fuso horário especificado. Em seguida, corte qualquer micros / nanos. Em seguida, convertemos para apenas um deslocamento de UTC (número de horas-minutos-segundos) em vez de um fuso horário completo (um histórico de alterações passadas, presentes e futuras no deslocamento usado pelas pessoas de um região em particular). Por fim, geramos texto representando o valor no OffsetDateTimeformato ISO 8601 padrão usado por padrão em seu toStringmétodo.
Basil Bourque

Obrigado por fornecer esta explicação detalhada, também +1 para o Android suporta :) @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
Por que você analisa com dateFormatLocal depois de usar o formato dateFormatGmt ... não faz sentido lendo-o. Tenho certeza de que funciona, mas apenas me perguntando?
MindWire

2
setTimeZone fez isso (eu acho que você também pode usar getTimeZone ( "UTC") mesmo que GMT?)
rogerdpack

6
mas o tempo depende do tempo definido pelo dispositivo. Se o usuário tem tempo errado set em seu dispositivo, então você vai ter UTC errado .correct-me se estou errado
Basavaraj Hampali

@BasavarajHampali mas no mundo de hoje a maioria dos dispositivos estão conectados à internet que corrige hora incorreta
Akshat Agarwal

3
Não há diferença horária entre o Tempo Universal Coordenado (UTC) e o Tempo Médio de Greenwich (GMT)
slott

86

Definitivamente, retorna a hora UTC: como objetos 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;
}

Na minha resposta, esqueci de mostrar como o DATEFORMAT está definido: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Someone Somewhere

21
Evite iniciar nomes de métodos com letras maiúsculas em Java. Consulte as convenções de codificação Java para nomes de métodos.
Florian Schrofner

2
Como sou redirecionado para esta resposta, a chamada new Date()nunca retornará a hora UTC correta, se a hora do dispositivo estiver incorreta.
Sanoop 02/03/19

esse método obtém tempo depende do calendário do dispositivo?
Arnold Brown

Uma coisa a notar. Qualquer solução que precise obter uma data ou carimbo de data / hora no UTC, parece que a chave é não reutilizar o SimpleDateFormat, mas usar uma para inserir o UTC em uma sequência e criar outro UTC ao converter a sequência em uma data ou Objeto de carimbo de data e hora. Notei que, se você tentar reutilizar o mesmo SimpleDateFormat, o objeto Date / Timestamp resultante será revertido para o fuso horário local em vez do UTC.
Brian Begun

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

Na verdade, não é hora, mas sua representação pode ser alterada.

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

O tempo é o mesmo em qualquer ponto da Terra, mas nossa percepção do tempo pode ser diferente dependendo da localização.


Sim, solução agradável e limpa. Só me preocupa, se é ineficaz criar um novo objeto Date em vez de apenas obter uma instância do Calendar?
Beemo

Será otimizado pela JVM e o HotSpot executará o código x86 mais eficaz possível
Antonio

17

Calendário aGMTCalendar = Calendar.getInstance (TimeZone.getTimeZone ("GMT")); Todas as operações executadas usando o objeto aGMTCalendar serão realizadas com o fuso horário GMT e não terão o horário de verão ou compensações fixas aplicadas

Errado!

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

e

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

retornará ao mesmo tempo. Idem para

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

17

Este código imprime a hora atual 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

14

Isso funciona para obter milissegundos UTC no Android.

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

7
somente você precisa subtrair o deslocamento?
tevch 27/07

c.add(Calendar.MILLISECOND, (-utcOffset))para obter Calendário com fuso horário UTC
shanavas M

10

Aqui está o que parece estar incorreto na resposta de Jon Skeet . Ele disse:

java.util.Dateestá sempre em UTC. O que faz você pensar que é na hora local? Eu suspeito que o problema é que você está exibindo-o por meio de uma instância do Google Agenda que usa o fuso horário local ou possivelmente usando o Date.toString()que também usa o fuso horário local.

No entanto, o código:

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

fornece as horas locais, não GMT (horas UTC), usando nenhum Calendare nenhum SimpleDateFormat.

É por isso que parece que algo está incorreto.

Reunindo as respostas, o código:

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

mostra as horas GMT em vez das horas locais - observe que getTime.getHours()está faltando porque isso criaria um Date()objeto que teoricamente armazena a data em GMT, mas devolve as horas no fuso horário local.


6
Eu não tinha visto essa resposta antes, mas se você ler a documentação para o Date.getHours()método descontinuado , fica muito claro: "O valor retornado é um número (0 a 23) que representa a hora do dia que contém ou começa com o valor instante no tempo representado por esse objeto Date, conforme interpretado no fuso horário local . " (Ênfase minha.) É o getHours()método que interpreta o valor no fuso horário local - não faz parte do estado do Datepróprio objeto.
11133 Jon Skeet

2
Como Jon Skeet afirmou corretamente, um objeto java.util.Date não tem fuso horário . Mas, de maneira confusa, os métodos toStringe getHoursaplicam o fuso horário padrão à saída. Portanto, programadores ingênuos são facilmente enganados, pois parece que um Date tem um fuso horário, mas na verdade não.
Basil Bourque

7

Se você deseja um objeto Date com campos ajustados para UTC, pode fazê-lo assim com o 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
Você está trabalhando demais. Joda-Time pode fazer isso em uma única linha de código. Veja minha própria resposta sobre esta questão. Chame o .toDateTimemétodo e passe a constante para o fuso horário UTC.
Basil Bourque

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

6

Você pode usar:

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

Todas as operações executadas usando o objeto aGMTCalendar serão realizadas com o fuso horário GMT e não terão o horário de verão ou compensações fixas aplicadas. Eu acho que o pôster anterior está correto que o objeto Date () sempre retorna um GMT, não é até você fazer algo com o objeto date que ele é convertido no fuso horário local.


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

Por favor, adicione alguma explicação à sua resposta, como é diferente de tantas outras respostas?
akjoshi

esse método obtém tempo depende do calendário do dispositivo?
Arnold Brown

6

Você pode usar isso diretamente

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

5

Com:

Calendar cal = Calendar.getInstance();

Depois, caltenha a data e hora atuais.
Você também pode obter a Data e Hora atuais do fuso horário com:

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

Você pode perguntar cal.get(Calendar.DATE);ou outra constante do Calendário sobre outros detalhes.
A data e o carimbo de data e hora foram preteridos em Java. A aula do calendário não é.


6
Certos métodos e construtores de Date e Timestamp foram descontinuados, mas as próprias classes não são.
Powerlord 21/11/08

5

Aqui está outra sugestão para obter um 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));
}

5

Aqui está outra maneira de obter o horário GMT no 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

Aqui está minha implementação do toUTC:

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

Provavelmente existem várias maneiras de melhorar, mas funciona para mim.


3

Código de amostra para renderizar a hora do sistema em um fuso horário específico e em um 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);
    }

}

Resultado

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

Apenas para simplificar, para criar um Date, UTCvocê pode usar Calendar:

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

O que criará uma nova instância para Calendarusar o "UTC" TimeZone.

Se você precisar de um Dateobjeto desse calendário, poderá usar getTime().


5
Se você chamar getTime (), perderá as informações do fuso horário e retornará a hora local.
RealCasually

3

Convertendo DateTime Atual em 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
Você está fazendo muito trabalho aqui. (a) O padrão do formatador que você define já está incorporado em um DateTime por padrão; basta chamar toStringum DateTime para obter esse padrão de string ISO 8601 . (b) Código em excesso para converter entre fusos horários. Simplesmente chame "toDateTime" e passe um objeto de fuso horário. Como esta: myDateTime.toDateTime( DateTimeZone.UTC ). Para um fuso horário específico, instancie e passe um objeto de fuso horário com base em um nome próprio , chamada myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Basil Bourque

2

Isso funcionou para mim, retorna o timestamp no 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

Use esta classe para obter sempre a hora UTC correta de um servidor NTP on-line:

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 use-o com:

        long now = 0;

        NTP_UTC_Time client = new NTP_UTC_Time();

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

Se você precisar da Hora UTC "agora" como DateTimeString, use a função:

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 use-o com:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);

Na única linha <br/> <pre> <code> Calendário utcTime = Calendar.getInstance (). Add (Calendar.MILLISECOND, -time.getTimeZone (). GetOffset (time.getTimeInMillis ())); </pre> < / código>
Harun

1
Sim, mas isso chama o horário local do dispositivo, que pode ser alterado manualmente do usuário para um falso DateTime
Ingo

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

1

Para simplificar. Um objeto de calendário armazena informações sobre o fuso horário, mas quando você executa cal.getTime (), as informações do fuso horário são perdidas. Portanto, para conversões de fuso horário, aconselhamos o uso de classes DateFormat ...


1

esta é a minha implementação:

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 você deseja evitar a análise da data e deseja apenas um carimbo de data e hora no GMT, use:

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

0

Se você estiver usando o tempo joda e quiser o horário atual em milissegundos sem o deslocamento local, poderá usar o seguinte:

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

Resultado:

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

Você pode alterar o formato da data, conforme necessário.


1
Por favor, não ensine os jovens a usar o há muito desatualizado e notoriamente problemático SimpleDateFormat. Hoje temos muito melhor na java.timemoderna API de data e hora de Java . Além disso, o que você está fornecendo que ainda não está nas respostas de Dan, Antonio e outros?
VV Ole Ole

2
(a) Como essa resposta agrega valor às dezenas de respostas existentes? (b) As classes problemáticas usadas aqui foram substituídas anos atrás pelas modernas classes java.time . Sugerir seu uso em 2018 é um péssimo conselho.
Basil Bourque

0

Use o pacote java.time e inclua os códigos abaixo

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

ou

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

dependendo da necessidade do seu aplicativo.


(A) Se estiver usando um deslocamento ( ZoneOffset) em vez de um fuso horário ( ZoneId), OffsetDateTimeé mais apropriado que ZonedDateTime. (B) LocalDateTimenão deve ser usado para capturar o momento atual, pois não possui conceito de fuso horário ou deslocamento do UTC. (C) Outras respostas preexistentes cobriram este material e fizeram um trabalho melhor. Não vejo como esta resposta agrega valor.
Basil Bourque
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.