Je veux une liste de dates entre la date de début et la date de fin.
Le résultat devrait être une liste de toutes les dates, y compris les dates de début et de fin.
En 2010, j'ai suggéré d'utiliser Joda-Time pour cela.
Notez que Joda-Time est maintenant en mode maintenance. Depuis 1.8 (2014), vous devriez utiliser
Java.time
.
Ajoutez un jour à la fois jusqu'à la date de fin:
int days = Days.daysBetween(startDate, endDate).getDays();
List<LocalDate> dates = new ArrayList<LocalDate>(days); // Set initial capacity to `days`.
for (int i=0; i < days; i++) {
LocalDate d = startDate.withFieldAdded(DurationFieldType.days(), i);
dates.add(d);
}
Il ne serait pas trop difficile de mettre en œuvre votre propre itérateur pour le faire également, ce serait encore mieux.
Si vous utilisez Java 8 , il existe une approche beaucoup plus propre. Le nouveau package Java.time de Java 8 intègre les fonctionnalités de l'API Joda-Time .
Votre besoin peut être résolu en utilisant le code ci-dessous:
String s = "2014-05-01";
String e = "2014-05-10";
LocalDate start = LocalDate.parse(s);
LocalDate end = LocalDate.parse(e);
List<LocalDate> totalDates = new ArrayList<>();
while (!start.isAfter(end)) {
totalDates.add(start);
start = start.plusDays(1);
}
Obtenez le nombre de jours entre les dates, inclus.
public static List<Date> getDaysBetweenDates(Date startdate, Date enddate)
{
List<Date> dates = new ArrayList<Date>();
Calendar calendar = new GregorianCalendar();
calendar.setTime(startdate);
while (calendar.getTime().before(enddate))
{
Date result = calendar.getTime();
dates.add(result);
calendar.add(Calendar.DATE, 1);
}
return dates;
}
Voici la façon dont Java 8 utilise des flux et Joda-Time .
List<LocalDate> daysRange = Stream.iterate(startDate, date -> date.plusDays(1)).limit(numOfDays).collect(toList());
Vous pouvez faire la même chose avec le framework Java.time intégré à Java 8 et versions ultérieures, en utilisant sa classe LocalDate
.
s'il vous plaît trouver le code ci-dessous.
List<Date> dates = new ArrayList<Date>();
String str_date ="27/08/2010";
String end_date ="02/09/2010";
DateFormat formatter ;
formatter = new SimpleDateFormat("dd/MM/yyyy");
Date startDate = (Date)formatter.parse(str_date);
Date endDate = (Date)formatter.parse(end_date);
long interval = 24*1000 * 60 * 60; // 1 hour in millis
long endTime =endDate.getTime() ; // create your endtime here, possibly using Calendar or Date
long curTime = startDate.getTime();
while (curTime <= endTime) {
dates.add(new Date(curTime));
curTime += interval;
}
for(int i=0;i<dates.size();i++){
Date lDate =(Date)dates.get(i);
String ds = formatter.format(lDate);
System.out.println(" Date is ..." + ds);
}
sortie:
La date est ... 27/08/2010
La date est ... 28/08/2010
La date est ... 29/08/2010
La date est ... 30/08/2010
La date est ... 31/08/2010
La date est ... 01/09/2010
La date est ... 02/09/2010
Avec Lamma cela ressemble à ceci en Java:
for (Date d: Dates.from(2014, 6, 29).to(2014, 7, 1).build()) {
System.out.println(d);
}
et le résultat est:
Date(2014,6,29)
Date(2014,6,30)
Date(2014,7,1)
Quelque chose comme ça devrait fonctionner:
private List<Date> getListOfDaysBetweenTwoDates(Date startDate, Date endDate) {
List<Date> result = new ArrayList<Date>();
Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
end.setTime(endDate);
end.add(Calendar.DAY_OF_YEAR, 1); //Add 1 day to endDate to make sure endDate is included into the final list
while (start.before(end)) {
result.add(start.getTime());
start.add(Calendar.DAY_OF_YEAR, 1);
}
return result;
}
Dans Java 9 , vous pouvez utiliser la nouvelle méthode suivante, LocalDate::datesUntil
:
LocalDate start = LocalDate.of(2017, 2, 1);
LocalDate end = LocalDate.of(2017, 2, 28);
Stream<LocalDate> dates = start.datesUntil(end.plusDays(1));
List<LocalDate> list = dates.collect(Collectors.toList());
La nouvelle méthode datesUntil(...)
fonctionne avec une date de fin exclusive, d’où le bidouillage indiqué pour ajouter un jour.
Une fois que vous avez obtenu un flux, vous pouvez exploiter toutes les fonctionnalités offertes par les packages Java.util.stream
- ou Java.util.function
-. Travailler avec des flux est devenu si simple comparé aux précédentes approches basées sur des boucles for ou while bien personnalisées.
Ou si vous recherchez une solution basée sur le flux qui fonctionne par défaut avec des dates incluses mais peut également être configurée autrement, vous pouvez trouver la classe DateInterval dans ma bibliothèque Time4J caractéristiques autour des flux de données, y compris un séparateur performant plus rapide que dans Java-9:
PlainDate start = PlainDate.of(2017, 2, 1);
PlainDate end = start.with(PlainDate.DAY_OF_MONTH.maximized());
Stream<PlainDate> stream = DateInterval.streamDaily(start, end);
Ou encore plus simple en cas de mois complet:
Stream<PlainDate> februaryDates = CalendarMonth.of(2017, 2).streamDaily();
List<LocalDate> list =
februaryDates.map(PlainDate::toTemporalAccessor).collect(Collectors.toList());
Une solution serait de créer une instance Calendar
et de démarrer un cycle en augmentant le champ Calendar.DATE
jusqu'à ce qu'il atteigne la date souhaitée. En outre, à chaque étape, vous devez créer une instance Date
(avec les paramètres correspondants) et la mettre dans votre liste.
Un code sale:
public List<Date> getDatesBetween(final Date date1, final Date date2) {
List<Date> dates = new ArrayList<Date>();
Calendar calendar = new GregorianCalendar() {{
set(Calendar.YEAR, date1.getYear());
set(Calendar.MONTH, date1.getMonth());
set(Calendar.DATE, date1.getDate());
}};
while (calendar.get(Calendar.YEAR) != date2.getYear() && calendar.get(Calendar.MONTH) != date2.getMonth() && calendar.get(Calendar.DATE) != date2.getDate()) {
calendar.add(Calendar.DATE, 1);
dates.add(new Date(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE)));
}
return dates;
}
Comme @folone, mais correct
private static List<Date> getDatesBetween(final Date date1, final Date date2) {
List<Date> dates = new ArrayList<>();
Calendar c1 = new GregorianCalendar();
c1.setTime(date1);
Calendar c2 = new GregorianCalendar();
c2.setTime(date2);
int a = c1.get(Calendar.DATE);
int b = c2.get(Calendar.DATE);
while ((c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) || (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) || (c1.get(Calendar.DATE) != c2.get(Calendar.DATE))) {
c1.add(Calendar.DATE, 1);
dates.add(new Date(c1.getTimeInMillis()));
}
return dates;
}
Avec Joda-Time , peut-être que c'est mieux:
LocalDate dateStart = new LocalDate("2012-01-15");
LocalDate dateEnd = new LocalDate("2012-05-23");
// day by day:
while(dateStart.isBefore(dateEnd)){
System.out.println(dateStart);
dateStart = dateStart.plusDays(1);
}
C'est ma solution .... très facile :)
public static List<Date> getDaysBetweenDates(Date startDate, Date endDate){
ArrayList<Date> dates = new ArrayList<Date>();
Calendar cal1 = Calendar.getInstance();
cal1.setTime(startDate);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(endDate);
while(cal1.before(cal2) || cal1.equals(cal2))
{
dates.add(cal1.getTime());
cal1.add(Calendar.DATE, 1);
}
return dates;
}
List<Date> dates = new ArrayList<Date>();
String str_date = "DD/MM/YYYY";
String end_date = "DD/MM/YYYY";
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date startDate = (Date)formatter.parse(str_date);
Date endDate = (Date)formatter.parse(end_date);
long interval = 1000 * 60 * 60; // 1 hour in milliseconds
long endTime = endDate.getTime() ; // create your endtime here, possibly using Calendar or Date
long curTime = startDate.getTime();
while (curTime <= endTime) {
dates.add(new Date(curTime));
curTime += interval;
}
for (int i = 0; i < dates.size(); i++){
Date lDate = (Date)dates.get(i);
String ds = formatter.format(lDate);
System.out.println("Date is ..." + ds);
//Write your code for storing dates to list
}
Avec Java 8
public Stream<LocalDate> getDaysBetween(LocalDate startDate, LocalDate endDate) {
return IntStream.range(0, (int) DAYS.between(startDate, endDate)).mapToObj(startDate::plusDays);
}
Vous pouvez également consulter l'API Date.getTime () . Cela donne une longueur à laquelle vous pouvez ajouter votre incrément. Puis créez une nouvelle date.
List<Date> dates = new ArrayList<Date>();
long interval = 1000 * 60 * 60; // 1 hour in millis
long endtime = ; // create your endtime here, possibly using Calendar or Date
long curTime = startDate.getTime();
while (curTime <= endTime) {
dates.add(new Date(curTime));
curTime += interval;
}
et peut-être Apache commons a-t-il quelque chose comme ceci dans DateUtils, ou peut-être ont-ils aussi un CalendarUtils :)
MODIFIER
inclure le début et le date de fin peut ne pas être possible si votre intervalle n'est pas parfait :)
C'est une solution simple pour obtenir une liste de dates
import Java.io.*;
import Java.util.*;
import Java.text.SimpleDateFormat;
public class DateList
{
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
public static void main (String[] args) throws Java.lang.Exception
{
Date dt = new Date();
System.out.println(dt);
List<Date> dates = getDates("2017-01-01",dateFormat.format(new Date()));
//IF you don't want to reverse then remove Collections.reverse(dates);
Collections.reverse(dates);
System.out.println(dates.size());
for(Date date:dates)
{
System.out.println(date);
}
}
public static List<Date> getDates(String fromDate, String toDate)
{
ArrayList<Date> dates = new ArrayList<Date>();
try {
Calendar fromCal = Calendar.getInstance();
fromCal.setTime(dateFormat .parse(fromDate));
Calendar toCal = Calendar.getInstance();
toCal.setTime(dateFormat .parse(toDate));
while(!fromCal.after(toCal))
{
dates.add(fromCal.getTime());
fromCal.add(Calendar.DATE, 1);
}
} catch (Exception e) {
System.out.println(e);
}
return dates;
}
}
Améliorer l'une des solutions ci-dessus. Comme l'ajout d'un jour à la date de fin ajoute parfois un jour au-delà de la date de fin.
Liste statique publique getDaysBetweenDates (Date de début à la date, Date de fin à la date) { Liste des dates = new ArrayList (); Calendrier startDay = new GregorianCalendar (); calendar.setTime (startdate); Calendar endDay = new GregorianCalendar (); endDay.setTime (enddate); endDay.add (Calendar.DAY_OF_YEAR, 1); endDay.set (Calendar.HOUR_OF_DAY, 0); endDay.set (Calendar.MINUTE, 0); endDay.set (Calendar.SECOND, 0); endDay.set (Calendar.MILLISECOND, 0); while (calendar.getTime (). before (endDay.getTime ())) { Date résultat = startDay.getTime (); dates.add (résultat); startDay.add (Calendar.DATE, 1); } dates de retour; }
Une version queue-récursive:
public static void datesBetweenRecursive(Date startDate, Date endDate, List<Date> dates) {
if (startDate.before(endDate)) {
dates.add(startDate);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
calendar.add(Calendar.DATE, 1);
datesBetweenRecursive(calendar.getTime(), endDate, dates);
}
}
Voici ma méthode pour obtenir des dates entre deux dates, y compris/w.o. y compris les jours ouvrables. Il prend également la source et le format de date souhaité en paramètre.
public static List<String> getAllDatesBetweenTwoDates(String stdate,String enddate,String givenformat,String resultformat,boolean onlybunessdays) throws ParseException{
DateFormat sdf;
DateFormat sdf1;
List<Date> dates = new ArrayList<Date>();
List<String> dateList = new ArrayList<String>();
SimpleDateFormat checkformat = new SimpleDateFormat(resultformat);
checkformat.applyPattern("EEE"); // to get Day of week
try{
sdf = new SimpleDateFormat(givenformat);
sdf1 = new SimpleDateFormat(resultformat);
stdate=sdf1.format(sdf.parse(stdate));
enddate=sdf1.format(sdf.parse(enddate));
Date startDate = (Date)sdf1.parse( stdate);
Date endDate = (Date)sdf1.parse( enddate);
long interval = 24*1000 * 60 * 60; // 1 hour in millis
long endTime =endDate.getTime() ; // create your endtime here, possibly using Calendar or Date
long curTime = startDate.getTime();
while (curTime <= endTime) {
dates.add(new Date(curTime));
curTime += interval;
}
for(int i=0;i<dates.size();i++){
Date lDate =(Date)dates.get(i);
String ds = sdf1.format(lDate);
if(onlybunessdays){
String day= checkformat.format(lDate);
if(!day.equalsIgnoreCase("Sat") && !day.equalsIgnoreCase("Sun")){
dateList.add(ds);
}
}else{
dateList.add(ds);
}
//System.out.println(" Date is ..." + ds);
}
}catch(ParseException e){
e.printStackTrace();
throw e;
}finally{
sdf=null;
sdf1=null;
}
return dateList;
}
Et l'appel de méthode ressemblerait à ceci:
public static void main(String aregs[]) throws Exception {
System.out.println(getAllDatesBetweenTwoDates("2015/09/27","2015/10/05","yyyy/MM/dd","dd-MM-yyyy",false));
}
Vous pouvez trouver le code de démonstration: Cliquez ici
Cela ajoutera toutes les dates entre deux dates et ajoutera des dates actuelles, puis de nouvelles dates seront ajoutées en fonction de la condition de boucle.
private void onDateSet(){
Calendar endDate = Calendar.getInstance(),startDate = Calendar.getInstance();
startDate.set(currentYear,currentMonthOfYear,currentDayOfMonth);
endDate.set(inputYear,inputMonthOfYear,inputDayOfMonth);
datesToAdd(startDate,endDate);
}
//call for get dates list
private List<Date> datesToAdd(Calendar startDate,Calendar endDate){
List<Dates> datesLists = new List<>();
while (startDate.get(Calendar.YEAR) != endDate.get(Calendar.YEAR) ||
startDate.get(Calendar.MONTH) != endDate.get(Calendar.MONTH) ||
startDate.get(Calendar.DAY_OF_MONTH) != endDate.get(Calendar.DAY_OF_MONTH)) {
datesList.add(new Date(startDate.get(Calendar.YEAR), startDate.get(Calendar.MONTH), startDate.get(Calendar.DATE));
startDate.add(Calendar.DATE, 1);//increas dates
}
return datesList;
}
List<LocalDate> totalDates = new ArrayList<>();
popularDatas(startDate, endDate, totalDates);
System.out.println(totalDates);
private void popularDatas(LocalDate startDate, LocalDate endDate, List<LocalDate> datas) {
if (!startDate.plusDays(1).isAfter(endDate)) {
popularDatas(startDate.plusDays(1), endDate, datas);
}
datas.add(startDate);
}
Solution récursive