【问题标题】:Human readable and parsable date format in JavaJava中人类可读和可解析的日期格式
【发布时间】:2010-11-30 21:44:32
【问题描述】:

我想将 Date 对象保存为可读字符串(例如 22/10/2009 21:13:14),该字符串也可解析回 Date 对象。

我尝试了很多东西,我能找到的最好的方法是使用 DateFormater 进行解析和格式化,但它有一个挫折。当您格式化日期时,您会丢失秒信息。我试图找到是否有一个选项来格式化它并显示秒数(更好的是毫秒级别,因为这是 Date 对象允许您拥有的分辨率),但我没有完成。

有什么想法吗?

【问题讨论】:

    标签: java datetime date date-format


    【解决方案1】:

    看看java.text.SimpleDateFormat

    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS");
    Date dt = new Date();
    String S = sdf.format(dt); // formats to 09/23/2009 13:53:28.238
    Date dt2 = sdf.parse(S); // parses back
    

    【讨论】:

    • 当这个答案写于 2009 年时,SimpleDateFormat 就是我们为此目的所拥有的。它已被证明很麻烦,幸运的是,它已在 2014 年被现代 Java 日期和时间 API 及其 DateTimeFormatterjava.time 取代。我建议您不要再使用 SimpleDateFormat
    【解决方案2】:

    SimpleDateFormat 可以基于一个非常简单的模式系统(包括秒甚至毫秒)来格式化和解析日期。

    【讨论】:

    • @Unihedron 更新了链接。审稿人,请注意,这不是一个仅链接的答案 - 没有链接,答案仍然有意义,并且链接本身就是官方文档。
    【解决方案3】:

    其他答案都不错。

    但是在做这种事情时选择一种在编码为字符串时正确排序的格式....“yyyy/MM/dd HH:mm: ss”没问题。当软件工程师选择一种不能以明显、方便的方式排序的日期格式时,我总是感到惊讶。

    你会在未来的某个遥远的时刻为你的开发者伙伴们省去很多痛苦——把它想象成好的业力:-)

    【讨论】:

    • "yyyy/dd/MM" 排序不正确。考虑到 2015/21/10、2015/20/11 和 2015/22/11 被排序为 2015/20/11、2015/21/10、2015/22/11 作为字符串。
    • 对不起,我的意思是 yyyy/MM/dd。固定。
    【解决方案4】:

    ISO 8601

    使用ISO 8601 格式。

    • 它很灵活,它包括秒和秒的小数部分(如果有),但如果它们为 0,你也可以将它们排除在外。
    • 它是标准的,因此越来越多的工具对其进行格式化和解析。非常适合用于存储或数据交换的序列化。
    • 类似于 2009-10-22T21:13:14,我应该说它非常易于阅读(尽管中间的 T 表示时间部分的开始,起初可能会觉得不寻常)。
    • 只要年份在 1000 到 9999 的四位数范围内,字符串就会按照 mikera 在another answer 中的要求正确排序。
    • java.time 的类,现代 Java 日期和时间 API 以及 Joda Time 的类将 ISO 8601 解析为默认值,即没有任何显式格式化程序,并从它们的 toString 生成相同的格式方法。

    一个使用java.time的简单演示:

    LocalDateTime dateTime = LocalDateTime.of(2009, 10, 22, 21, 13, 14);
    String readableString = dateTime.toString();
    System.out.println(readableString);
    LocalDateTime parsedBack = LocalDateTime.parse(readableString);
    System.out.println(parsedBack);
    

    这会打印两条相同的行:

    2009-10-22T21:13:14
    2009-10-22T21:13:14
    

    后一个System.out.println() 调用隐式调用toString() 一次,所以这应该不足为奇。

    【讨论】:

    • 问题是转换Date对象,如果我想使用你的代码那么我需要将Date转换为LocalDateTime,我该怎么做?
    • 感谢@RoyHabeahan 的关注。给定一个老式的DateString readableString = yourDate.toInstant().toString(); 和相反的方式Date parsedBack = Date.from(Instant.parse(readableString));。该字符串最后将有Z,它表示UTC。在这种情况下不要使用LocalDateTime
    【解决方案5】:

    有点跑题了,但我总觉得有必要提醒人们 DateFormat 和 SimpleDateFormat 不是线程安全的! Sun 文档清楚地说明了这一点,但我一直在野外寻找代码,人们将 SimpleDateFormat 粘贴在静态文件中......

    【讨论】:

    • 这就是为什么每个人都应该使用 Joda Time 来代替,以免自己头疼:)
    • 我完全同意。另一方面,我希望 Sun 修复这些类,所以如果不出意外,我不必再坐下来学习另一个“并发经验教训”——人们警告我这些课程。 (哦,具有讽刺意味的是......我刚刚在 StackOverflow 上做了完全相同的事情 :-))
    • 甲骨文(收购 Sun 的公司)已修复此问题。 java.time 的类,现代 Java 日期和时间 API,是线程安全的。忘记关于旧的SimpleDateFormat 的一切。
    【解决方案6】:

    如果您想简单一点,并且避免制作大多数其他答案所涉及的自己的 DateFormat,您可以利用 java.time.Instant 中的默认格式:

    (new Date()).toInstant.toString();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-09
      • 1970-01-01
      • 2018-04-18
      • 2012-08-03
      • 1970-01-01
      • 2018-04-22
      相关资源
      最近更新 更多