Wie extrahiert man die Epoche aus LocalDate und LocalDateTime?

Lesezeit: 5 Minuten

Wie extrahiere ich den Epochenwert in Long aus Instanzen von LocalDateTime oder LocalDate? Ich habe folgendes versucht, aber es gibt mir andere Ergebnisse:

LocalDateTime time = LocalDateTime.parse("04.02.2014  19:51:01", DateTimeFormatter.ofPattern("dd.MM.yyyy  HH:mm:ss"));
System.out.println(time.getLong(ChronoField.SECOND_OF_DAY)); // gives 71461
System.out.println(time.getLong(ChronoField.EPOCH_DAY)); // gives 16105

Was ich will, ist einfach der Wert 1391539861 für die lokale Datumszeit "04.02.2014 19:51:01". Meine Zeitzone ist Europe/Oslo UTC+1 mit Sommerzeit.

  • Bitte erläutern Sie Ihre erwartete Nummer 1396468261. Ich bekomme ohne Zeitzonenkorrektur: 1391543461 (siehe Bearbeiten in meiner Antwort). 57 Tage Unterschied!

    – Meno Hochschild

    10. April 2014 um 14:38 Uhr

  • @MenoHochschild Ich habe meine Frage mit Zeitzoneninformationen aktualisiert und den tatsächlichen Wert von GTM auf Ortszeit korrigiert. Gibt es einen einfacheren Weg, die Epoche von einigen zu erhalten? LocalDateTime außer es manuell zu berechnen?

    Benutzer1019830

    10. April 2014 um 14:58 Uhr


  • Zurück aus meiner Pause, siehe mein Update.

    – Meno Hochschild

    10. April 2014 um 16:25 Uhr

Benutzer-Avatar
Nosid

Die Klassen LocalDate und LocalDateTime enthalten keine Informationen über die Zeitzone oder Zeitverschiebung, und Sekunden seit Epoche wären ohne diese Informationen mehrdeutig. Die Objekte verfügen jedoch über mehrere Methoden, um sie in Datums-/Uhrzeitobjekte mit Zeitzonen zu konvertieren, indem Sie a übergeben ZoneId Beispiel.

Lokales Datum

LocalDate date = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = date.atStartOfDay(zoneId).toEpochSecond();

LocalDateTime

LocalDateTime time = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = time.atZone(zoneId).toEpochSecond();

  • Ist es möglich, die Verwendung von ZoneId zu vermeiden oder mit einer benutzerdefinierten, konstanten ZoneId-Instanz (von +0 , was GMT bedeutet) zu verwenden? Ich frage das, weil ich möchte, dass alle Berechnungen darauf normalisiert werden. Wie mache ich auch das Gegenteil: Konvertiere von der Epochenzeit in LocalDate/LocalDateTime (auch ohne ZoneId oder mit GMT)?

    – Android-Entwickler

    11. Januar 2018 um 10:06 Uhr

  • Macht nichts. Fand es: ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0))

    – Android-Entwickler

    14. Januar 2018 um 12:41 Uhr


  • Ein einfacherer Ansatz ist nur long epoch = time.toEpochSecond(ZoneOffset.UTC) für UTC-Fälle, oder wo Sie die Zeitzone bereits kennen, oder long epoch = time.toEpochSecond(ZoneId.systemDefault()); wenn du diesen Weg gehen willst.

    – Markus

    19. März 2019 um 1:30 Uhr


  • Das mag lächerlich klingen, aber wie wäre es mit einer Rückkonvertierung von Epoche zu LocalDate, LocalTime & LocalDateTime

    – Samuel Owino

    10. Januar 2020 um 23:37 Uhr

  • Macht nichts, ich glaube, ich habe es gefunden; Instant.ofEpochMilli(responseTime).atZone(ZoneId.systemDefault()).toLocalTime()

    – Samuel Owino

    10. Januar 2020 um 23:40 Uhr

‘Millis Since Unix Epoch’ stellt einen Instant dar, daher sollten Sie die Instant-Klasse verwenden:

private long toEpochMilli(LocalDateTime localDateTime)
{
  return localDateTime.atZone(ZoneId.systemDefault())
    .toInstant().toEpochMilli();
}

  • es ist falsch zu verwenden ZoneId.systemDefault() weil Unix-Epoche sich auf UTC bezieht

    – ACV

    26. November 2019 um 12:13 Uhr

  • @ACV Bist du immer noch damit einverstanden, was du einmal gedacht hast? Hat der API-Designer nicht definiert ZonedDateTime#toInstant?

    – Jinkwon

    27. März um 7:20 Uhr


  • @JinKwon Ich bezog mich lediglich auf die Tatsache, dass ZoneId.systemDefault() gibt möglicherweise nicht unbedingt die Zeitzone zurück, die das OP erwartet hat: My timezone is Europe/Oslo. Also sollten sie verwenden ZoneId.of("Europe/Oslo") stattdessen wie in anderen Antworten vorgeschlagen. Wie für ZonedDateTime.toInstant() – sein Javadoc erklärt die Implementierung klar: This returns an Instant representing the same point on the time-line as this date-time. The calculation combines the local date-time and offset.

    – ACV

    28. März um 15:16 Uhr

  • ZoneId.systemDefault() scheint UTC zurückzugeben, also sollte systemDefault in Ordnung sein

    – Ernie Thomason

    4. Juni um 22:59 Uhr

