如何格式化 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.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

从哪里获得 java.time 类?

Java SE 8Java SE 9 及更高版本 内置。 标准 Java API 的一部分,带有捆绑实现。 Java 9 添加了一些小功能和修复。 Java SE 6Java SE 7 大部分 java.time 功能都在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android ThreeTenABP 项目专门针对 Android 改编了 ThreeTen-Backport(如上所述)。 见How to use ThreeTenABP…

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 和more。

【讨论】:

亲爱的投票者:请在投票的同时留下批评意见。 嘿,我玩java.time 很久了,还没发现GregorianCalendarZonedDateTime 之间的转换。这是一件自然而美好的事情,因为这些类在预期用途上非常匹配。相反的转换以GregorianCalendar.from(ZonedDateTime) 存在。谢谢你的消息,不管它是不是旧消息。 @OleV.V.是的,这种转换途径并不明显,因为这些方法只存在于具体的GregorianCalendar 类上,而 存在于常用的Calendar 抽象类上。如果你手头有一个Calendar 对象,你必须用instanceOf 进行测试,以验证它实际上是一个GregorianCalendar,转换它,然后调用转换方法。

以上是关于如何格式化 GregorianCalendar的主要内容,如果未能解决你的问题,请参考以下文章

django中如何格式化当前时间

MyEclipse,HTML页面的代码如何格式化/整理?

jsp如何时间格式化输出呢?

苹果系统下如何格式化移动硬盘

Ruby如何格式化嵌套哈希

如何格式化日期