【问题标题】:error output converting date format from YYYYMMDD to dd-mm-yyyy将日期格式从 YYYYMMDD 转换为 dd-mm-yyyy 的错误输出
【发布时间】:2018-02-24 22:51:57
【问题描述】:

我对日期的 java 转换有疑问。 我输入了一个字符串 YYYYMMDD,它转换为 long 并且通过执行代码输出是错误的

try {
           //Current date to dd-mm-yyyy
            Date currentDate = new Date(20161205); //or 
            DateFormat df = new SimpleDateFormat("dd-mm-yyyy");
            String strCurrentDate = df.format(currentDate);
            System.out.println("Date is " + strCurrentDate);
        } catch (Exception e) {
            System.out.println("Exception :" + e);
        }

输出是:01-49-1970 为什么??我该如何解决这个问题

【问题讨论】:

  • 请不要使用旧的java.util.Date 类。您应该改用 java.time 包中的适当类。
  • 您的默认时区是什么?输出中的 49 看起来很奇怪。
  • 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 和 Java 中内置的 java.time 类所取代9. 见Tutorial by Oracle

标签: java string date-format


【解决方案1】:

解决方案:

 Date currentDate = new Date(116,11,05);

解释:

您将单个数字作为 Date 构造函数的参数。如果您查看此类in Java API documentation here 的可用构造函数列表,您会注意到将选择以long 作为参数的构造函数。正如文档所述:

Date​(long date) - 分配一个 Date 对象并初始化它以表示自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。

取而代之的是,如果你真的需要使用 java.util.date 包(现在认为 java.time 是正确的选择),请考虑使用另一个构造函数:Date​(int year, int month, int date)。在这种情况下,您应该将以下数字作为参数传递:

Date currentDate = new Date(116,11,05);

这是因为:

年份 - 减去 1900 的年份。

月 - 0-11 之间的月份。

日期 - 1-31 之间的月份中的某天。

顺便说一句,考虑使用 java.time 包而不是 java.util,因为 java.util.Date 现在已弃用。

【讨论】:

    【解决方案2】:

    你做错了看 如果您想将日期从该格式yyyyMMdd 更改为该格式yyyy-MM-dd

    你必须稍微改变你的代码

    try {
    //Current date to dd-mm-yyyy
    
    DateFormat fromFormate = new SimpleDateFormat("yyyyMMdd");
    DateFormat toFormate = new SimpleDateFormat("yyyy-MM-dd");
    
    String dateToFormate = "20161205"; //or 
    Date d=fromFormate.parse(dateToFormate);
    
    System.out.println("Date is " + toFormat.formate(d));
    } catch (Exception e) {
    System.out.println("Exception :" + e);
    }
    

    【讨论】:

    • 在 2018 年使用旧的日期时间类是不明智的。
    【解决方案3】:

    tl;博士

    LocalDate.parse(
        "20161205", 
        DateTimeFormatter.BASIC_ISO_DATE
    ).format(
        DateTimeFormatter.ofPattern("dd-MM-uuuu")
    )
    

    2016 年 5 月 12 日

    为什么是 01-49-1970?

    我无法重现您的确切输出,因此可以解释其中的大部分内容,而不是全部。可能您混淆了几个测试示例并且没有从new Date(20161205) 得到 01-49-1970。在我的电脑上,我得到了Date is 01-36-1970。已经够糟糕了。

    正如其他人所指出的,new Date(20161205) 为您提供了一个时间点,该时间点在 1970 年 1 月 1 日 00:00 UTC 的纪元之后 20 000 多秒。在 UTC 中,时间是 1 月 1 日的 5:36:01.205 (AM)。您所在时区的时间可能不同。有些时区的日期仍然是 1969 年 12 月 31 日。

    但这似乎并不能解释你是如何在 1970 年的第 49 个月或我在第 36 个月获得输出的。这是因为您在格式模式字符串中使用了小写的mmmm 是一分钟。大写的MM 是月份。所以我得到的 36 与 5:36:01 中的分钟相匹配。有分钟不相同的时区;但我目前找不到小时为 49 的时区,因此我无法解释您报告的确切输出。

    我该如何解决这个问题?

    正如其他人所说,使用现代 Java 日期和时间 API java.time。使用起来感觉好多了。

        LocalDate currentDate = LocalDate.of(2016, Month.DECEMBER, 5);
    

    或者来自一个字符串:

        LocalDate currentDate 
                = LocalDate.parse("20161205", DateTimeFormatter.BASIC_ISO_DATE);
    

    格式化为您想要的输出:

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu");
        String strCurrentDate = currentDate.format(dtf);
        System.out.println("Date is " + strCurrentDate);
    

    打印出来

    日期是 05-12-2016

    如果您碰巧在上面的格式模式字符串中使用mm 而不是MM,java.time 会通过异常通知您。

    链接: Oracle Tutorial: Date Time 解释如何使用 java.time。

    【讨论】:

    【解决方案4】:

    就像@oceano22 所说,有更新/更好的日期/时间包可用。也就是说,发生这种情况的原因是,当您调用 new Date(20161205) 时,日期构造函数采用的参数不是 yyyyMMdd。根据 javadoc ...“分配一个 Date 对象并将其初始化为表示自称为“纪元”的标准基准时间以来的指定毫秒数,即 1970 年 1 月 1 日,格林威治标准时间 00:00:00。”

    所以实际上,您在 Unix 纪元(1970 年 1 月 1 日)之后仅 2000 万毫秒创建了一个日期。

    您正在尝试使用您定义的 SimpleDateFormat df 将 2016 年 12 月 5 日转换为日期使用 df.parse("05-12-2016")。

    您可能还希望在日期格式中使用大写 M 来表示月份,例如"dd-MM-yyyy" 因为小写的 m 代表分钟。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-09
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      相关资源
      最近更新 更多