The modern answer (valid from 2014 onwards): first I declare a helper method:
private static LocalDateTime parseWithDefaultYear(String stringWithoutYear, int defaultYear) { DateTimeFormatter parseFormatter = new DateTimeFormatterBuilder() .appendPattern("dd MMM HH:mm:ss") .parseDefaulting(ChronoField.YEAR, defaultYear) .toFormatter(Locale.ENGLISH); LocalDateTime dateTime = LocalDateTime.parse(stringWithoutYear, parseFormatter); return dateTime; }
Then we can do:
ZoneId zone = ZoneId.of("America/Argentina/Jujuy"); String stringWithoutYear = "13 Dec 12:00:00"; LocalDateTime now = LocalDateTime.now(zone); int defaultYear = now.getYear(); LocalDateTime dateTime = parseWithDefaultYear(stringWithoutYear, defaultYear); if (dateTime.isAfter(now)) {
When launched today (June 2018), this prints:
2017-12-13T12: 00
You may ask why I want to parse a second time with the new formatter if the first attempt gives a date in the future. Isn’t it easier to subtract 1 year? Although java.time certainly has good support for this, I chose the second parsing to better deal with the corner case on February 29 in leap years. Imagine that the code runs in the first couple of months of 2021, and the line is 29 Feb 12:00:00 . Since 2021 is not a leap year, Java will choose February 28, the last day of the month. Subtracting 1 year will give February 28, 2020, which would be wrong, since 2020 is a leap year. Instead, my new 2020 analysis by default gives the correct value on February 29, 2020.
Messages:
- Although the other answers were good in 2011, the
Date , SimpleDateFormat , Calendar and GregorianCalendar classes are long outdated, so I recommend avoiding them. Modern classes tend to be more programmer friendly and bring fewer unpleasant surprises. - Always indicate the correct time zone. Using the wrong time zone may cause the test for future date-time to be inaccurate, which may lead to the result being rejected for 1 year.
- Always indicate explicit language. In this case, I took "Dec" for the English language and provided
Locale.ENGLISH . Since you consider it safe to assume that this date refers to the last year, I invite you to think about whether, for example, can it also be assumed that this date has occurred in the last 4, 6 or 8 months? If so, checking if this is the case will give you a better check:
if (dateTime.isBefore(now.minusMonths(5))) { throw new IllegalArgumentException("Not within the last 5 months: " + stringWithoutYear); }
source share