Die benötigte Konvertierung erfordert den Offset von UTC/Greewich oder eine Zeitzone.

Wenn Sie einen Offset haben, gibt es a dedizierte Methode an LocalDateTime für diese Aufgabe:

long epochSec = localDateTime.toEpochSecond(zoneOffset);

Wenn Sie nur eine haben ZoneId dann bekommst du die ZoneOffset von dem ZoneId:

ZoneOffset zoneOffset = ZoneId.of("Europe/Oslo").getRules().getOffset(ldt);

Aber Sie können die Konvertierung über finden ZonedDateTime einfacher:

long epochSec = ldt.atZone(zoneId).toEpochSecond();

  • Wenn Sie sich nur für UTC interessieren, gibt es long epochSec = localDateTime.toEpochSecond(ZoneOffset.UTC);

    – ruhong

    5. Februar 2018 um 23:59 Uhr

Benutzer-Avatar
Meno Hochschild

Ansehen diese Methode um zu sehen, welche Felder unterstützt werden. Sie finden für LocalDateTime:

•NANO_OF_SECOND 
•NANO_OF_DAY 
•MICRO_OF_SECOND 
•MICRO_OF_DAY 
•MILLI_OF_SECOND 
•MILLI_OF_DAY 
•SECOND_OF_MINUTE 
•SECOND_OF_DAY 
•MINUTE_OF_HOUR 
•MINUTE_OF_DAY 
•HOUR_OF_AMPM 
•CLOCK_HOUR_OF_AMPM 
•HOUR_OF_DAY 
•CLOCK_HOUR_OF_DAY 
•AMPM_OF_DAY 
•DAY_OF_WEEK 
•ALIGNED_DAY_OF_WEEK_IN_MONTH 
•ALIGNED_DAY_OF_WEEK_IN_YEAR 
•DAY_OF_MONTH 
•DAY_OF_YEAR 
•EPOCH_DAY 
•ALIGNED_WEEK_OF_MONTH 
•ALIGNED_WEEK_OF_YEAR 
•MONTH_OF_YEAR 
•PROLEPTIC_MONTH 
•YEAR_OF_ERA 
•YEAR 
•ERA 

Das Feld INSTANT_SECONDS wird natürlich nicht unterstützt, weil a LocalDateTime kann sich nicht auf einen absoluten (globalen) Zeitstempel beziehen. Was aber hilfreich ist, ist das Feld EPOCH_DAY die die verstrichenen Tage seit dem 01.01.1970 zählt. Ähnliche Gedanken gelten für den Typus LocalDate (mit noch weniger unterstützten Feldern).

Wenn Sie beabsichtigen, das nicht vorhandene Feld millis-since-unix-epoch zu erhalten, benötigen Sie auch die Zeitzone für die Konvertierung von einem lokalen in einen globalen Typ. Diese Konvertierung kann viel einfacher durchgeführt werden, siehe andere SO-Beiträge.

Zurück zu Ihrer Frage und den Zahlen in Ihrem Code:

The result 1605 is correct
  => (2014 - 1970) * 365 + 11 (leap days) + 31 (in january 2014) + 3 (in february 2014)
The result 71461 is also correct => 19 * 3600 + 51 * 60 + 1

16105L * 86400 + 71461 = 1391543461 Sekunden seit 1970-01-01T00:00:00 (Achtung, keine Zeitzone) Dann können Sie den Zeitzonen-Offset abziehen (achten Sie auf eine mögliche Multiplikation mit 1000, wenn in Millisekunden).

UPDATE nach gegebener Zeitzoneninfo:

local time = 1391543461 secs
offset = 3600 secs (Europe/Oslo, winter time in february)
utc = 1391543461 - 3600 = 1391539861

Als JSR-310-Code mit zwei gleichwertigen Ansätzen:

long secondsSinceUnixEpoch1 =
  LocalDateTime.of(2014, 2, 4, 19, 51, 1).atZone(ZoneId.of("Europe/Oslo")).toEpochSecond();

long secondsSinceUnixEpoch2 =
  LocalDate
    .of(2014, 2, 4)
    .atTime(19, 51, 1)
    .atZone(ZoneId.of("Europe/Oslo"))
    .toEpochSecond();

Benutzer-Avatar
Aled Evans

Dies ist eine Möglichkeit, ohne Zeit eine Zone zu verwenden:

LocalDateTime now = LocalDateTime.now();
long epoch = (now.getLong(ChronoField.EPOCH_DAY) * 86400000) + now.getLong(ChronoField.MILLI_OF_DAY);

Benutzer-Avatar
Dmitrij Fialkowsky

Konvertieren von menschenlesbares Datum bis Epoche:

long epoch = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000;

Konvertieren von Epoche bis zum menschenlesbaren Datum:

String date = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").format(new java.util.Date (epoch*1000));

Für andere Sprachkonverter:
https://www.epochconverter.com

1335260cookie-checkWie extrahiert man die Epoche aus LocalDate und LocalDateTime?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy