Java 8 LocalDateTime 和 ZonedDateTime 的转换
Java 8 LocalDateTime and ZonedDateTime conversion
给定区域名称和 outputDtf
,这是使用 Java 8 LocalDateTime 和 ZonedDateTime 的最佳方式吗?我想尽可能简化。
String zoneName = "America/Los_Angeles";
DateTimeFormatter outputDtf = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")
.withZone(ZoneId.of(zoneName));
// timestamp in UTC. convert to zone America/Los_Angeles
DateTimeFormatter timestampDtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
String timestamp = "20180722060602";
LocalDateTime ldt = LocalDateTime.parse(timestamp, timestampDtf);
Instant tsInstant = ldt.atZone(ZoneId.of("UTC")).toInstant();
System.out.println(outputDtf.format(tsInstant));
// 2018-07-21T23:06:02-0700
// date in zone America/Los_Angeles. add start of day and zone
DateTimeFormatter dateDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String date = "2018-07-18";
ZonedDateTime zdt = LocalDate.parse(date, dateDtf).atStartOfDay().atZone(ZoneId.of(zoneName));
System.out.println(outputDtf.format(zdt));
// 2018-07-18T00:00:00-0700
除了去掉第一个例子中的toInstant()
,没有什么可以简化的了。
您必须解析输入的字符串,必须指定时区,对于仅限日期的日期,您必须说是午夜。
这些是您正在执行的步骤,无法简化,但您可以让 DateTimeFormatter
完成工作。
String zoneName = "America/Los_Angeles";
DateTimeFormatter outputDtf = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")
.withZone(ZoneId.of(zoneName));
// timestamp in UTC. convert to zone America/Los_Angeles
DateTimeFormatter timestampDtf = DateTimeFormatter
.ofPattern("yyyyMMddHHmmss")
.withZone(ZoneOffset.UTC);
String timestamp = "20180722060602";
ZonedDateTime zdt1 = ZonedDateTime.parse(timestamp, timestampDtf);
System.out.println(outputDtf.format(zdt1)); // 2018-07-21T23:06:02-0700
// date in zone America/Los_Angeles. add start of day and zone
DateTimeFormatter dateDtf = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.toFormatter()
.withZone(ZoneId.of(zoneName));
String date = "2018-07-18";
ZonedDateTime zdt2 = ZonedDateTime.parse(date, dateDtf);
System.out.println(outputDtf.format(zdt2)); // 2018-07-18T00:00:00-0700
可以看到,如果把DateTimeFormatter
设置一次再使用,代码using就更简单了,但是总体来说代码并不简单.
您的代码总体上还不错,您可以做得更好。
在第一个片段中我会使用 OffsetDateTime
而不是 Instant
:
OffsetDateTime tsOffsetDateTime = ldt.atOffset(ZoneOffset.UTC);
System.out.println(outputDtf.format(tsOffsetDateTime));
您不需要第二个代码段中的格式化程序,因为您的字符串 2018-07-18
是 LocalDate
(又名 ISO 8601)的默认格式:
ZonedDateTime zdt = LocalDate.parse(date).atStartOfDay().atZone(zone);
给定区域名称和 outputDtf
,这是使用 Java 8 LocalDateTime 和 ZonedDateTime 的最佳方式吗?我想尽可能简化。
String zoneName = "America/Los_Angeles";
DateTimeFormatter outputDtf = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")
.withZone(ZoneId.of(zoneName));
// timestamp in UTC. convert to zone America/Los_Angeles
DateTimeFormatter timestampDtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
String timestamp = "20180722060602";
LocalDateTime ldt = LocalDateTime.parse(timestamp, timestampDtf);
Instant tsInstant = ldt.atZone(ZoneId.of("UTC")).toInstant();
System.out.println(outputDtf.format(tsInstant));
// 2018-07-21T23:06:02-0700
// date in zone America/Los_Angeles. add start of day and zone
DateTimeFormatter dateDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String date = "2018-07-18";
ZonedDateTime zdt = LocalDate.parse(date, dateDtf).atStartOfDay().atZone(ZoneId.of(zoneName));
System.out.println(outputDtf.format(zdt));
// 2018-07-18T00:00:00-0700
除了去掉第一个例子中的toInstant()
,没有什么可以简化的了。
您必须解析输入的字符串,必须指定时区,对于仅限日期的日期,您必须说是午夜。
这些是您正在执行的步骤,无法简化,但您可以让 DateTimeFormatter
完成工作。
String zoneName = "America/Los_Angeles";
DateTimeFormatter outputDtf = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")
.withZone(ZoneId.of(zoneName));
// timestamp in UTC. convert to zone America/Los_Angeles
DateTimeFormatter timestampDtf = DateTimeFormatter
.ofPattern("yyyyMMddHHmmss")
.withZone(ZoneOffset.UTC);
String timestamp = "20180722060602";
ZonedDateTime zdt1 = ZonedDateTime.parse(timestamp, timestampDtf);
System.out.println(outputDtf.format(zdt1)); // 2018-07-21T23:06:02-0700
// date in zone America/Los_Angeles. add start of day and zone
DateTimeFormatter dateDtf = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.toFormatter()
.withZone(ZoneId.of(zoneName));
String date = "2018-07-18";
ZonedDateTime zdt2 = ZonedDateTime.parse(date, dateDtf);
System.out.println(outputDtf.format(zdt2)); // 2018-07-18T00:00:00-0700
可以看到,如果把DateTimeFormatter
设置一次再使用,代码using就更简单了,但是总体来说代码并不简单.
您的代码总体上还不错,您可以做得更好。
在第一个片段中我会使用 OffsetDateTime
而不是 Instant
:
OffsetDateTime tsOffsetDateTime = ldt.atOffset(ZoneOffset.UTC);
System.out.println(outputDtf.format(tsOffsetDateTime));
您不需要第二个代码段中的格式化程序,因为您的字符串 2018-07-18
是 LocalDate
(又名 ISO 8601)的默认格式:
ZonedDateTime zdt = LocalDate.parse(date).atStartOfDay().atZone(zone);