java.lang.IllegalArgumentException:错误类:类java.lang.String

时间:2018-05-19 12:15:53

标签: java android string date parsing

我读到了这个问题,但我无法找到我的错误。我在我的Datebase中有日期,当我检索它们并尝试将它们与当前日期进行比较时,这个错误出现在logcat中:

E/AndroidRuntime: FATAL EXCEPTION: main
       Process: com.example.hpdemon.diploma, PID: 9879
       java.lang.RuntimeException: Unable to start receiver com.example.hpdemon.diploma.BroadcastManager: java.lang.IllegalArgumentException: Bad class: class java.lang.String
           at android.app.ActivityThread.handleReceiver(ActivityThread.java:2417)
           at android.app.ActivityThread.access$1700(ActivityThread.java:138)
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1275)
           at android.os.Handler.dispatchMessage(Handler.java:102)
           at android.os.Looper.loop(Looper.java:136)
           at android.app.ActivityThread.main(ActivityThread.java:5034)
           at java.lang.reflect.Method.invokeNative(Native Method)
           at java.lang.reflect.Method.invoke(Method.java:515)
           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:731)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
           at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.IllegalArgumentException: Bad class: class java.lang.String
           at java.text.DateFormat.format(DateFormat.java:296)
           at java.text.Format.format(Format.java:93)
           at com.example.hpdemon.diploma.BroadcastManager.onReceive(BroadcastManager.java:51)
           at android.app.ActivityThread.handleReceiver(ActivityThread.java:2410)
           at android.app.ActivityThread.access$1700(ActivityThread.java:138) 
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1275) 
           at android.os.Handler.dispatchMessage(Handler.java:102) 
           at android.os.Looper.loop(Looper.java:136) 
           at android.app.ActivityThread.main(ActivityThread.java:5034) 
           at java.lang.reflect.Method.invokeNative(Native Method) 

此行出现错误deadline = new Date(deadline.getTime() - 604800000L);我的代码是:

        Users_Database db = new Users_Database(context);
        String currentUsrname = PreferenceManager.getDefaultSharedPreferences(context).getString("USRNFORBROADCAST", "NothingFound");
        List<String> dates=db.getAllDates(db.findID(currentUsrname));
        String dateIns = "";
        String dateVin = "";
        String dateTax = "";
        // int tyres;
        dateIns=(dates.get(0));
        dateVin=(dates.get(1));
        dateTax=(dates.get(2));
        dateIns = dateIns.replaceAll("\n", "");

        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        Calendar c = Calendar.getInstance();//текуща дата
        Date todayDate = c.getTime();
        Date deadline=c.getTime();

        try {
            todayDate = sdf.parse(sdf.format(todayDate.getTime()));
            deadline = sdf.parse(sdf.format(dateIns));
            deadline = new Date(deadline.getTime() - 604800000L);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (todayDate.before(deadline) /*&& hour.equals(yourHour)*/) {
            Intent it = new Intent(context, BootServices.class);
            createNotification(context, it, "I Love My Car", "Краен срок!", "Изтичащ преглед");
            context.startService(it);
        }

2 个答案:

答案 0 :(得分:1)

您没有为精确答案提供足够的信息。所以这里有一些指示。

你正在使用几年前由 java.time 类取代的糟糕的旧日期时间类。

  • Instant已取代Date
  • ZonedDateTime已取代Calendar
  • DateTimeFormatter已取代SimpleDateFormat

如果您必须与尚未针对 java.time 更新的旧代码进行互操作,则可以通过调用添加到旧类的新转换方法来回转换。

您正在使用愚蠢的字符串,您应该使用智能对象。从JDBC 4.2开始,您可以直接与数据库交换 java.time 对象。

Instant instant = myResultSet.getObject( … , Instant.class ) ;

Instant始终为UTC。要获取日期,您必须指定时区。对于任何给定的时刻,日期在全球范围内因地区而异。

ZoneId z = ZoneId.of( "America/Montreal" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;

提取仅限日期的值,显然是您的目标。

LocalDate ld = zdt.toLocalDate() ;

通过致电isBeforeisAfter进行比较。

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

答案 1 :(得分:0)

java.time

这个问题并不完全清楚,但我认为你试图做以下事情:

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");

    List<String> dates = Arrays.asList("31/05/2018", "19/06/2018", "01/07/2018");
    String dateIns = dates.get(0);
    dateIns = dateIns.replaceAll("\n", "");

    LocalDate todayDate = LocalDate.now(ZoneId.of("Pacific/Rarotonga"));
    LocalDate deadline = LocalDate.parse(dateIns, dateFormatter).minusWeeks(1);
    if (todayDate.isBefore(deadline)) {
        System.out.println("I Love My Car. Краен срок! Изтичащ преглед.");
    }

刚刚运行此片段,自5月19日以来严格在5月24日之前,它已打印

  

我爱我的车。 Краенсрок! Изтичащпреглед。

如果碰巧不是Pacific / Rarotonga,请替换您想要的时区。

我正在使用并推荐现代Java日期和时间API java.timeLocalDate是一个没有时间的日期,似乎正好符合您的需求。整个java.time比使用DateSimpleDateFormat的{​​{1}}和SimpleDateFormat更加精彩,这些已经过时了,LocalDate尤其出了名的麻烦。

如果您使用的是至少Java 8或Android API级别26或更高级别,则应确保您已获得符合JDBC 4.2的驱动程序,然后检索 deadline = sdf.parse(sdf.format(dateIns)); 个对象而不是数据库中的字符串。通过这种方式,您可以免除对代码中字符串的任何解析,它不仅更容易,而且更不容易出错。

您的代码出了什么问题?

我认为问题出在这一行:

dateIns

此处StringSimpleDateFormat。格式化已经是字符串的东西是没有意义的,format不能这样做,因此抛出你得到的异常。在将错误的类型传递给SimpleDateFormat方法时,您可能更喜欢并且可能需要编译时错误消息。 format(Date)DateFormat继承format(Object)方法,但从Format继承String方法。因此调用后者java.time,编译器无法确定是否有任何错误。

问题:我可以在Android上使用java.time吗?

是的,org.threeten.bp适用于较旧和较新的Android设备。它只需要至少Java 6

  • 在Java 8及更高版本和更新的Android设备上(来自API级别26,我被告知)现代API内置。
  • 在Java 6和7中获取ThreeTen Backport,新类的后端端口(适用于JSR 310的ThreeTen;请参阅底部的链接)。
  • On(较旧)Android使用Android版的ThreeTen Backport。它被称为ThreeTenABP。并确保使用子包从java.time导入日期和时间类。

链接

  • Oracle tutorial: Date Time解释如何使用java.time
  • Java Specification Request (JSR) 310,首先描述java.time
  • ThreeTen Backport projectcurl -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) -H "Content-Type: application/json; charset=utf-8" --data "{ 'input':{ 'text':'Android is a mobile operating system developed by Google, based on the Linux kernel and designed primarily for touchscreen mobile devices such as smartphones and tablets.' }, 'voice':{ 'languageCode':'en-gb', 'name':'en-GB-Standard-A', 'ssmlGender':'FEMALE' }, 'audioConfig':{ 'audioEncoding':'MP3' } }" "https://texttospeech.googleapis.com/v1beta1/text:synthesize" > synthesize-output.txt 向Java 6和7的后端(JST-310的ThreeTen)。
  • ThreeTenABP,Android版ThreeTen Backport
  • Question: How to use ThreeTenABP in Android Project,有一个非常详尽的解释。