Wie konvertiere ich currentTimeMillis in ein Datum in Java?


140

Ich habe Millisekunden in bestimmten Protokolldateien, die auf dem Server generiert wurden. Ich kenne auch das Gebietsschema, aus dem die Protokolldatei generiert wurde. Mein Problem besteht darin, Millisekunden in das angegebene Format zu konvertieren. Die Verarbeitung dieses Protokolls erfolgt auf einem Server in einer anderen Zeitzone. Während der Konvertierung in das Programm "SimpleDateFormat" wird das Datum des Computers verwendet, da das formatierte Datum nicht die korrekte Uhrzeit des Servers darstellt. Gibt es eine Möglichkeit, elegant damit umzugehen?

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

Ausgabe:

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

Verwechseln Sie das Gebietsschema nicht mit der Zeitzone. Völlig getrennt. Das Gebietsschema bestimmt die menschliche Sprache für den Namen von Monaten und Tagen sowie für kulturelle Normen wie die Reihenfolge von Teilen wie Monat, Tag usw. Eine Zeitzone ist von UTC versetzt und enthält Regeln für den Umgang mit Anomalien wie Sommerzeit.
Basil Bourque

War das Problem, dass die Anzahl der Millisekunden nicht von 1970-01-01T00: 00: 00Z, sondern von einem anderen Moment an gezählt wurde?
Basil Bourque

FYI, beide schrecklich alt Datum-Zeit - Klassen ( GregorianCalendar, SimpleDateFormatusw.) und die hervorragende Joda-Time Bibliothek werden jetzt von den modernen verdrängten java.time Klassen.
Basil Bourque

Antworten:


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

Ich musste den Kalender als endgültig festlegen, damit er funktioniert. final Calendar calendar = Calendar.getInstance();
Victor Augusto

4
Kalenderobjekte werden im Allgemeinen als ziemlich groß angesehen und sollten daher nach Möglichkeit vermieden werden. Ein Date-Objekt ist besser, vorausgesetzt, es verfügt über die von Ihnen benötigte Funktionalität. "Datum Datum = neues Datum (Millis);" in der anderen Antwort von Benutzer AVD zur Verfügung gestellt wird die beste Route sein :)
Dick Lucas

1
Irgendwie 1515436200000lwerde ich calendar.get(Calendar.MONTH))so 0!
Sajib Acharya

Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque

2
@SajibAcharya Beachten Sie, dass die Instanzen für Calendar.MONTH bei 0 beginnen. Sie müssen einen hinzufügen, um den "echten" Monat zu erhalten, wie wir ihn kennen. Beispiel: 0 = Januar, 1 = Februar, 2 = März usw.
Shagberg

256

Sie können verwenden java.util.Date class verwenden und dann verwenden, um die SimpleDateFormatzu formatieren Date.

Date date=new Date(millis);

Wir können das Paket java.time (Tutorial) verwenden - DateTime-APIs, die in Java SE 8 eingeführt wurden.

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
Viel effizienter.
Chad Bingham

2
Nee. Nicht alle Methoden von java.util.Datewerden abgeschrieben. (Es gibt verbesserte Datums- und Zeit-APIs in JDK8 java.time)
Adatapost

1
@ RafaelZeffa, der Konstruktor '' 'Date (long date)' '' ist nicht veraltet
Gugelhupf

Das Date-Objekt wird aus Gründen der Abwärtskompatibilität bereitgestellt. Verwenden Sie den Kalender besser wie oben vorgeschlagen.
Ton Snoei

2
Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von 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.

Einzelheiten

Die anderen Antworten verwenden veraltete oder falsche Klassen.

Vermeiden Sie die alten Datums- und Uhrzeitklassen wie java.util.Date/.Calendar. Sie haben sich als schlecht gestaltet, verwirrend und problematisch erwiesen.

java.time

Das java.time- Framework ist in Java 8 und höher integriert. Ein Großteil der Funktionen wird auf Java 6 & 7 zurückportiert und weiter an Android angepasst . Hergestellt von einigen der gleichen Leute wie Joda-Time .

An Instantist ein Moment auf der Zeitachse in UTC mit einer Auflösung von Nanosekunden . Seine Epoche ist der erste Moment des Jahres 1970 in UTC.

Angenommen, Ihre Eingabedaten sind eine Anzahl von Millisekunden von 1970-01-01T00: 00: 00Z (in der Frage nicht klar), dann können wir leicht eine instanziieren Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

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

