After i added throws ParseException, the parse excception still occured, why?

812 Views Asked by At

The question is to calculate the days between two dates. Here's my code

public static void main(String[] args) throws ParseException  {
    // TODO Auto-generated method stub
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd)");
    Scanner input=new Scanner(System.in);
    String date1=input.nextLine();
    String date2=input.nextLine();
    Date d1 =sdf.parse(date1);
    Date d2= sdf.parse(date2);
    if(d1.getTime()>d2.getTime()) {
        System.out.println(d2.getTime()-d1.getTime()/(24*60*60*1000));
    }
    else
        System.out.println(d1.getTime()-d2.getTime()/(24*60*60*1000));

and output is

2010/05/29
2010/01/01
Exception in thread "main" java.text.ParseException: Unparseable date: "2010/05/29"
        at java.base/java.text.DateFormat.parse(DateFormat.java:396)
        at HW10_09156136_1092.HW10_Ex01.main(HW10_Ex01.java:15)
1

There are 1 best solutions below

0
Arvind Kumar Avinash On

You have used m [Minute in hour] at the place of M [Month in year].

Your input has / as the separator whereas you have specified - for it in the parser. The input should match the pattern specified with the parser.

Apart from this, the java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Demo using java.time, the modern Date-Time API:

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        String strDateStart = "2021-06-09";
        String strDateEnd = "2021-06-12";
        LocalDate dateStart = LocalDate.parse(strDateStart);
        LocalDate dateEnd = LocalDate.parse(strDateEnd);
        long days = ChronoUnit.DAYS.between(dateStart, dateEnd);
        System.out.println(days);
    }
}

Output:

3

ONLINE DEMO

The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.

Learn more about the modern Date-Time API from Trail: Date Time.

Using the legacy API:

Avoid performing calculations yourself if there already exists an API for the same e.g. the following code uses Math#abs and TimeUnit#convert to avoid error-prone if-else and calculations.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws ParseException {
        String strDateStart = "2021-06-09";
        String strDateEnd = "2021-06-12";
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
        Date dateStart = sdf.parse(strDateStart);
        Date dateEnd = sdf.parse(strDateEnd);
        
        long millisInOneDay = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS);
        long days = Math.abs((dateEnd.getTime() - dateStart.getTime()) / millisInOneDay);
        
        System.out.println(days);
    }
}

ONLINE DEMO

After i added throws ParseException, the parse excception still occured, why?

Adding the throws clause to a method forces the caller of the method to either handle the exception using try-catch or rethrow it. It is not a way to prevent the exception from being thrown. Learn more about it from this excellent tutorial from Oracle.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.