Java8 beherrscht die Kernideen der Datums- und Java.time-Konvertierung und löst problemlos verschiedene Zeitkonvertierungsprobleme



Detaillierte Erläuterung der Verwendung der Java8-Zeitzonenzeit, 20.000 Wörter, um Ihnen beim Bestehen des java.time-Pakets zu helfen




Setzen Sie die Kernidee um

Es gibt nur einen Prozess für den Konvertierungskern verschiedener Zeitklassen: Zeitklasse -> Zeitstempel -> Zeitklasse

  • Datums- und Instant-Store-Zeitstempelinformationen
  • LocalDateTime, LocalDate, LocalTime, ZonedDateTime, OffsetDateTime, OffsetTime, Year und andere Java8-Zeitklassen sind eine 年、月、日、时、分、秒、纳秒Kombination aus Teilwerten in + Zeitzone oder Offset

Aus Sicht der Konvertierung kann Date direkt in Instant konvertiert werden oder basierend auf Zeitstempeln direkt in andere Zeitklassen konvertiert werden; andere Zeitklassen in Java8 können ineinander konvertiert oder in Zeitstempel konvertiert und dann in Date oder Instant konvertiert werden.

Dieser Artikel hat also 5 Ideen für die Zeitumrechnung:

  1. Datum bis Instant
  2. Sofort auf dem Laufenden
  3. Datum zu Java8 anderen Zeitklassen
  4. Java8 andere Zeitklassen bis heute
  5. Austausch zwischen Zeitklassen in Java8




Zeitumstellung

1. Datum —》 Sofort

Date long fastTimespeichert intern den gesamten Zeitstempel System.currentTimeMillis(), während Instant Sekunden long secondsund Nanosekunden verwendet int nanos, um den gesamten Zeitstempel zu speichern. Sie können also direkt ineinander umgerechnet werden. Eine Sache, die hier zu beachten ist, ist, dass der Zeitstempel die Zeit in UTC + 0 oder GMT + 0 aufzeichnet. Wenn er direkt ausgegeben wird Date.toString(), konvertiert er tatsächlich automatisch die GMT + 0-Zeit in die Standardzeitzonenzeit des Systems.

Date date = new Date();
// 1. Date兼容了Instant,可以直接转
Instant instant = date.toInstant(); 
// 2. 或通过时间戳初始化
Instant.ofEpochMilli(date.getTime());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// SimpleDateFormat中使用当前系统的默认时区输出时间,所以需要把时区转为UTC时区才能保证两者区时一致
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(simpleDateFormat.format(date));
System.out.println(instant);

Ausgabezeit:

2023-04-25 05:52:43
2023-04-25T05:52:43.246Z



2. Sofort —》 Datum

Instant und Date ähneln sich darin, dass sie Instanzen durch Zeitstempel erstellen:

Instant instant = Instant.now();
// 1. 构造方法转换
Date date = Date.from(instant);
// 2. 通过时间戳初始化
new Date(instant.toEpochMilli());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(simpleDateFormat.format(date));
System.out.println(instant);

Ausgabezeit:

2023-04-25 06:05:00
2023-04-25T06:05:00.882Z



3. Datum -> Java8-Zeitklasse

A. Konvertieren der Zeitklasse durch Konvertieren in Instant
Die folgende Zeitzone ZoneIdund der Zeitversatz ZoneOffsetkönnen in die Standardzeitzone des Systems geändert werden, um dieselbe Ortszeit ZoneId.systemDefault()anzuzeigen .new Date().toString()

Date date = new Date();
Instant instant = date.toInstant();
// 1. 通过添加时区、偏移量信息直接转换
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("UTC"));
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC);

// 2. 通过构造方法
ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

B. Zeitklasse durch Zeitstempel konvertieren
Als die eingangs erwähnte Kernidee der Konvertierung können wir den Zeitstempel von Date bereitstellen (dasselbe gilt für Instant) und dann den Zeitstempel in andere Zeitklassen konvertieren:

long timestamp = date.getTime();
// 这里的计算就是Date转Instant,Instant转LocalDateTime的源代码实现方式
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(Math.floorDiv(timestamp, 1000), 
	(int) Math.floorMod(timestamp, 1000), ZoneOffset.UTC);
