Comparing dates with months as strings

848 Views Asked by At

I am trying to compare these two dates :

17 Oct. 2019 (08:23)
19 déc. 2019 (21:15)

The months are in French and the main problem is the months. Do I need to put an if statement for every type of month so I can switch it with the appropriate month? For example:

if (MonthValue.equals("oct."){
    DateValue.replace("oct.","10");
}

Or is there an easier solution, because I need to check in a table if the first value is bigger than the second one.

Edit : My new Code :

String target1 = "17 oct. 2019 (08:23)";
        String target2 = "19 déc. 2019 (21:15)";
        DateFormat df = new SimpleDateFormat("dd MMM. YYYY (kk:mm)", Locale.FRENCH);
        Date result =  df.parse(target1);  
        Date result2 =  df.parse(target2); 
        System.out.println(result);
        System.out.println(result2);
        if(result.compareTo(result2) < 0) {
            System.out.println("true");
        }
        else {
            System.out.println("false");
        }

Doesn't work gives this error:

java.text.ParseException: Unparseable date: "17 oct. 2019 (08:23)"
5

There are 5 best solutions below

0
Anonymous On BEST ANSWER

java.time and optional parts in the format pattern string

Like the others I recommend that you use java.time, the modern Java date and time API, for your date and time work. I understand that if your month names are five letters or shorter (for example avril), they are written out in full, whereas if they are seven letters or longer (for example juillet), they are abbreviated. The following formatter can parse in both situations:

private static final DateTimeFormatter DATE_FORMATTER
        = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .appendPattern("dd [MMMM][MMM] uuuu (HH:mm)")
                .toFormatter(Locale.FRENCH);    

Square brackets [] in the format pattern string surround optional parts. MMMM is for full month name. MMM is for the abbreviation. So the point in [MMMM][MMM] is that it will successfully parse either full month name or abbreviations and just skip the one that doesn’t work. Since you gave an example of Oct. being written with an upper case O, I have also specified that the parsing should not be sensitive to case. If this is not necessary, you may use this simpler formatter:

private static final DateTimeFormatter DATE_FORMATTER
        = DateTimeFormatter.ofPattern("dd [MMMM][MMM] uuuu (HH:mm)", Locale.FRENCH);

In order to check that all months work, I have set up these test data:

    String[] dateStrings = {
            "17 Oct. 2019 (08:23)",
            "19 déc. 2019 (21:15)",
            "01 avril 2021 (09:40)",
            "08 janv. 2020 (01:18)",
            "28 févr. 2021 (21:41)",
            "03 mars 2020 (22:54)",
            "06 mai 2020 (03:14)",
            "21 juin 2020 (07:15)",
            "18 juil. 2020 (23:06)",
            "06 août 2020 (22:28)",
            "29 sept. 2020 (06:04)",
            "18 nov. 2019 (01:35)"
    };

To parse and compare two of them use LocalDateTime.parse() and .isBefore():

    LocalDateTime dateTime1 = LocalDateTime.parse(dateStrings[1], DATE_FORMATTER);
    LocalDateTime dateTime2 = LocalDateTime.parse(dateStrings[2], DATE_FORMATTER);
    if (dateTime1.isBefore(dateTime2)) {
        System.out.format(Locale.FRENCH, "%s is before %s%n", dateTime1, dateTime2);
    }

Output:

2019-12-19T21:15 is before 2021-04-01T09:40

For comparison you may also exploit the fact that LocalDateTime implements Comparable. This is practical when sorting the dates and times, for example. As a brief example let’s sort all the LocalDateTime objects that come out of parsing the above strings:

    Arrays.stream(dateStrings)
            .map(ds -> LocalDateTime.parse(ds, DATE_FORMATTER))
            .sorted()
            .forEach(System.out::println);
2019-10-17T08:23
2019-11-18T01:35
2019-12-19T21:15
2020-01-08T01:18
2020-03-03T22:54
2020-05-06T03:14
2020-06-21T07:15
2020-07-18T23:06
2020-08-06T22:28
2020-09-29T06:04
2021-02-28T21:41
2021-04-01T09:40

Link: Trail: Date Time (The Java™ Tutorials) explaining how to use java.time.

4
Puce On

My recommendation:

1
Muhammad Tahir Ali On

What I've got from your question is that you want to convert Month's names to their respective numbers. If this is the case, then you should try switch
Example:

switch (MonthValue){
    case jan:
      MonthValue = 1; // Set Month variable to it Numbered Position (type casting might be required)
      break;
    case feb:
      MonthValue = 2;
      break;
    default:
      System.out.println("Somthing...");
}
7
zephyr On

Using DateTimeFormatter with pattern dd MMM yyyy (HH:mm) to parse the date string like this

String target1 = "17 oct. 2019 (08:23)";
String target2 = "19 déc. 2019 (21:15)";

Locale locale = Locale.FRANCE;
DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder().appendPattern("dd MMM yyyy (HH:mm)")
        .toFormatter(locale);
LocalDateTime dateTime1 = LocalDateTime.parse(target1, dateTimeFormatter);
LocalDateTime dateTime2 = LocalDateTime.parse(target2, dateTimeFormatter);

System.out.println(dateTime1);
System.out.println(dateTime2);
if (dateTime1.compareTo(dateTime2) < 0) {
    System.out.println("true");
} else {
    System.out.println("false");
}
2
Samraj Edwin Samuel On

Try encoding to UTF8, which will avoid DateTimeParseException Exception in thread "main" java.time.format.DateTimeParseException: Text '19 d??c. 2019 (21:15)' could not be parsed at index 3

    public static void main(String args[]) throws Exception {
        String date1 = "17 oct. 2019 (08:23)";
        String date2 = "19 déc. 2019 (21:15)";
        
        DateTimeFormatter longDateTimeFormatter = DateTimeFormatter.ofPattern("dd MMM yyyy (HH:mm)").withLocale(Locale.FRENCH);
        LocalDateTime lclDate1 = LocalDateTime.parse(encodeUTF8(date1), longDateTimeFormatter);
        LocalDateTime lclDate2 = LocalDateTime.parse(encodeUTF8(date2), longDateTimeFormatter);
        if (lclDate1.compareTo(lclDate2) < 0) {
            System.out.println("true");
        }
        else {
            System.out.println("false");
        }
    }
    
    public static String encodeUTF8(String dateStr) {
        byte[] bytes = dateStr.getBytes();
        String utf8EncodStr = new String(bytes, StandardCharsets.UTF_8);
        return utf8EncodStr;
    }