Como converter currentTimeMillis para uma data em Java?


140

Tenho milissegundos em determinado arquivo de log gerado no servidor, também sei o código de idioma de onde o arquivo de log foi gerado. Meu problema é converter milissegundos para a data no formato especificado. O processamento desse log está acontecendo no servidor localizado em fuso horário diferente. Enquanto a conversão para o programa "SimpleDateFormat" está ocorrendo a data da máquina, essa data formatada não representa a hora correta do servidor. Existe alguma maneira de lidar com isso com elegância?

long yourmilliseconds = 1322018752992l;
        //1322018752992-Nov 22, 2011 9:25:52 PM 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);

System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));

DateTime jodaTime = new DateTime(yourmilliseconds, 
                    DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");

System.out.println("jodaTime "+parser1.print(jodaTime));

Resultado:

Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992

Não confunda Localidade com fuso horário. Totalmente separado. O código de idioma determina o idioma humano para o nome de meses e dias, e normas culturais como ordem de peças como mês, dia etc. Um fuso horário é diferenciado do UTC mais regras para lidar com anomalias como o horário de verão.
Basil Bourque

O problema era que o número de milissegundos era uma contagem não de 1970-01-01T00: 00: 00Z, mas de algum outro momento?
Basil Bourque

Para sua informação, tanto as terríveis e antigas classes de data e hora ( GregorianCalendar, SimpleDateFormatetc.) quanto a excelente biblioteca Joda-Time agora são substituídas pelas modernas classes java.time .
Basil Bourque

Respostas:


115
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);

Eu tive que definir o Calendário como final para fazê-lo funcionar. final Calendar calendar = Calendar.getInstance();
Victor Augusto

4
Os objetos de calendário são geralmente considerados bastante grandes, portanto, devem ser evitados quando possível. Um objeto Date será melhor, supondo que ele tenha a funcionalidade necessária. "Data da data = nova data (milis);" fornecidas na outra resposta por AVD usuário vai ser a melhor rota :)
Dick Lucas

1
De alguma forma, para 1515436200000l, eu estou recebendo calendar.get(Calendar.MONTH))como 0!
Sajib Acharya

FYI, os terrivelmente problemáticas aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado , suplantado pelos java.time classes internas em Java 8 e posterior. Consulte o Tutorial da Oracle .
Basil Bourque

2
@SajibAcharya Observe que as instâncias para Calendar.MONTH começam em 0; você precisa adicionar um para obter o mês "real" como o conhecemos. Exemplo: 0 = janeiro, 1 = fevereiro, 2 = março, etc.
shagberg

256

Você pode usar java.util.Dateclasse e, em seguida, usar SimpleDateFormatpara formatar o Date.

Date date=new Date(millis);

Podemos usar o pacote java.time (tutorial) - APIs DateTime introduzidas no Java SE 8.

var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
                        .ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
                            .ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));

// Format the date

var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);

2
Muito mais eficiente.
Chad Bingham

2
Não. Nem todos os métodos de java.util.Datesão depreciados. (Há APIs de data e hora aprimoradas nos JDK8 java.time))
adatapost 15/09/15

1
@RafaelZeffa, o '' 'Data (data de comprimento)' '' construtor não é obsoleto
Gugelhupf

O objeto Data é fornecido para compatibilidade com versões anteriores. Melhor usar o Calendário, conforme sugerido acima.
Ton Snoei

2
FYI, os terrivelmente problemáticas aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado , suplantado pelos java.time classes internas em Java 8 e posterior. Consulte o Tutorial da Oracle .
Basil Bourque

24

tl; dr

Instant.ofEpochMilli( 1_322_018_752_992L )     // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
       .atZone( ZoneId.of( "Africa/Tunis" ) )  // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.

Detalhes

As outras respostas usam classes obsoletas ou incorretas.

Evite as classes de data e hora antigas, como java.util.Date/.Calendar. Eles provaram ser mal projetados, confusos e problemáticos.

java.time

A estrutura java.time é incorporada ao Java 8 e posterior. Grande parte da funcionalidade é suportada para Java 6 e 7 e mais adaptada para Android . Feito por algumas das mesmas pessoas que fizeram o Joda-Time .

An Instanté um momento na linha do tempo no UTC com uma resolução de nanossegundos . Sua época é o primeiro momento de 1970 no UTC.

Assumindo que seus dados de entrada são uma contagem de milissegundos de 01-01-2009T00: 00: 00Z (não está claro na pergunta), podemos instanciar facilmente um Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

Clique aqui para mais definições de Imediato

A cadeia de caracteres no formato ISO 8601Z padrão é abreviada e significa UTCZulu .

Aplique um fuso horário usando um nome de fuso horário adequado para obter um ZonedDateTime.

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );

Veja este código executado ao vivo em IdeOne.com .

Asia/Kolkata fuso horário ?

