如何将ZonedDateTime格式化为字符串?

64

我想将一个ZonedDateTime转换成格式为("dd/MM/yyyy - hh:mm")String。我知道在Joda-Time的其他类型中,只需使用它们的toString("dd/MM/yyyy - hh:mm")即可实现这一点...但是这对于ZonedDateTime.toString()不起作用。

如何将ZonedDateTime格式化为String


编辑:

我尝试在另一个时区打印时间,结果似乎始终相同:

ZonedDateTime date = ZonedDateTime.now();
ZoneId la = ZoneId.of("America/Los_Angeles");
ZonedDateTime date2 = date.of(date.toLocalDateTime(), la);

// 24/02/2017 - 04:53
System.out.println(DateTimeFormatter.ofPattern("dd/MM/yyyy - hh:mm").format(date));
// same result as the previous one
// 24/02/2017 - 04:53
System.out.println(DateTimeFormatter.ofPattern("dd/MM/yyyy - hh:mm").format(date2));

我所在的时区不同于洛杉矶。


编辑2:

找到了如何更改时区:

// Change this:
ZonedDateTime date2 = date.of(date.toLocalDateTime(), la); // incorrect!
// To this:
ZonedDateTime date2 = date.withZoneSameInstant(la);

你是否正在使用JDK8的java.time.ZonedDateTime? - reos
是的,我想是这样的... - Michel Feinstein
使用ZonedDateTime类型的format()方法 - bart.s
5
使用小写字母"h"是一个严重的错误。要么与am/pm结合使用,因为它是12小时制,要么使用大写字母"H"表示24小时制。 - Meno Hochschild
3个回答

105

谢谢!这个可行!现在我只需要弄清楚如何在不同的时区之间切换并相应地打印它... - Michel Feinstein
请随时提出另一个问题。 - reos
这只是我的印象吗?无论定义的时区是什么,它总会打印ZonedDateTime吗? - Michel Feinstein
1
没关系,我发现我需要使用 ZonedDateTime.withZoneSameInstant()...谢谢! - Michel Feinstein

3

日期时间格式 dd/MM/yyyy - hh:mm 不合理

日期时间格式 dd/MM/yyyy - hh:mm 因为缺少 a 而失去了意义。请注意,h 表示 上午或下午时钟小时数(1-12),而 a 表示 一天内的上午或下午,即没有 ah 返回的小时将会是模棱两可的。例如,没有 ah 将无法区分上午 9:00 和下午 9:00。

因此,请使用表示 一天内的小时数(0-23)H 或者带有 ah

另外,由于日期时间解析/格式化API与 Locale 有关,因此总是要在格式化程序中使用 Locale

ZoneId zoneId = ZoneId.of("Europe/London");
ZonedDateTime zdt9Am = ZonedDateTime.of(LocalDate.now(), LocalTime.of(9, 0), zoneId);
ZonedDateTime zdt9Pm = ZonedDateTime.of(LocalDate.now(), LocalTime.of(21, 0), zoneId);

DateTimeFormatter ambiguousFormatter = 
                    DateTimeFormatter.ofPattern("dd/MM/yyyy - hh:mm", Locale.ENGLISH);
String ambiguosDtStr1 = zdt9Am.format(ambiguousFormatter);
String ambiguosDtStr2 = zdt9Pm.format(ambiguousFormatter);
System.out.println(ambiguosDtStr1); // 08/10/2022 - 09:00
System.out.println(ambiguosDtStr2); // 08/10/2022 - 09:00

DateTimeFormatter correctAmPmFormatter = 
                    DateTimeFormatter.ofPattern("dd/MM/yyyy - hh:mm a", Locale.ENGLISH);
System.out.println(zdt9Am.format(correctAmPmFormatter)); // 08/10/2022 - 09:00 AM
System.out.println(zdt9Pm.format(correctAmPmFormatter)); // 08/10/2022 - 09:00 PM

DateTimeFormatter correct24HourFormatter = 
                    DateTimeFormatter.ofPattern("dd/MM/yyyy - HH:mm", Locale.ENGLISH);
System.out.println(zdt9Am.format(correct24HourFormatter)); // 08/10/2022 - 09:00
System.out.println(zdt9Pm.format(correct24HourFormatter)); // 08/10/2022 - 21:00

请查看DateTimeFormatter文档以了解更多信息。
Trail: Date Time中学习有关现代日期时间API的更多信息。

1
非常感谢以上内容。这里是Scala版本,其中localDateTime.now始终为Zulu/UTC时间。
import java.time.format.DateTimeFormatter
import java.time.LocalDateTime
import java.time.ZoneId

val ny = ZoneId.of("America/New_York")
val utc = ZoneId.of("UTC")
val dateTime = LocalDateTime.now.atZone(utc)

val nyTime = DateTimeFormatter.
      ofPattern("yyyy-MMM-dd HH:mm z").
      format(dateTime.withZoneSameInstant(ny))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接