Come convertire currentTimeMillis in una data in Java?


140

Ho alcuni millisecondi in alcuni file di registro generati nel server, conosco anche le impostazioni internazionali da cui è stato generato il file di registro, il mio problema è convertire i millisecondi fino ad oggi nel formato specificato. L'elaborazione di quel registro avviene su server situati in diversi fusi orari. Durante la conversione al programma "SimpleDateFormat" la data del computer sta prendendo la data poiché tale data formattata non rappresenta l'ora corretta del server. C'è un modo per gestirlo elegantemente?

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

Produzione:

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

Non confondere Locale con fuso orario. Totalmente separato. Le impostazioni locali determinano il linguaggio umano per nome di mesi e giorni e norme culturali come l'ordine delle parti come mese, giorno, ecc. Un fuso orario è offset rispetto a UTC più regole per la gestione di anomalie come l'ora legale.
Basil Bourque,

Il problema era che il numero di millisecondi era un conteggio non dal 1970-01-01 alle 00:00: 00: 00Z ma da qualche altro momento?
Basil Bourque,

Cordiali saluti, sia le terribili vecchie lezioni di data e ora ( GregorianCalendar, SimpleDateFormatecc.) Che l'eccellente biblioteca di Joda-Time sono ora soppiantate dalle moderne classi di java.time .
Basil Bourque,

Risposte:


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

Ho dovuto impostare Calendar come finale per farlo funzionare. final Calendar calendar = Calendar.getInstance();
Victor Augusto,

4
Gli oggetti del calendario sono generalmente considerati abbastanza grandi, quindi dovrebbero essere evitati quando possibile. Un oggetto Date sarà migliore supponendo che abbia le funzionalità di cui hai bisogno. "Data data = nuova data (millis);" fornita nell'altra risposta dall'utente AVD sarà la strada migliore :)
Dick Lucas,

1
In qualche modo, per 1515436200000l, sto diventando calendar.get(Calendar.MONTH))come 0!
Sajib Acharya,

Cordiali saluti, le vecchie classi data-ora terribilmente fastidiose come java.util.Date, java.util.Calendare java.text.SimpleDateFormatora sono legacy , soppiantate dalle classi java.time integrate in Java 8 e versioni successive. Vedi Tutorial di Oracle .
Basil Bourque,

2
@SajibAcharya Nota che le istanze per Calendar.MONTH iniziano da 0; devi aggiungerne uno per ottenere il mese "reale" come lo conosciamo. Esempio: 0 = gennaio, 1 = febbraio, 2 = marzo, ecc.
Shagberg,

256

È possibile utilizzare la java.util.Dateclasse e quindi utilizzare SimpleDateFormatper formattare il file Date.

Date date=new Date(millis);

Possiamo usare il pacchetto java.time (tutorial) - API DateTime introdotte in 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
Molto più efficiente.
Chad Bingham,

2
No. Non tutti i metodi di java.util.Datesono ammortizzati. (Sono state migliorate le API di data e ora in JDK8 java.time)
adatapost,

1
@RafaelZeffa, il costruttore '' 'Date (long date)' '' non è deprecato
Gugelhupf

L'oggetto Date viene fornito per compatibilità con le versioni precedenti. Meglio usare Calendar come suggerito sopra.
Ton Snoei,

2
Cordiali saluti, le vecchie classi data-ora terribilmente fastidiose come java.util.Date, java.util.Calendare java.text.SimpleDateFormatora sono legacy , soppiantate dalle classi java.time integrate in Java 8 e versioni successive. Vedi Tutorial di 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.

Dettagli

Le altre risposte utilizzano classi obsolete o errate.

Evita le vecchie classi di data e ora come java.util.Date/.Calendar. Hanno dimostrato di essere mal progettati, confusi e problematici.

java.time

Il framework java.time è integrato in Java 8 e versioni successive. Gran parte delle funzionalità sono backportate su Java 6 e 7 e ulteriormente adattate ad Android . Realizzato da alcune delle stesse persone che avevano creato Joda-Time .

An Instantè un momento sulla linea temporale in UTC con una risoluzione di nanosecondi . La sua epoca è il primo momento del 1970 in UTC.

Supponendo che i tuoi dati di input siano conteggiati in millisecondi dal 1970-01-01T00: 00: 00Z (non chiaro nella Domanda), allora possiamo facilmente istanziare un Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