// 然后通过LocalDateTime转其它类
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
ZonedDateTime zonedDateTime1 = localDateTime.atZone(ZoneId.of("UTC"));
OffsetDateTime offsetDateTime1 = localDateTime.atOffset(ZoneOffset.UTC);

C. Konvertieren durch Zeichenkettenformatierung
Diese Methode ist knifflig, aber sehr nützlich.Der zu beachtende Punkt ist: LocalDateTime, ZonedDateTime und OffsetDateTime müssen Offset-Informationen (oder Zeitzoneninformationen) bereitstellen.

String pattern = "yyyy-MM-dd HH:mm:ss X";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String format = simpleDateFormat.format(date);
LocalDateTime.parse(format, dateTimeFormatter);
OffsetDateTime.parse(format, dateTimeFormatter);
ZonedDateTime.parse(format, dateTimeFormatter);

Passende Bedeutungen (Teile) von Buchstaben in DateTimeFormatter für Zeitformatierung:

  • V : Zeitzonen-ID, America/Los_Angeles; Z; -08:30
  • z : Name oder Abkürzung der Zeitzone, Pacific Standard Time; PST
  • Z : Zeitversatz, keine Zeitzone angegeben, stellt nur den Versatzbereich dar, +0000, -0800, -08:00;
  • x : Zeitversatz, keine Zeitzone angegeben, stellt nur den Versatzbereich dar, +0000; -08; -0830; -08:30; -083015; -08:30:15;
  • X : Zeitverschiebung der Weltzeit (UTC-GMT-UT, abhängig davon, welche Weltzeit die Zeitklasse unterstützt), Z; -08; -0830; -08:30; -083015; -08:30:15;
  • O : Zeitversatz mit Zeitzone, GMT+8, GMT+08:00, UTC-08:00;

Passende Bedeutungen (Teile) von Buchstaben in SimpleDateFormat zur Zeitformatierung:

  • V : Keine
  • z : Zeitzonenname oder Abkürzung oder Zeitzonenoffset, Pacific Standard Time; PST; GMT-08:00
  • Z : Zeitversatz, keine Zeitzone angegeben, stellt nur den Versatzbereich dar, +0000, -0800, -08:00;
  • x : keine
  • X : Zeitversatz, keine Zeitzone angegeben, stellt nur den Versatzbereich dar, -08; -0800; -08:00
  • O : Keine

Beim Vergleich der drei oben genannten Methoden können wir sehen, dass es bequemer ist, Date in andere Zeitklassen zu übertragen, indem Sie zuerst zu Instant -> und dann zu anderen Zeitklassen übertragen.



4. Java8-Zeitklasse – „Datum

Verwenden Sie Date, um in der umgekehrten Richtung von Java8 andere Zeitklassen zu konvertieren.

Initialisierungszeit:

LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();

A. Konvertieren Sie das Datum, indem Sie es in Instant umwandeln

Wechseln Sie zu Instant und dann zu Date

Instant instant = localDateTime.toInstant(ZoneOffset.ofHours(8));
offsetDateTime.toInstant();
zonedDateTime.toInstant();
Date date = Date.from(instant);
// 输出
System.out.println(localDateTime);
System.out.println(offsetDateTime);
System.out.println(zonedDateTime);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));

Ausgabezeit:

2023-04-25T15:18:53.585
2023-04-25T15:18:53.586+08:00
2023-04-25T15:18:53.586+08:00[Asia/Shanghai]
2023-04-25 15:18:53

B. Durch Konvertieren von timestamp in Date
localDateTime und andere Zeitklassen können Sie den Zeitstempel der zweiten Ebene der Zeit erhalten, sodass Sie ihn basierend auf diesem Zeitstempel direkt in Date konvertieren können. Diese Konvertierung verliert die Genauigkeit von Nano-Millisekunden. Wenn die Genauigkeit erforderlich ist, muss dies toEpochMilli()durch Konvertierung in Instant und anschließendem Aufruf der Methode realisiert werden.

long epochSecond = localDateTime.toEpochSecond(ZoneOffset.ofHours(8));
offsetDateTime.toEpochSecond();
zonedDateTime.toEpochSecond();
Date date1 = new Date(epochSecond * 1000L);

