I want a list of dates between start date and end date.
The result should be a list of all dates including the start and end date.
java.time Package
If you are using Java 8, there is a much cleaner approach. The new java.time package in Java 8 incorporates the features of the Joda-Time API.
Your requirement can be solved using the below code:
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);
}
Back in 2010, I suggested to use Joda-Time for that.
Note that Joda-Time is now in maintenance mode. Since 1.8 (2014), you should use java.time.
Add one day at a time until reaching the end date:
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);
}
It wouldn't be too hard to implement your own iterator to do this as well, that would be even nicer.
Get the number of days between dates, inclusive.
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;
}
Streams
Edit: Joda-Time is now deprecated, changed the answer to use Java 8 instead.
Here is the Java 8 way, using streams.
List<LocalDate> daysRange = Stream.iterate(startDate, date -> date.plusDays(1)).limit(numOfDays).collect(Collectors.toList());
please find the below code.
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);
}
output:
Date is ...27/08/2010
Date is ...28/08/2010
Date is ...29/08/2010
Date is ...30/08/2010
Date is ...31/08/2010
Date is ...01/09/2010
Date is ...02/09/2010
Recommending date streams
In Java 9, you can use following new method, 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());
The new method datesUntil(...) works with an exclusive end date, hence the shown hack to add a day.
Once you have obtained a stream you can exploit all the features offered by java.util.stream- or java.util.function-packages. Working with streams has become so simple compared with earlier approaches based on customized for- or while-loops.
Or if you look for a stream-based solution which operates on inclusive dates by default but can also be configured otherwise then you might find the class DateInterval in my library Time4J interesting because it offers a lot of special features around date streams including a performant spliterator which is faster than in 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);
Or even simpler in case of full months:
Stream<PlainDate> februaryDates = CalendarMonth.of(2017, 2).streamDaily();
List<LocalDate> list =
februaryDates.map(PlainDate::toTemporalAccessor).collect(Collectors.toList());
With java 8
public Stream<LocalDate> getDaysBetween(LocalDate startDate, LocalDate endDate) {
return IntStream.range(0, (int) DAYS.between(startDate, endDate)).mapToObj(startDate::plusDays);
}
Something like this should definitely work:
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;
}
With Lamma it looks like this in Java:
for (Date d: Dates.from(2014, 6, 29).to(2014, 7, 1).build()) {
System.out.println(d);
}
and the output is:
Date(2014,6,29)
Date(2014,6,30)
Date(2014,7,1)
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;
}
One solution would be to create a Calendar instance, and start a cycle, increasing it's Calendar.DATE field until it reaches the desired date. Also, on each step you should create a Date instance (with corresponding parameters), and put it to your list.
Some dirty code:
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;
}
You can also look at the Date.getTime() API. That gives a long to which you can add your increment. Then create a new 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;
}
and maybe apache commons has something like this in DateUtils, or perhaps they have a CalendarUtils too :)
EDIT
including the start and enddate may not be possible if your interval is not perfect :)
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
}
Like as #folone, but 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;
}
With Joda-Time , maybe it's better:
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);
}
It's my solution.... very easy :)
This is simple solution for get a list of 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;
}
}
As of Java 9, you can use the datesUntil method on LocalDate:
public List<LocalDate> getDatesBetween(
LocalDate startDate, LocalDate endDate) {
return startDate.datesUntil(endDate)
.collect(Collectors.toList());
}
The LocalDateRange class in the ThreeTen-Extra library represents a range of dates, and can be used for this purpose:
LocalDateRange.ofClosed(startDate, endDate).stream().toList();
A tail-recursive version:
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);
}
}
Enhancing one of the above solutions. As adding 1 day to end date sometimes adds an extra day beyond the end date.
public static List getDaysBetweenDates(Date startdate, Date enddate)
{
List dates = new ArrayList();
Calendar 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 result = startDay.getTime();
dates.add(result);
startDay.add(Calendar.DATE, 1);
}
return dates;
}
Here is my method for getting dates between two dates, including / w.o. including business days. It also takes source and desired date format as parameter.
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;
}
And the method call would be like :
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));
}
You can find the demo code : Click Here
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);
}
Recursive solution
This will add all dates between two dates and It will add current dates and then new dates will be added based on loop condition.
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;
}
What i am trying to do is display the response from a POST message on to the HTML loaded in my webview. However, the my webview appears blank. I can see the response message by in LogCat by printing it out. However, again my webview appears blank. Example.html is the page loading in my webview. My implementation is below:
private void startSchedule()
{
for(int i=0;i<temPojoData.size();i++)
{
tempPojo tem =temPojoData.get(i);
/////////////////////// Daily and AllDays functionality start here //////////////////
if(tem.getDaysweekmonth().equals("Daily") )
{
if(tem.getDaysbases().equals("AllDays")) {
if (findDateBTwoDates(tem.getStartDate(), tem.getEndDate())) {
Log.i("Daily Date", "Today Available");
layoutID += tem.getLayout();
}
}else if(tem.getDaysbases().equals("Whole Day")){
}else if(tem.getDaysbases().equals("Morning"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("After Noon"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("Evening"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("Night"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("Choose Time"))
{ scheduleStartTimes.add(tem.getStartTime());
}
}
/////////////////////// Weekly and AllDays functionality start here //////////////////
else if(tem.getDaysweekmonth().equals("weekly") && tem.getDaysbases().equals("AllDays"))
{
if(tem.getDaysbases().equals("AllDays")) {
}
}
/////////////////////// Monthly and AllDays functionality start here //////////////////
else if(tem.getDaysweekmonth().equals("montly") && tem.getDaysbases().equals("AllDays"))
{
if(tem.getDaysbases().equals("AllDays")) {
}
}
}
}
private void findTimeBTwoTimes(String sTime,String eTime)
{
try {
String string1 = "20:11:13";
Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
String string2 = "14:49:00";
Date time2 = new SimpleDateFormat("HH:mm:ss").parse(string2);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time2);
calendar2.add(Calendar.DATE, 1);
String someRandomTime = "01:00:00";
Date d = new SimpleDateFormat("HH:mm:ss").parse(someRandomTime);
Calendar calendar3 = Calendar.getInstance();
calendar3.setTime(d);
calendar3.add(Calendar.DATE, 1);
Date x = calendar3.getTime();
if (x.after(calendar1.getTime()) && x.before(calendar2.getTime())) {
//checkes whether the current time is between 14:49:00 and 20:11:13.
System.out.println(true);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
private boolean findDateBTwoDates(String sDate,String eDate)
{
try {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String s = sDate.replace(" AM","");
String e = eDate.replace(" AM","");
String oeStartDateStr =sDate.replace("PM","");
String oeEndDateStr =eDate.replace("PM","");
Log.i("Start End Date ",sDate+"------------"+eDate);
Calendar cal = Calendar.getInstance();
Integer year = cal.get(Calendar.YEAR);
Date startDate = sdf.parse(oeStartDateStr);
Date endDate = sdf.parse(oeEndDateStr);
Date d = new Date();
String currDt = sdf.format(d);
if ((d.after(startDate) && (d.before(endDate))) || (currDt.equals(sdf.format(startDate)) || currDt.equals(sdf.format(endDate)))) {
System.out.println("Date is between 1st april to 14th nov...");
return true;
}
/*else {
System.out.println("Date is not between 1st april to 14th nov...");
}*/
}catch (Exception e){}
return false;
}
I will explain this in a sudo code so that you can come up with a solution.
The first point to your answer is that -> No, you cannot do it in a straightforward manner. The reason behind this is that MongoDB does not have/support joins. Like in SQL where you can join two tables and query them for conditional results; the same is not doable in MongoDB.
But do not lose hope. You cannot do a join on the DB side but you can certainly come up with a solution on the driver/application side. What I would suggest you to do is as follows. (I am using the JAVA driver and Morphia so my solutions' arrangement may look specific to them)
Have a DAO interface for both collections seperately
public interface MyDAO1 extends DAO<MyClass1, ObjectId>
{
public MyClass1 getByName(String name);
}
public interface MyDAO2 extends DAO<MyClass2, ObjectId>
{
public MyClass2 getByResult(int result);
}
First make implementation classes for both the above interfaces. That's pretty simple so I am skipping it to move on to the real part. Have an implementation of the interface
public class MyDAOImpl extends BasicDAO<MyClass, ObjectId> implements MyDAO1, MyDAO2
{
public MyClass1 getByName (String name)
{
MyClass1 output= query collection1 with with the Name;
return output;
}
public MyClass2 getByResult (int result)
{
MyClass2 output= query collection2 with with the result;
return output;
}
public void getByNameResult (String name, int result)
{
MyClass1 output1 = getByName (name);
MyClass2 output2 = getByResult (result);
print them in however format you want OR create a string;
}
}
please note:
MyClass1 is the #Entity class for the employee collection
MyClass2 is the #Entity class for the result collection
I am trying to build a CellTable Widget for time tracking. The first Column must represent all days for current month in following form
Fri, 1
Sat, 2
Sun, 3
Mon, 4
Tue, 5
…
etc. till the end of the month (28 -31 rows).
My code looks like that:
Column<Rec,String> dayColumn = new Column<Rec,String>(new TextCell())
{
#Override
public String getValue(Rec rec)
{
dayNr = DateTimeFormat.getFormat( "EE,d" ).format(new Date());
return dayNr;
}
};
table.addColumn(dayColumn, "Date");
So can I see in this Column only Today-date in all cells.
How can I get all days of the month (1...28/30/31) in this Column each in its own cell?
It would be ideal if you prepared the list of Rec items with a Date variable.
Declaring a Rec pojo with date
Class Rec{
Date date;
//getter and setters.
}
Populate list of Rec items
List<Rec> recItems = new ArrayList<Rec>();
Date now = new Date();
int nowMonth = now.getMonth();
int nowYear = now.getYear();
List<Date> listOfDatesInThisMonth = new ArrayList<Date>();
Date beginningOfMonth = new Date(nowYear,nowMonth,1);
Date beginningOfNextMonth = new Date(nowYear,nowMonth+1,1);
Date start = beginningOfMonth;
while(start.before(beginningOfNextMonth)){
listOfDatesInThisMonth.add(start);
start = new Date(nowYear,nowMonth,start.getDate()+1);
}
for(Date date:listOfDatesInThisMonth){
Rec recItem = new Rec();
recItem.setDate(date);
recItems.add(recItem );
}
Rendering
Column<Rec,String> dayColumn = new Column<Rec,String>(new TextCell())
{
#Override
public String getValue(Rec rec)
{
dayNr = DateTimeFormat.getFormat( "EE,d" ).format(rec.getDate());
return dayNr;
}
};
Something like this ??
private static String getMonthsString() {
StringBuffer buffer = new StringBuffer();
Date date = new Date() ;
int i = date.getMonth();
if(i==2)//feb {
for (int j = 0; j < 28; j++) {
buffer.append(DateTimeFormat.getFormat( "EE,d" ).format( new Date(new Date().getTime() + ((1000 * 60 * 60 * 24*j)))));
}
return buffer.toString();
}
In a Cell Table each row is one record. A month will have atleast 28 days. So you must build atleast 28 records and do setList or setData on the cell Table. A short code snippet is given below -
Date currentDate = new Date();
Map<Integer, String> daysMap = new HashMap<Integer, String>();
daysMap .put(0,"Sunday");
.
.
daysMap .put(6, "Saturday");
Map<Integer, Integer> monthMap = new HashMap<Integer, Integer>();
monthMap.put(0, 31);
.
.
monthMap.put(0, 31);
List<Rec> list = new ArrayList<Rec>();
for(int i=1;i <= monthMap.get(currentDate.getMonth());i++)
{
list.add(new Rec( daysMap.get(currentDate.getDay())+" , "+ i ));
}
Column<Rec,String> dayColumn = new Column<Rec,String>(new TextCell())
{
#Override
public String getValue(Rec rec)
{
return rec.getDayDateString(); // which returns Friday, 1 etc.
}
};
table.addColumn(dayColumn, "Date");
ListDataProvider<Rec> listDataProvider = new ListDataProvider<Rec>();
listDataProvider.addDataDisplay(table);
listDataProvider.setList( list );
You could get the dates of each month on the server side using java.util.Calendar
Showing a scrollable list for dates is horrible usability. I would suggest using a DatePickerCell instead. It uses a date picker, so that the user can just click on the date to choose it.