instant.toString (): 2011-11-23T03: 25: 52.992Z

Il Zin questo standard ISO 8601 stringa formattata è l'abbreviazione di Zulue mezzi UTC .

Applicare un fuso orario usando un nome di fuso orario appropriato , per ottenere un ZonedDateTime.

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

Vedi questo codice eseguito dal vivo su IdeOne.com .

Asia/Kolkata fuso orario ?

Immagino che il tuo codice abbia un fuso orario in India. Vediamo qui che l'adattamento al Asia/Kolkatafuso orario rende la stessa ora del giorno indicata per il rapporto, 08:55che è di cinque ore e mezza in anticipo rispetto al nostro valore UTC 03:25.

2011-11-23T08: 55: 52,992 + 05: 30 [Asia / Kolkata]

Zona predefinita

È possibile applicare il fuso orario predefinito corrente della JVM. Attenzione che l'impostazione predefinita può cambiare in qualsiasi momento durante il runtime . Qualsiasi codice in qualsiasi thread di qualsiasi app all'interno della JVM può modificare l'impostazione predefinita corrente. Se importante, chiedi all'utente il fuso orario desiderato / previsto.

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

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.

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

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

Con un driver JDBC conforme a JDBC 4.2 o versione successiva, è possibile scambiare oggetti java.time direttamente con il database. Non sono necessarie stringhe o classi java.sql. *.

Dove ottenere le classi java.time?

  • Java SE 8 , Java SE 9 e versioni successive
    • Built-in.
    • Parte dell'API Java standard con un'implementazione in bundle.
    • Java 9 aggiunge alcune funzionalità e correzioni minori.
  • Java SE 6 e Java SE 7
    • Gran parte della funzionalità java.time è trasferita su Java 6 e 7 in ThreeTen-Backport .
  • androide
    • Versioni successive di implementazioni di bundle Android delle classi java.time.
    • Per precedenza Android, il ThreeTenABP progetto si adatta ThreeTen-Backport (di cui sopra). Vedi Come usare ThreeTenABP… .

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 .


Sarebbe facile convertire l'istante consigliato in precedenza nel fuso orario locale predefinito su un dispositivo (ad esempio uno smartphone)?
AJW,

1
@AJW Sì. Chiama ZoneId.systemDefault(). Vedi la nuova sezione aggiunta alla fine della mia risposta.
Basil Bourque,

Eccellente, ci proverò.
AJW,

14

Il modo più semplice per farlo è usare la classe DateTime di Joda e specificare sia il timestamp in millisecondi sia la DateTimeZone desiderata.

Consiglio vivamente di evitare le classi Java Date e Calendar integrate; sono terribili.


GorgianCalender non ha funzionato ... per qualsiasi motivo abbia impiegato il fuso orario predefinito del sistema. Joda ha funzionato perfettamente.
Entro il

Fammi sapere guardando il codice di esempio se possiamo fare qualcosa di diverso con Gregorian
Amit

1
Cordiali saluti, il progetto Joda-Time è ora in modalità manutenzione , che consiglia la migrazione alle classi java.time . Vedi Tutorial di Oracle .
Basil Bourque,

13

Se il valore in millis è il numero di millis dal 1 gennaio 1970 GMT, come standard per la JVM, allora è indipendente dal fuso orario. Se vuoi formattarlo con un fuso orario specifico, puoi semplicemente convertirlo in un oggetto GregorianCalendar e impostare il fuso orario. Successivamente ci sono numerosi modi per formattarlo.


1
Questo è il codice di esempio con GregorianCalendar e Joda, sto ottenendo un output corretto con Joda ma non con il calendario GregorianCalendar Gregorian = 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-gg HH: mm: ss, SSS");
Entro il

L'impostazione del fuso orario nell'oggetto calendario non ha funzionato, ma l'impostazione nell'oggetto formatter data ha funzionato?
Bill

Che cos'è DateTime e DateTimeFormatter ??
SweetWisher ツ

11

La mia soluzione

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

Lo faccio così:

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

È inoltre possibile utilizzare getDateInstance(int style)con i seguenti parametri:

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT



5

Il modo più semplice:

private String millisToDate(long millis){

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

}

2

Di seguito è la mia soluzione per ottenere la data da millisecondi al formato della data. Devi usare Joda Library per far funzionare questo codice.

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

Puoi provare java.time api;

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