【问题标题】:Java Android Studio - Unparseable date error on phisycal device with Android 10Java Android Studio - 使用 Android 10 的物理设备上出现无法解析的日期错误
【发布时间】:2021-02-18 07:35:09
【问题描述】:

这部分代码将“2020 年 1 月 1 日”等输入转换为“01/01”。整个代码在 Android 到 Pie 的设备上完美运行,在 AVD 中也可以在 Q 和 R 的设备上完美运行。当我尝试在具有 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:无法解析的日期:“Thu Nov 05 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 但结果相同

【问题讨论】:

  • 顺便考虑扔掉长期过时且臭名昭著的麻烦SimpleDateFormat和朋友。看看您是否可以使用desugaring 或将ThreeTenABP 添加到您的Android 项目中,以便使用现代Java 日期和时间API 的java.time。使用起来感觉好多了。
  • 我会尽力做到的。顺便说一句,仍然不知道我的问题:/
  • 作为反馈。我使用新的 Java.time 完全转换了代码,这解决了我在物理设备上与 Android Q(和 R)的兼容性问题。看来他们不喜欢 SimpleDataFormat
  • 很高兴听到!如果您能将其发布为您自己问题的答案,以供其他读者学习,我会很高兴。

标签: android android-studio date simpledateformat android-10.0


【解决方案1】:

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

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

                        String dateInString = dato;
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", 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++;
                }

【讨论】:

    【解决方案2】:

    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,这是现代类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
    • 在较旧的 Android 上,请使用脱糖或 Android 版本的 ThreeTen Backport。后者称为 ThreeTenABP。使用 ThreeTenABP 时,请确保从 org.threeten.bp 导入日期和时间类以及子包。

    链接

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 2020-12-08
      • 2017-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多