如何格式化 GregorianCalendar
Posted
技术标签:
【中文标题】如何格式化 GregorianCalendar【英文标题】:How can I format a GregorianCalendar 【发布时间】:2017-10-12 05:49:56 【问题描述】:我有一个GregorianCalendar
对象。如何获取格式化字符串?
System.out.print("End of rental: " + endDate);
行生成以下非常长的日历。如何将其格式化为 dd/mm/yyyy?
End of rental: java.util.GregorianCalendar[time=1495050625200,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2017,MONTH=4,WEEK_OF_YEAR=20,WEEK_OF_MONTH=3,DAY_OF_MONTH=17,DAY_OF_YEAR=137,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=8,HOUR_OF_DAY=20,MINUTE=50,SECOND=25,MILLISECOND=200,ZONE_OFFSET=0,DST_OFFSET=3600000]
【问题讨论】:
你应该查看java.util.GregorianCalendar
的文档
本站必须有 50 个关于日期格式的 Q/A。但是例如检查DateFormat
。
@KevinO 实际上,我寻找了一个重复的问题,但找不到一个专门询问如何格式化GregorianCalendar
的问题。所以我写了一个答案。如果您能找到重复的问题,请将此问题标记为重复,我将与您一起投票结束。
Using GregorianCalendar with SimpleDateFormat的可能重复
@Matthias That Question 不是重复的。该问题主要是关于将字符串解析为GregorianCalendar
对象,而此问题以GregorianCalendar
对象开头。引用:“将日期字符串转换为 GregorianCalendar 对象”,“从文件中获取一小段文本,将其分解”,“convertFromDMY
”。
【参考方案1】:
强烈推荐@Basil Bourque 的回答。我只想用 Java 6 和 7 的答案来补充它(所以如果您使用的是 Java 8 或更高版本,请忽略)。此外,如果您可以完全避免 Calendar
类,这是最好的,您应该使用其他答案。在下文中,我假设您无法避免从某些遗留 API 获取 Calendar
对象,而您现在无法更改或不想更改。
java.time 和 ThreeTen 反向移植
我的示例来自一个重复的问题,如何将日历对象转换为如下所示的日期格式(链接在底部)。所需的格式为
7/23/2019 11:02:11 AM
我们可以通过以下方式获得。首先我们实例化一个格式化程序:
private static final DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("M/d/u h:mm:ss a", Locale.ENGLISH);
那我们就这样使用
Calendar cal = getCalendarFromLegacyApi();
ZonedDateTime zdt = DateTimeUtils.toZonedDateTime(cal);
String howItShouldLook = zdt.format(formatter);
System.out.println(howItShouldLook);
本例中的输出是期望的:
2019 年 7 月 23 日上午 11:02:11
问题:我可以在 Java 7 上使用 java.time 吗?
是的,java.time 在 Java 7 上运行良好。它至少需要 Java 6。
在 Java 8 及更高版本以及更新的 android 设备(从 API 级别 26 起)中,现代 API 是内置的。 在 Java 6 和 7 中获得 ThreeTen Backport,这是现代类的后向端口(JSR 310 的 ThreeTen;请参阅底部的链接)。 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从org.threeten.bp
导入日期和时间类以及子包。
链接
Oracle tutorial: Date Time 解释如何使用 java.time。 Java Specification Request (JSR) 310,其中首次描述了java.time
。
ThreeTen Backport project,java.time
的向后移植到 Java 6 和 7(JSR-310 的 ThreeTen)。
ThreeTen Backport API documentation (Javadoc)
ThreeTenABP,Android 版 ThreeTen Backport
Question: How to use ThreeTenABP in Android Project,解释得很透彻。
重复的问题How to convert a Calendar object to date format that looks like this 是提供此答案的机会。
【讨论】:
【参考方案2】:tl;博士
endDate.toZonedDateTime()
.format( DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) )
23/01/2017
详情
从麻烦的遗留类GregorianCalendar
转换为现代java.time 类ZonedDateTime
。调用toString
生成标准ISO 8601 格式的文本。
endDate.toZonedDateTime().toString()
得到这样的东西:
2017-01-23T12:34:56.789-07:00[美国/洛杉矶]
仅用于您的约会,请使用DateTimeFormatter
。 Specify您的自定义格式模式。
endDate.toZonedDateTime()
.format( DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) )
23/01/2017
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获得 java.time 类?
Java SE 8、Java SE 9 及更高版本 内置。 标准 Java API 的一部分,带有捆绑实现。 Java 9 添加了一些小功能和修复。 Java SE 6 和 Java SE 7 大部分 java.time 功能都在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android ThreeTenABP 项目专门针对 Android 改编了 ThreeTen-Backport(如上所述)。 见How to use ThreeTenABP…。ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval
、YearWeek
、YearQuarter
和more。
【讨论】:
亲爱的投票者:请在投票的同时留下批评意见。 嘿,我玩java.time
很久了,还没发现GregorianCalendar
和ZonedDateTime
之间的转换。这是一件自然而美好的事情,因为这些类在预期用途上非常匹配。相反的转换以GregorianCalendar.from(ZonedDateTime)
存在。谢谢你的消息,不管它是不是旧消息。
@OleV.V.是的,这种转换途径并不明显,因为这些方法只存在于具体的GregorianCalendar
类上,而不 存在于常用的Calendar
抽象类上。如果你手头有一个Calendar
对象,你必须用instanceOf
进行测试,以验证它实际上是一个GregorianCalendar
,转换它,然后调用转换方法。以上是关于如何格式化 GregorianCalendar的主要内容,如果未能解决你的问题,请参考以下文章