【问题标题】:How to identify date format? [closed]如何识别日期格式? [关闭]
【发布时间】:2020-01-06 16:17:04
【问题描述】:

1) 如果我打印出一个日历对象,我会得到: java.util.GregorianCalendar[time=1567535353679,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=8,WEEK_OF_YEAR=36,WEEK_OF_MONTH=1,DAY_OF_MONTH=3,DAY_OF_YEAR=246,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=6,HOUR_OF_DAY=18,MINUTE=29,SECOND=13,MILLISECOND=679,ZONE_OFFSET=0,DST_OFFSET=0]

2) 如果我打印出一个 Date 对象,我会得到:

Tue Sep 03 18:29:13 GMT 2019

3) 但是我正在检查生成的 XML 并观察到这种格式:

2014-02-28T08:00:00.000Z

我在 XML 中看到的是哪种格式?

【问题讨论】:

标签: java date calendar


【解决方案1】:

日期时间对象没有“格式”

如何识别日期格式?

日期时间对象没有“格式”。每个类都定义了自己的内部存储日期时间值的机制。这种机制通常不关我们的事。类的 API,该类做出的承诺,才是最重要的。

您可能将日期时间对象生成的文本与日期时间对象本身混为一谈。日期时间类可以将文本作为其实例化的一部分进行解析。日期时间类可以生成文本来表示它们的值。但是文本和对象是分开的和不同的。

避免Calendar

如果我打印出一个日历对象,我会得到:

Calendar::toString 方法只是其许多内部字段的数据转储。显然仅用于调试,否则无用。

Calendar 类及其常用子类GregorianCalendar 现在都为legacy。几年前,随着 JSR 310 的采用,它们被 java.time 类所取代。永远不要使用它们。 GregorianCalendar 被专门替换为 ZonedDateTime

避免Date

如果我打印出一个 Date 对象,我会得到:

Date::toString 方法的谎言。该方法在生成文本时动态应用 JVM 的当前默认时区。 java.util.Date 实际上代表 UTC 中的一个时刻,而不是在 toString 的结果中看到的时区。这个反功能是从不使用Date 的众多原因之一。

java.util.Date 类已替换为 java.time.Instant,它也代表 UTC 中的一个时刻,但分辨率更高,为纳秒而不是毫秒。

ISO 8601

但是我正在检查生成的 XML 并观察到这种格式:

2014-02-28T08:00:00.000Z

该文本的格式在ISO 8601 标准中定义。该标准被巧妙地设计为以文本形式表示各种日期时间值以进行数据交换。该标准取代了早期定义不明确的日期时间文本格式,例如在早期电子邮件协议中看到的。

java.time 类在解析/生成字符串时默认使用ISO 8601 格式。

UTC 当前时刻

要以 UTC 格式捕捉当前时刻,请使用 Instant

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

生成以标准 ISO 8601 格式表示该值的文本。末尾的Z 表示UTC,发音为“Zulu”。

2020-01-23T12:34:56.123456Z

解析这样的字符串。

Instant instant = Instant.parse( "2020-01-23T12:34:56.123456Z" );

时区

通过特定地区、时区的人们使用的挂钟时间查看同一时刻。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

通过将时区名称附加在方括号中,以明智地扩展 ISO 8601 标准的格式生成字符串。

String output = zdt.toString() ;

看到这个code run live at IdeOne.com

instant.toString(): 2020-01-23T12:34:56.123456Z

zdt.toString(): 2020-01-23T07:34:56.123456-05:00[美国/蒙特利尔]

Java 中的日期时间类型


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

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

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

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

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

【讨论】:

  • 回答“我在 XML 中看到的是哪种格式?”这个简单问题需要大量文字,这是唯一提出的问题,然后您甚至没有做对。 XML 中使用的日期格式由 XML Schema 数据类型规范 (XML Schema Part 2: Datatypes Second Edition) 定义,dateTime 数据类型与 ISO 8601“密切相关”/“受其启发”,因此实际上并非 ISO 8601。跨度>
  • @Andreas 实际上“XML 格式”只是问题的 1/4,但感谢您的反馈。至于该字符串在 XML 中的上下文,该问题没有提及涉及 XML 模式,甚至没有解释该字符串的来源。事实上,我在要求解释的问题上发表了评论。
  • 其实只有一个问题,在最后一行。其余的是事实陈述,而不是问题。如果 OP 意味着所有这些都是问题,那么 OP 应该学习how to ask a better question
  • @Andreas 我必须以不同于你的方式阅读问题。
【解决方案2】:

我在 XML 中看到的是哪种格式?

XML 格式的灵感来自ISO 8601,由XML schema documentation 指定。

3.2.7.1 词法表示

dateTime·lexical space· 由以下形式的字符的有限长度序列组成:'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2021-07-22
    相关资源
    最近更新 更多