Suponho que o seu fuso horário na Índia esteja afetando seu código. Vemos aqui que o ajuste no Asia/Kolkatafuso horário gera a mesma hora do dia que você informa, 08:55cinco horas e meia antes do valor UTC 03:25.

2011-11-23T08: 55: 52.992 + 05: 30 [Ásia / Calcutá]

Zona padrão

Você pode aplicar o fuso horário padrão atual da JVM. Cuidado: o padrão pode mudar a qualquer momento durante o tempo de execução . Qualquer código em qualquer encadeamento de qualquer aplicativo na JVM pode alterar o padrão atual. Se importante, peça ao usuário o fuso horário desejado / esperado.

ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

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.

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

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

Com um driver JDBC em conformidade com o JDBC 4.2 ou posterior, você pode trocar objetos java.time diretamente com seu banco de dados. Não há necessidade de strings ou classes java.sql. *.

Onde obter as classes java.time?

  • Java SE 8 , Java SE 9 e posterior
    • Construídas em.
    • Parte da API Java padrão com uma implementação em pacote configurável.
    • O Java 9 adiciona alguns recursos e correções menores.
  • Java SE 6 e Java SE 7
    • Grande parte da funcionalidade java.time é portada para Java 6 e 7 no ThreeTen-Backport .
  • Android
    • Versões posteriores das implementações do pacote Android das classes java.time.
    • Para anteriormente Android, o ThreeTenABP projeto adapta ThreeTen-Backport (mencionados acima). Consulte Como usar o ThreeTenABP… .

O projeto ThreeTen-Extra estende 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 .


Seria fácil converter o Instant que você recomendou acima no fuso horário local que é o padrão em um dispositivo (por exemplo, um smartphone)?
AJW

1
@AJW Sim. Ligue ZoneId.systemDefault(). Veja a nova seção adicionada ao final da minha resposta.
Basil Bourque 29/04

Excelente, vou tentar.
AJW 29/04

14

A maneira mais fácil de fazer isso é usar a classe Joda DateTime e especificar o registro de data e hora em milissegundos e o DateTimeZone desejado.

Eu recomendo fortemente evitar as classes Java Date e Calendar internas; Eles são terríveis.


O GorgianCalender não funcionou ... por qualquer motivo que levou o fuso horário padrão do sistema. Joda funcionou perfeitamente.
Amit

Deixe-me saber olhando o código de exemplo, se pudermos fazer algo diferente com o gregoriano
Amit

1
Para sua informação, o projeto Joda-Time agora está no modo de manutenção , aconselhando a migração para as classes java.time . Consulte o Tutorial da Oracle .
Basil Bourque

13

Se o valor em milissegundos for o número de milissegundos desde 1º de janeiro de 1970 GMT, como é padrão para a JVM, isso será independente do fuso horário. Se você deseja formatá-lo com um fuso horário específico, basta convertê-lo em um objeto GregorianCalendar e definir o fuso horário. Depois disso, existem várias maneiras de formatá-lo.


1
Este é o código de exemplo com GregorianCalendar e Joda, estou obtendo saída correta com Joda, mas não com Gregorian GregorianCalendar calendar = new GregorianCalendar (TimeZone.getTimeZone ("US / Central")); calendar.setTimeInMillis (yourmilliseconds); DateTime jodaTime = new DateTime (yourmilliseconds, DateTimeZone.forTimeZone (TimeZone.getTimeZone ("US / Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern ("aaaa-MM-dd HH: mm: ss, SSS");
Amit

A configuração do fuso horário no objeto de calendário não funcionou, mas a configuração no objeto do formatador de datas funcionou?
Bill

O que é DateTime e DateTimeFormatter ??
SweetWisherツ

11

Minha solução

public class CalendarUtils {

    public static String dateFormat = "dd-MM-yyyy hh:mm";
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

    public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Long.parseLong(milliSeconds));
        return simpleDateFormat.format(calendar.getTime());
    }
}

6

Eu faço assim:

static String formatDate(long dateInMillis) {
    Date date = new Date(dateInMillis);
    return DateFormat.getDateInstance().format(date);
}

Você também pode usar getDateInstance(int style)com os seguintes parâmetros:

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT



5

Caminho mais fácil:

private String millisToDate(long millis){

    return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
    //You can use DateFormat.LONG instead of SHORT

}

2

Abaixo está minha solução para obter a data de milissegundos para o formato de data. Você precisa usar a Biblioteca Joda para executar esse código.

import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class time {

    public static void main(String args[]){

        String str = "1431601084000";
        long geTime= Long.parseLong(str);
        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
        calendar.setTimeInMillis(geTime);
        DateTime jodaTime = new DateTime(geTime, 
               DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
        DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println("Get Time : "+parser1.print(jodaTime));

   }
}

1

Você pode tentar java.time api;

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
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.