C. Konvertierung durch Stringformatierung
Da die Zeitklasse in Java8 unterschiedliche Attribute hat (Zeitzone, Offset usw.), unterscheiden sich die Formatstrings von LocalDateTime, OffsetDateTime und ZonedDateTime bei der Formatierung durch Zeitstrings. Dieser Punkt unterscheidet sich von Date zu diesen Zeitklassen und muss bei der eigentlichen Konvertierung beachtet werden.

String local = "yyyy-MM-dd HH:mm:ss";
String offset = "yyyy-MM-dd HH:mm:ss X";
String zone = "yyyy-MM-dd HH:mm:ss z";
System.out.println(new SimpleDateFormat(local).parse(DateTimeFormatter.ofPattern(local).format(localDateTime)));
System.out.println(new SimpleDateFormat(offset).parse(DateTimeFormatter.ofPattern(offset).format(offsetDateTime)));
System.out.println(new SimpleDateFormat(zone).parse(DateTimeFormatter.ofPattern(zone).format(zonedDateTime)));

Die Ausgabezeiten sind wie folgt:

Tue Apr 25 16:18:37 CST 2023
Tue Apr 25 16:18:37 CST 2023
Tue Apr 25 16:18:37 CST 2023



5. Konvertierung der Java8-Zeitklasse

Die folgenden Transformationen stellen alle Transformationen bereit, die von jeder Zeitklasse unterstützt werden, einschließlich Konstruktionsmethoden und Instanzobjektmethoden.

A. Sofort

Instant instant = Instant.now();
// 通过实例对象转换
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("UTC"));
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC);
// 通过构造方法转换
ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
LocalDateTime.ofInstant(instant, ZoneOffset.UTC);


B. Wenn LocalDateTimetoXX OffsetDateTime und ZonedDateTime konvertiert, gibt es keine Methode, und from(TemporalAccessor temporal)der Konstruktor kann nicht zum Instanziieren verwendet werden, da LocalDateTime keine Zeitzonen- und Offset-Informationen hat.

LocalDateTime localDateTime = LocalDateTime.now();
ZoneOffset zoneOffset = ZoneOffset.ofHours(8);
// 通过实例对象转换
Instant instant = localDateTime.toInstant(zoneOffset);
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneOffset);
OffsetDateTime offsetDateTime = localDateTime.atOffset(zoneOffset);
// 通过构造方法转换
Instant.ofEpochSecond(localDateTime.toEpochSecond(zoneOffset));
LocalDate.from(localDateTime);
LocalTime.from(localDateTime);
OffsetDateTime.of(localDateTime, zoneOffset);
ZonedDateTime.of(localDateTime, zoneOffset);

C. OffsetDateTime
Die Konvertierung von OffsetDateTime und ZonedDateTime ist dieselbe, verwenden Sie toXXXeine direkte Konvertierung in andere Zeitklassen und verwenden Sie andere Zeitklassenmethoden, fromum ihre Zeitinformationen zu kopieren.

OffsetDateTime offsetDateTime = OffsetDateTime.now();
// 通过实例对象转换
Instant instant = offsetDateTime.toInstant();
OffsetTime offsetTime = offsetDateTime.toOffsetTime();
LocalDate localDate = offsetDateTime.toLocalDate();
LocalTime localTime = offsetDateTime.toLocalTime();
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
ZonedDateTime zonedDateTime = offsetDateTime.toZonedDateTime();
// 通过构造方法转换
Instant.from(offsetDateTime);
OffsetTime.from(offsetDateTime);
LocalDate.from(offsetDateTime);
LocalTime.from(offsetDateTime);
LocalDateTime.from(offsetDateTime);
ZonedDateTime.from(offsetDateTime);

D. ZonedDateTime

ZonedDateTime zonedDateTime = ZonedDateTime.now();
// 通过实例对象转换
Instant instant = zonedDateTime.toInstant();
LocalDate localDate = zonedDateTime.toLocalDate();
LocalTime localTime = zonedDateTime.toLocalTime();
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();
// 通过构造方法转换
Instant.from(zonedDateTime);
OffsetTime.from(zonedDateTime);
OffsetDateTime.from(zonedDateTime);
LocalDate.from(zonedDateTime);
LocalTime.from(zonedDateTime);
LocalDateTime.from(zonedDateTime);

おすすめ

転載: blog.csdn.net/HO1_K/article/details/130361520
おすすめ