Java Android Studio-具有Android 10的Phsycal设备上的不可解析的日期错误

问题描述

这部分代码将输入从“ 2020年1月1日”转换为“ 01/01”。整个代码在配备Pie的Android设备以及配备Q和R的AVD设备中均能完美运行。当我尝试在带有Android Q的非同寻常的Android设备上运行它时,它无法运行(我尝试使用2种不同的设备(Mi Note 10和OnePlus 6T))。我检查了调试器,并在IF循环中发现了此错误(我认为在指令中:@SuppressLint(“ SimpleDateFormat”)SimpleDateFormat dt = new SimpleDateFormat(“ E MMM dd HH:mm:ss z yyyy“);”

W / System.err:java.text.ParseException:无法解析的日期:“星期四11月5日00:00:00 GMT + 01:00 2020”

       String[] mese = new String[] {"January","February","march","April","May","June","July","August","September","October","November","December"};
       int a= 0 ;

       while (a < 12){ 
                    if(dato.contains(mese[a])){ 
                             System.out.println("Test 3");
                             DateFormat format = new SimpleDateFormat("MMMM d,yyyy",Locale.ENGLISH);
                             Date date = format.parse(dato);
                             @SuppressLint("SimpleDateFormat") SimpleDateFormat dt = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy");
                             Date date2 = dt.parse(String.valueOf(date));
                             @SuppressLint("SimpleDateFormat") SimpleDateFormat dt1 = new SimpleDateFormat("dd/MM");
                             assert date2 != null;
                             dato = dato.replaceAll(dato,dt1.format(date2));
                    }
                    a++;
                }

我的图案是错误的吗?我尝试了EEE MMM dd HH:mm:ss zzz yyyy和EEE MMM dd HH:mm:ss zzzz yyyy,但是结果相同

解决方法

java.time和废止或ThreeTenABP

我建议您使用现代Java日期和时间API java.time进行日期工作。

java.time格式化程序是线程安全的,因此我们通常倾向于将它们声明为静态:

private static final DateTimeFormatter sourceFormatter
        = DateTimeFormatter.ofPattern("MMMM d,yyyy",Locale.ENGLISH);
private static final DateTimeFormatter targetFormatter
        = DateTimeFormatter.ofPattern("dd/MM");

现在您的转换是这样的:

    String dato = "November 5,2020";
    LocalDate date = LocalDate.parse(dato,sourceFormatter);
    dato = date.format(targetFormatter);
    System.out.println(dato);

输出:

05/11

您的代码出了什么问题?

在我看来,您进行格式转换的方式比所需的更为复杂。除了检查字符串中是否有月份名称之外,为什么不尝试解析它呢?如果没有,我的代码将抛出一个DateTimeParseException,然后您可以捕获并处理适合您情况的方式。您的代码将String转换为Date,再将String转换为Date,再转换为String。我不明白原因。另外,您正在使用SimpleDateFOrmat类。众所周知,这很麻烦并且已经过时了。您第二次从String解析到Date失败了,我敢打赌,我知道原因:对于您的第一个SimpleDateFormat,您记得指定了Locale.ENGLISH,但是您忘记了第二SimpleDateFormat。该字符串包含英语的ThuNov,因此,如果您的Android Q和R设备具有不同的语言设置,则可以解释。最后,出于您的目的,此行:

    dato = dato.replaceAll(dato,dt1.format(date2));

与更简单的相同:

    dato = dt1.format(date2);

问题:java.time是否不需要Android API级别26?

java.time在较新和较旧的Android设备上均可正常运行。它只需要至少 Java 6

  • 在Java 8和更高版本以及更新的Android设备(API级别26以上)中,内置了现代API。
  • 在非Android Java 6和7中,获得ThreeTen Backport,这是现代类的backport(JSR 310的ThreeTen;请参见底部的链接)。
  • 在较旧的Android上,请使用废除旧书或Android版本的ThreeTen Backport。后者称为ThreeTenABP。使用ThreeTenABP时,请确保使用子包从org.threeten.bp导入日期和时间类。

链接

,

我以这种方式解决了,不再使用SimpleDateFormat:

         while (a < 12){
                    if(dato.contains(mese[a])){

                        String dateInString = dato;
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d,Locale.ENGLISH);
                        LocalDate dateTime = LocalDate.parse(dateInString,formatter);
                        DateTimeFormatter f2 = DateTimeFormatter.ofPattern("dd/MM");
                        String newDate = dateTime.format(f2);
                        dato = dato.replaceAll(dato,newDate);

                    }
                    a++;
                }