-->

Java Generate all dates between x and y [duplicate

2019-01-20 15:09发布

问题:

This question already has an answer here:

  • how to get a list of dates between two dates in java 21 answers

I attempted to generate the date range between date x and date y but failed. I have the same method in c# so I tried to modify it as much as I can but failed to get result. Any idea what I could fix?

private ArrayList<Date> GetDateRange(Date start, Date end) {
    if(start.before(end)) {
        return null;
    }

    int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
    ArrayList<Date> listTemp = new ArrayList<Date>();
    Date tmpDate = start;

    do {
        listTemp.add(tmpDate);
        tmpDate = tmpDate.getTime() + MILLIS_IN_DAY;
    } while (tmpDate.before(end) || tmpDate.equals(end));

    return listTemp;
}

To be honest I was trying to get all the dates starting from january 1st till the end of year 2012 that is december 31st. If any better way available, please let me know. Thanks

回答1:

Joda-Time

Calendar and Date APIs in java are really weird... I strongly suggest to consider jodatime, which is the de-facto library to handle dates. It is really powerful, as you can see from the quickstart: http://joda-time.sourceforge.net/quickstart.html.

This code solves the problem by using Joda-Time:

import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;


public class DateQuestion {

    public static List<DateTime> getDateRange(DateTime start, DateTime end) {

        List<DateTime> ret = new ArrayList<DateTime>();
        DateTime tmp = start;
        while(tmp.isBefore(end) || tmp.equals(end)) {
            ret.add(tmp);
            tmp = tmp.plusDays(1);
        }
        return ret;
    }

    public static void main(String[] args) {

        DateTime start = DateTime.parse("2012-1-1");
        System.out.println("Start: " + start);

        DateTime end = DateTime.parse("2012-12-31");
        System.out.println("End: " + end);

        List<DateTime> between = getDateRange(start, end);
        for (DateTime d : between) {
            System.out.println(" " + d);
        }
    }
}


回答2:

You could use this function:

public static Date addDay(Date date){
   //TODO you may want to check for a null date and handle it.
   Calendar cal = Calendar.getInstance();
   cal.setTime (date);
   cal.add (Calendar.DATE, 1);
   return cal.getTime();
}

Found here. And what is the reason of fail? Why you think that your code is failed?



回答3:

java.time

The other Answers are outmoded as of Java 8.

The old date-time classes bundled with earlier versions of Java have been supplanted with the java.time framework built into Java 8 and later. See Tutorial.

LocalDate (date-only)

If you care only about the date without the time-of-day, use the LocalDate class. The LocalDate class represents a date-only value, without time-of-day and without time zone.

LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ;
LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;

To get the current date, specify a time zone. For any given moment, today’s date varies by time zone. For example, a new day dawns earlier in Paris than in Montréal.

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );

We can use the isEqual, isBefore, and isAfter methods to compare. In date-time work we commonly use the Half-Open approach where the beginning of a span of time is inclusive while the ending is exclusive.

List<LocalDate> localDates = new ArrayList<>();
LocalDate localDate = start;
while ( localDate.isBefore( stop ) ) {
    localDates.add( localDate );
    // Set up the next loop.
    localDate = localDate.plusDays( 1 );
}

Instant (date-time)

If you have old java.util.Date objects, which represent both a date and a time, convert to the Instant class. An Instant is a moment on the timeline in UTC.

Instant startInstant = juDate_Start.toInstant();
Instant stopInstant = juDate_Stop.toInstant();

From those Instant objects, get LocalDate objects by:

  • Applying the time zone that makes sense for your context to get ZonedDateTime object. This object is the very same moment on the timeline as the Instant but with a specific time zone assigned.
  • Convert the ZonedDateTime to a LocalDate.

We must apply a time zone as a date only has meaning within the context of a time zone. As we said above, for any given moment the date varies around the world.

Example code.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate start = ZonedDateTime.ofInstant( startInstant , zoneId ).toLocalDate();
LocalDate stop = ZonedDateTime.ofInstant( stopInstant , zoneId ).toLocalDate();


回答4:

You can use joda-time.

Days.daysBetween(fromDate, toDate);

Found at joda-time homepage.

similar question in stackoverflow with some good answers.



回答5:

Look at the Calendar API, particularly Calendar.add().