0

I'm trying to write 'isPast(String dateStr)' function, which receives date string and returns true if it's in the past and false otherwise.

private static boolean isPast(String dateStr) {
    Calendar c = GregorianCalendar.getInstance();

    int currentYear = c.get(Calendar.YEAR);
    int currentMonth = c.get(Calendar.MONTH);
    int currentDay = c.get(Calendar.DAY_OF_MONTH);
    int currentHour = c.get(Calendar.HOUR_OF_DAY);
    int currentMinute = c.get(Calendar.MINUTE);
    c.set(currentYear, currentMonth, currentDay, currentHour, currentMinute);
    Date now = c.getTime();

    SimpleDateFormat sdfDates = new SimpleDateFormat("dd/m/yyyy");

    Date date = null;
    try {
        date = sdfDates.parse(dateStr);

    } catch (ParseException e) {
        e.printStackTrace();
    }

    if (now.compareTo(date) == 1){
        System.out.println(dateStr + " date given is past");
        return true;
    }
    System.out.println(dateStr + " date given is future");
    return false;
}

And i'm calling it with:

 String str1 = "22/04/2018";
 String str2 = "22/01/2018";
 System.out.println(isPast(str1));
 System.out.println(isPast(str2));

And the output is:

22/04/2018 date given is past
22/01/2018 date given is past

What is going on here? It's not true. I'm on this for too long - it should be simple, obviously i'm missing something with that Calendar object...

jonb
  • 845
  • 1
  • 13
  • 36
  • 4
    `SimpleDateFormat sdfDates = new SimpleDateFormat("dd/M/yyyy");` lower case `m` is minutes. – Elliott Frisch Feb 22 '18 at 22:27
  • 1
    "`if (now.compareTo(date) == 1){`" the contract on `compareTo` is that it returns `<0`, `==0` or `>0`. You shouldn't look for *exactly* 1. – Andy Turner Feb 22 '18 at 22:28
  • 2
    Convert the String to `Date` (preferably `LocalDate`) and use api functionality to test it (ie `before`/`after`) – MadProgrammer Feb 22 '18 at 22:28
  • I was going to recommend before/after methods of Date class after converting String to Date but @MadProgrammer beat me to it :-) – Balwinder Singh Feb 22 '18 at 22:30
  • I’m also not sure what you hope to accomplish with `c.set` and simply passing the values you already extracted back in? – MadProgrammer Feb 22 '18 at 22:32
  • I'm trying to get the current time (Now). If you can suggest me for another way - I'd be glad. Thanks everyone else for the helpfull comments – jonb Feb 22 '18 at 22:38
  • 1
    @JohnSnowTheDeveloper To get current time: `Date now = new Date();` – Andreas Feb 22 '18 at 22:48
  • I'm working with android, the Date constructor is depreached – jonb Feb 22 '18 at 22:49
  • @JohnSnowTheDeveloper I don't see `android` tagged in your question. – Andreas Feb 22 '18 at 22:51
  • My bad, I didn't know the constructor exists in Java, adding tag now – jonb Feb 22 '18 at 22:52
  • @JohnSnowTheDeveloper The `Date()` constructor is not listed as deprecated: https://developer.android.com/reference/java/util/Date.html#Date() – Andreas Feb 22 '18 at 22:53
  • The `Date`, `Calendar` and `SimpleDateFormat` classes are long outdated anyway, and `SimpleDateFormat` in particular notoriously troublesome. Consider adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project and then use [java.time, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) instead of the old classes. – Ole V.V. Feb 23 '18 at 06:02
  • This question has been asked and answered many times already alright; but the linked question misses the problem in this question. Instead this is a duplicate of [Why SimpleDateFormat is giving Month as January instead of October in this case?](https://stackoverflow.com/questions/33454024/why-simpledateformat-is-giving-month-as-january-instead-of-october-in-this-case). – Ole V.V. Feb 23 '18 at 06:18
  • Other times the same question has been asked: (1) [Month in simple date formatter always return JANUARY](https://stackoverflow.com/questions/48184541/month-in-simple-date-formatter-always-return-january). (2) [Month issue in SimpleDateFormat class](https://stackoverflow.com/questions/35645551/month-issue-in-simpledateformat-class). (3) [How can I add one month to change into the milliseconds?](https://stackoverflow.com/questions/48768874/how-can-i-add-one-month-to-change-into-the-milliseconds). – Ole V.V. Feb 23 '18 at 06:22

2 Answers2

4

Use LocalDate that is available in Java 8

  public static void main(String[] args) {

    String str1 = "22/04/2018";
    String str2 = "22/01/2018";
    System.out.println(isPast(str1));
    System.out.println(isPast(str2));
  }


  private static boolean isPast(String dateStr) {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    LocalDate dates = LocalDate.parse(dateStr, formatter);

    return dates.isBefore(LocalDate.now());
  }
Evilguy
  • 306
  • 2
  • 14
  • It's good, but what if I want to consider the hh:mm as well ? DateTimeParse can't parse 23:40 as format hh:mm, do you know how can I overcome it ? – jonb Feb 22 '18 at 22:48
  • 2
    @JohnSnowTheDeveloper Use `LocalDateTime` instead of `LocalDate` and use format string `"dd/MM/yyyy HH:mm"`. – Andreas Feb 22 '18 at 22:49
  • FYI… Much of the java.time functionality is back-ported to Java 6 & 7 in [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/). For earlier Android, the [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP) project adapts *ThreeTen-Backport*. See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Feb 22 '18 at 23:44
0

Try this:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test {
    private static final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    public static void main(String[] args) {

         String str1 = "22/04/2018";
         String str2 = "22/01/2018";
         String str3 = "xx/01/2018";

         Date now = new Date();

         testDate (str1, now);
         testDate (str2, now);
         testDate (str3, now);
    }

    private static void testDate(String str, Date now) {
         try {
            if (sdf.parse(str).before(now)) {
                 System.out.println(str + " is in the past.");
             } else {
                 System.out.println(str + " is in the future.");
             }
        } catch (ParseException e) {
             System.out.println("Date not in format dd/MM/yyyy : " + str);
        } 
    }
}

Output:

22/04/2018 is in the future.
22/01/2018 is in the past.
Date not in format dd/MM/yyyy : xx/01/2018

If you have to use Calendar, try this:

    private static void testDateUsingCalendar (String str, Date now) {
         try {
            String[] split = str.split("/");
            Calendar c = GregorianCalendar.getInstance();

            c.set(Integer.valueOf(split[2]), Integer.valueOf(split[1]), Integer.valueOf(split[0]));
            if (c.getTime().before(now)) {
                 System.out.println(str + " is in the past.");
             } else {
                 System.out.println(str + " is in the future.");
             }
        } catch (Exception e) {
             System.out.println("Date not in format dd/MM/yyyy : " + str);
        } 
    }
Ari Singh
  • 1,228
  • 7
  • 12