Comment extraire epoch de LocalDate et LocalDateTime?

comment extraire la valeur d'époque de Long des instances de LocalDateTime ou LocalDate ? J'ai essayé ce qui suit, mais il 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 est simplement la valeur 1391539861 pour le datetime local "04.02.2014 19:51:01" . Mon fuseau horaire est Europe/Oslo UTC+1 avec l'heure d'été.

54
demandé sur JodaStephen 2014-04-10 17:52:48

5 réponses

les classes LocalDate et LocalDateTime ne contiennent pas d'information sur le timezone ou time offset , et les secondes car l'époque serait ambiguë sans cette information. Cependant, les objets ont plusieurs méthodes pour les convertir en objets date/time avec des fuseaux horaires en passant par 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();
78
répondu nosid 2018-09-30 19:22:56

'Millis depuis l'époque unix' représente un instantané, vous devez utiliser à l'Instant de la classe:

private long toEpochMilli(LocalDateTime localDateTime)
{
  return localDateTime.atZone(ZoneId.systemDefault())
    .toInstant().toEpochMilli();
}
13
répondu Werner Harnisch 2016-11-21 11:20:19

la conversion dont vous avez besoin nécessite le décalage de UTC/Greewich, ou un fuseau horaire.

si vous avez un offset, il y a une méthode dédiée sur LocalDateTime pour cette tâche:

long epochSec = localDateTime.toEpochSecond(zoneOffset);

si vous avez seulement un ZoneId alors vous pouvez obtenir le ZoneOffset du 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
répondu JodaStephen 2014-04-11 14:38:39

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_SECONDES n'est évidemment pas supporté car un LocalDateTime ne peut pas se référer à une date absolue (globale). Mais ce qui est utile est le champ EPOCH_DAY qui compte les jours écoulés depuis 1970-01-01. Des réflexions similaires sont valables pour le type LocalDate (avec encore moins de support Fields.)

si vous avez l'intention d'obtenir le champ millis-since-unix-epoch non existant, vous avez aussi besoin du fuseau horaire pour passer d'un type local à un type global. Cette conversion peut être fait beaucoup plus simple, voir d'autres SO-posts .

pour revenir à votre question et aux numéros 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 1970-01-01T00: 00:00 (attention, pas de fuseau horaire) Ensuite, vous pouvez soustraire le décalage du fuseau horaire (attention à une possible multiplication par 1000 si en millisecondes).

mise à JOUR après avoir donné le fuseau horaire info:

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

Comme JSR-310-code à 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();
0
répondu Meno Hochschild 2017-05-23 10:31:14

Convertir lisible par l'homme date de l'époque :

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

Convertir d'une époque à l'lisible par l'homme date :

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

pour autre convertisseur de langues: https://www.epochconverter.com

0
répondu michmich 2018-04-13 04:46:41