SimpleDateFormat but with current or next year

Viewed 91

I'm trying to adjust my method and accept current year or next if the second part of date is next year.

My code:

    private static final String PERIOD = "24 Dec-2 Jan";
    private static DateRange _period = null;

    public static void main(final String[] args)
    {
        _period = DateRange.parse(PERIOD, new SimpleDateFormat("dd MMM", Locale.US));
    }

And the parse method:

    public static DateRange parse(final String dateRange, final DateFormat format)
    {
        final String[] date = dateRange.split("-");

        if (date.length == 2)
        {
            try
            {
                final Date startDate = format.parse(date[0]);
                final Date endDate = format.parse(date[1]);

                return new DateRange(startDate, endDate);
            }
            catch (final ParseException e)
            {
                _log.log(Level.WARNING, "Invalid Date Format.", e);
            }
        }

        return new DateRange(null, null);
    }

So after i execute the code i want to have _startDate to show 24 Dec 2020 and _endDate to show 4 JAN 2021 since is in next year

Edit: Current it print this:

Thu Dec 24 00:00:00 EET 1970
Fri Jan 02 00:00:00 EET 1970

While i need this

Thu Dec 24 00:00:00 EET 2020
Fri Jan 02 00:00:00 EET 2021
1 Answers

Updated to use Java 8 date APIs. You can find a pre-Java8 version in the revision history.

You can use Java 8 date APIs to parse a MonthDay (a partial date), set it to the current year (with LocalDate), and then adjust the years to move the date range to the earliest valid range in the future.

public static DateRange parse(final String dateRange, final DateTimeFormatter formatter) {
    final String[] dates = dateRange.split("-");
    if (dates.length == 2) {
        try {
            final LocalDate now = LocalDate.now();
            final int currentYear = now.getYear();
            int startYear = currentYear, endYear = currentYear;
            // Parse partial dates (MonthDay) and set the year to the current year.
            LocalDate startDate = MonthDay.parse(dates[0], formatter).atYear(currentYear);
            LocalDate endDate = MonthDay.parse(dates[1], formatter).atYear(currentYear);
            // Increment both years if the start is in the past.
            if (startDate.isBefore(now)) {
                startYear++;
                endYear++;
            }
            // Increment the end year if the end is before the start.
            if (endDate.isBefore(startDate)) {
                endYear++;
            }
            // Update dates with the years.
            startDate = startDate.withYear(startYear);
            endDate = endDate.withYear(endYear);
            return new DateRange(startDate, endDate);
        } catch (DateTimeParseException e) {
            _log.log(Level.WARNING, "Invalid Date Format.", e);
        }
    }
    return null;
}

public static void main(String[] args) {
    final String dateString = "24 Feb-2 Jan";
    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMM", Locale.US);
    final DateRange dateRange = parse(dateString, formatter);
    System.out.println(dateRange);
}

Note that the format is d MMM instead of dd MMM to support single digit days.


Alternatively, if you need to support date strings that include years, you can use a LocalDate solution, and add a default year in the formatter parameter.

public static void main(String[] args) {
    final String dateString = "24 Feb-2 Jan";
    final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("d MMM")
            .parseDefaulting(ChronoField.YEAR, Year.now().getValue())
            .toFormatter(Locale.US);
    final DateRange dateRange = parse(dateString, formatter);
    System.out.println(dateRange);
}

public static DateRange parse(final String dateRange, final DateTimeFormatter formatter) {
    final String[] dates = dateRange.split("-");
    if (dates.length == 2) {
        try {
            final LocalDate now = LocalDate.now();
            final int currentYear = now.getYear();
            int startYear = currentYear, endYear = currentYear;
            // Parse partial dates (MonthDay) and set the year to the current year.
            LocalDate startDate = LocalDate.parse(dates[0], formatter);
            LocalDate endDate = LocalDate.parse(dates[1], formatter);
            // Increment both years if the start is in the past.
            if (startDate.isBefore(now)) {
                startYear++;
                endYear++;
            }
            // Increment the end year if the end is before the start.
            if (endDate.isBefore(startDate)) {
                endYear++;
            }
            // Update dates with the years.
            startDate = startDate.withYear(startYear);
            endDate = endDate.withYear(endYear);
            return new DateRange(startDate, endDate);
        } catch (DateTimeParseException e) {
            _log.log(Level.WARNING, "Invalid Date Format.", e);
        }
    }
    return null;
}
Related