Die Zin dieser Norm ISO 8601 formatierte Zeichenfolge steht für UTCZulu und bedeutet UTC .

Wenden Sie eine Zeitzone mit einem geeigneten Zeitzonennamen an , um eine zu erhalten ZonedDateTime.

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

Sehen Sie diesen Code live auf IdeOne.com .

Asia/Kolkata Zeitzone ?

Ich vermute, Sie haben eine Zeitzone in Indien, die sich auf Ihren Code auswirkt. Wir sehen hier, dass die Anpassung in die Asia/KolkataZeitzone dieselbe Tageszeit 08:55ergibt , die Sie melden, und die fünfeinhalb Stunden vor unserem UTC-Wert liegt 03:25.

2011-11-23T08: 55: 52.992 + 05: 30 [Asia / Kolkata]

Standardzone

Sie können die aktuelle Standardzeitzone der JVM anwenden . Beachten Sie, dass sich die Standardeinstellung jederzeit zur Laufzeit ändern kann . Jeder Code in einem Thread einer App innerhalb der JVM kann den aktuellen Standard ändern. Wenn wichtig, fragen Sie den Benutzer nach der gewünschten / erwarteten Zeitzone.

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

Über java.time

Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Mit einem JDBC - Treiber mit Einhaltung JDBC 4.2 oder später, können Sie tauschen java.time Objekte direkt mit Ihrer Datenbank. Keine Notwendigkeit für Strings oder java.sql. * Klassen.

Woher bekomme ich die java.time-Klassen?

Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden Interval, YearWeek, YearQuarter, und mehr .


Wäre es einfach, den oben empfohlenen Instant in die lokale Zeitzone zu konvertieren, die auf einem Gerät (z. B. einem Smartphone) die Standardeinstellung ist?
AJW

1
@AJW Ja. Rufen Sie an ZoneId.systemDefault(). Siehe neuen Abschnitt am Ende meiner Antwort.
Basil Bourque

Ausgezeichnet, ich werde es versuchen.
AJW

14

Der einfachste Weg, dies zu tun, ist die Verwendung der Joda DateTime-Klasse und sowohl den Zeitstempel in Millisekunden als auch die gewünschte anzugeben.

Ich empfehle dringend, die integrierten Java-Klassen für Datum und Kalender zu vermeiden. Sie sind schrecklich.


GorgianCalender hat nicht funktioniert ... aus irgendeinem Grund wurde die Standardzeitzone des Systems verwendet. Joda hat perfekt funktioniert.
Amit

Lassen Sie mich wissen, wie wir mit Gregorian
Amit

1
Zu Ihrer Information , das Joda-Time- Projekt befindet sich jetzt im Wartungsmodus und empfiehlt die Migration zu den Klassen java.time . Siehe Tutorial von Oracle .
Basil Bourque

13

Wenn der Millis-Wert die Anzahl der Millis seit dem 1. Januar 1970 GMT ist, wie es für die JVM Standard ist, dann ist dies unabhängig von der Zeitzone. Wenn Sie es mit einer bestimmten Zeitzone formatieren möchten, können Sie es einfach in ein GregorianCalendar-Objekt konvertieren und die Zeitzone festlegen. Danach gibt es zahlreiche Möglichkeiten, es zu formatieren.


1
Dies ist der Beispielcode für GregorianCalendar und Joda. Ich erhalte eine korrekte Ausgabe mit Joda, jedoch nicht mit Gregorian GregorianCalendar calendar = new GregorianCalendar (TimeZone.getTimeZone ("US / Central")); calendar.setTimeInMillis (Ihre Millisekunden); DateTime jodaTime = new DateTime (Ihre Millisekunden, DateTimeZone.forTimeZone (TimeZone.getTimeZone ("US / Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern ("JJJJ-MM-TT HH: MM: SS, SSS");
Amit

Das Festlegen der Zeitzone im Kalenderobjekt hat nicht funktioniert, das Festlegen im Datumsformatiererobjekt jedoch?
Bill

Was ist DateTime und DateTimeFormatter?
SweetWisher

11

Meine Lösung

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

So mach ich es:

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

Sie können auch getDateInstance(int style)folgende Parameter verwenden:

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT



5

Einfachster Weg:

private String millisToDate(long millis){

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

}

2

Unten ist meine Lösung, um das Datum von Millisekunden bis zum Datumsformat zu erhalten. Sie müssen Joda Library verwenden , um diesen Code auszuführen.

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

Sie können java.time api versuchen;

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.