web-dev-qa-db-fra.com

Comment extraire Epoch de LocalDate et LocalDateTime?

Comment extraire la valeur Epoch dans Long à partir d'instances de LocalDateTime ou LocalDate? J'ai essayé Ce qui suit, mais cela me donne d'autres résultats:

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

Ce que je veux, c'est simplement la valeur 1391539861 pour le dateetime local "04.02.2014 19:51:01". Mon fuseau horaire est Europe/Oslo UTC + 1 avec l'heure d'été.

63
user1019830

Les classes LocalDate et LocalDateTime ne contiennent pas d'informations sur le timezone ni sur time offset, et secondes car Epoch serait ambigu sans cette information. Cependant, les objets disposent de plusieurs méthodes pour les convertir en objets date/heure avec des fuseaux horaires en transmettant une instance ZoneId.

LocalDate

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();
92
nosid

'Millis Since Unix Epoch' représente un instant, vous devriez donc utiliser la classe Instant:

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

La conversion dont vous avez besoin nécessite le décalage par rapport à UTC/Greewich ou à un fuseau horaire.

Si vous avez un décalage, il existe une méthode dédiée on LocalDateTime pour cette tâche:

long epochSec = localDateTime.toEpochSecond(zoneOffset);

Si vous avez seulement une ZoneId, vous pouvez obtenir la ZoneOffset à partir de la ZoneId:

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

Mais vous pouvez trouver la conversion via ZonedDateTime plus simple:

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

Regardez cette méthode pour voir quels champs sont supportés. Vous trouverez pour 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 

Le champ INSTANT_SECONDS n'est évidemment pas pris en charge car une variable LocalDateTime ne peut faire référence à aucun horodatage absolu (global). Mais ce qui est utile, c’est le champ Epoch_DAY qui compte les jours écoulés depuis le 1970-01-01. Des pensées similaires sont valables pour le type LocalDate (avec encore moins de champs supportés).

Si vous souhaitez obtenir le champ millis-since-unix-Epoch non existant, vous avez également besoin du fuseau horaire pour la conversion d'un type local en un type global. Cette conversion peut être faite beaucoup plus simplement, voir autre SO-posts .

Revenons à votre question et aux chiffres de votre 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 secondes depuis le 1970-01-01T00: 00: 00 (attention, pas de fuseau horaire) Vous pouvez ensuite soustraire le décalage du fuseau horaire (surveillez une multiplication possible de 1 000 si elle est en millisecondes).

UPDATE après avoir indiqué le fuseau horaire:

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

En tant que code JSR-310 avec deux approches équivalentes:

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();
1
Meno Hochschild

Convertir de date lisible en humain en Epoch:

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

Conversion de époque en date lisible par l'homme:

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

Pour un autre convertisseur de langue: https://www.epochconverter.com

0
michmich