首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java11 (OpenJDK 11)不可解析日期

Java11 (OpenJDK 11)不可解析日期
EN

Stack Overflow用户
提问于 2020-10-13 14:58:05
回答 2查看 1.4K关注 0票数 0

我正在尝试将代码从Java 8迁移到OpenJDK 11,在我试图解析日期字符串之前,一切进展都非常顺利。我有大量这些数据字符串来自数据库(不,我不能更改数据库),它们在Java 7中解析得很好,但在Java 11中失败。

一些注意事项:

  1. 区域设置为相同的默认值。
  2. 日期最初是使用具有长、长设置的日期格式化程序生成的。
  3. 我在Java 8上运行了这个程序以获得磨坊的时间。然后在Java 11上,我把在磨坊的时间转换成了一个日期。看上去挺好的。
  4. 然而,该系统似乎在日期和时间之间插入了一个"at“。
  5. 我试图添加"at“文本到日期,但仍然失败。

有人能给我指明正确的方向吗?我最终需要对这些字符串做日期计算。

谢谢!

布鲁斯

代码语言:javascript
复制
package utility;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;


public class OpenJDK11DateDisaster {
    public static void main(String args[])
    {
        /*
         * Example of the date string that works with Java 8 but fails to
         * parse in OpenJDK 11.
         * 
         * Note:  The Locale is identical between the two versions (US, English)
         * 
         */
        
        /* Java 8 Output...
        Java Version = 1.8.0_265
        Broken Date = September 1, 2015 3:13:29 AM MDT
        Convert mills to a date.
        From mills date = September 1, 2015 3:13:29 AM MDT
        Broken Date = September 1, 2015 3:13:29 AM MDT
        Attempting to parse broken date.
        Date in mills = 1441098809000
        From mills date = September 1, 2015 3:13:29 AM MDT
        
        Java 11 output...
        Java Version = 11.0.8
        Broken Date = September 1, 2015 3:13:29 AM MDT
        Convert mills to a date.
        From mills date = September 1, 2015 at 3:13:29 AM MDT
        Broken Date = September 1, 2015 3:13:29 AM MDT
        Attempting to parse broken date.
        java.text.ParseException: Unparseable date: "September 1, 2015 3:13:29 AM MDT"

        Unable to parse broken date.
        Adding in the at...
            at java.base/java.text.DateFormat.parse(DateFormat.java:395)
            at utility.OpenJDK11DateDisaster.main(OpenJDK11DateDisaster.java:60)
        Fixed date =  September 1, 2015 at 3:13:29 AM MDT
            java.text.ParseException: Unparseable date: " September 1, 2015 at 3:13:29 AM MDT"
            at java.base/java.text.DateFormat.parse(DateFormat.java:395)
            at utility.OpenJDK11DateDisaster.main(OpenJDK11DateDisaster.java:89)

        Unable to parse fixed date.

        
        */
        System.out.println("Java Version = " + System.getProperty("java.version"));
        // This is the date that will parse in Java 7 but fails in Java 11
        String BrokenDate = "September 1, 2015 3:13:29 AM MDT";
        System.out.println("Broken Date = " + BrokenDate);
        
        // Broken date converted to mills in Java 7.
        long mills = 1441098809000L;
        
            
        System.out.println("Convert mills to a date.");
        DateFormat df2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
        
        Date millDate = new Date(mills);
        System.out.println("From mills date = " + df2.format(millDate));
        
        System.out.println("Broken Date = " + BrokenDate);
        
        
        /*
         * Parse these old dates.
         */
        System.out.println("Attempting to parse broken date.");
        df2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
        Date date = null;
        try {
            date = df2.parse(BrokenDate) ;
        } catch (ParseException e) {
            e.printStackTrace();
            System.out.println();
            System.out.println("Unable to parse broken date.");
            
            // For some reason, they now put an "at" word between the date and the time.
            // Here we put the "at" back in and see.
            
            // See if we can fix it.
            System.out.println("Adding in the at...");
            StringList fields = Acl.split(BrokenDate, ' ');
            String FixedDate = "";
            Iterator iter = fields.iterator();
            int count = 0;
            while (iter.hasNext() ) {
                String field = (String)iter.next();
                count++;
                FixedDate += " " + field;
                if (count == 3) {
                    // add an at
                    FixedDate += " at";
                }
                
            }
            System.out.println("Fixed date = " + FixedDate);
            // Now see if it will parse
        
            try {
                date = df2.parse(FixedDate);
            } catch (ParseException e2) {
                e2.printStackTrace();
                System.out.println();
                System.out.println("Unable to parse fixed date.");
                System.exit(-1);
            }
            System.out.println("Was able to parse Fixed Date " + date);
        }
        mills = date.getTime();  // From the BrokenDate
        // Should be -62112243600000 as computed on a Java 7 machine
        System.out.println("Date in mills = " + mills);
        
        // Convert the mills to a date.
        millDate = new Date(mills);
        System.out.println("From mills date = " + df2.format(millDate));
    }
}
EN

回答 2

Stack Overflow用户

发布于 2020-10-13 15:14:45

根据文档https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/DateFormat.html,您似乎需要完整的格式

代码语言:javascript
复制
LONG is longer, such as January 12, 1952 or 3:30:32pm
FULL is pretty completely specified, such as Tuesday, April 12, 1952 AD or 3:30:42pm PST.

如果可能的话,在解析方法(第395行)中在DateFormat.java上放置一个断点,以了解正在发生的事情。

票数 0
EN

Stack Overflow用户

发布于 2020-10-13 22:37:44

一个安全的选项是将MDT替换为相应的时区说明符Mountain Standard Time

代码语言:javascript
复制
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String dateTimeStr = "September 1, 2015 3:13:29 AM MDT".replace("MDT", "Mountain Standard Time");
        ZonedDateTime zdt = ZonedDateTime.parse(dateTimeStr,
                DateTimeFormatter.ofPattern("MMMM d, u h:m:s a zzzz", Locale.ENGLISH));
        System.out.println(zdt);

        // Custom format
        String formatted = zdt.format(DateTimeFormatter.ofPattern("EEEE MMMM dd uuuu 'at' hh:mm:ss a", Locale.ENGLISH));
        System.out.println(formatted);
    }
}

输出:

代码语言:javascript
复制
2015-09-01T03:13:29-06:00[America/Denver]
Tuesday September 01 2015 at 03:13:29 AM

注意:遗留的java.util日期-时间类已经过时,容易出错,它们的格式化API SimpleDateFormat也是如此。我建议您停止完全使用它们,转而使用现代日期时间API。在日期:时间上了解更多关于现代日期时间API的信息。

如果您是为您的Android项目这样做,并且您的Android级别仍然不符合Java-8,那么请检查通过desugaring提供的Java 8+ API如何在安卓项目中使用ThreeTenABP

带有遗留API的

代码语言:javascript
复制
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        String dateTimeStr = "September 1, 2015 3:13:29 AM MDT".replace("MDT", "Mountain Standard Time");
        Date date = new SimpleDateFormat("MMMM d, yyyy h:m:s a zzzz", Locale.ENGLISH).parse(dateTimeStr);
        System.out.println(date);

        // Custom format
        String formatted = new SimpleDateFormat("EEEE MMMM dd yyyy 'at' hh:mm:ss a", Locale.ENGLISH).format(date);
        System.out.println(formatted);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64337726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档