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;
}
Related
I'm trying to parse date string that looks like this Feb0920221500 (month, day in month, year, hours, minutes). But when I use MMMddyyyyHmm pattern I always get a FormatException. Furthermore intl's DateFormat fails to parse back a date which it has formatted before:
import 'package:intl/intl.dart';
void main() {
final dateFormat = DateFormat("MMMddyyyyHmm");
final dateString = dateFormat.format(DateTime.now());
print(dateString);
final date = dateFormat.parse(dateString);
print(date);
}
Output:
Feb0920221511
Uncaught Error: FormatException: Trying to read yyyy from Feb0920221511 at position 13
What am I doing wrong?
You are running into this issue: https://github.com/dart-lang/intl/issues/210
TL/DR: Both methods are not designed to work fully reversible, if I understood the package maintainers correctly.
Try to introduce field separators like a space or a dot as a workaround:
final dateFormat = DateFormat("MMM dd yyyy H mm");
final dateString = dateFormat.format(DateTime.now());
print(dateString);
print(dateFormat.parseStdaterict(dateString));
If the format of the given date String cannot be changed, you still have the possibility to make it work with a hack like this. Just make sure to handle errors gracefully.
import 'package:intl/intl.dart';
Future<void> main() async {
final parsedDate = 'Feb0920221511'.parseToDate();
print(parsedDate.toIso8601String());
}
extension CustomDateParser on String {
DateTime parseToDate() {
try {
final month = substring(0, 3);
final day = substring(3, 5);
final year = substring(5, 9);
final hour = substring(9, 11);
final minute = substring(11, 13);
final paddedDateString = '$month $day $year $hour $minute';
final dateFormat = DateFormat('MMM dd yyyy H mm');
return dateFormat.parse(paddedDateString);
} catch (e) {
// handle error
print(e);
rethrow;
}
}
}
I have a task to display remaining months and days for booked cruise. I have tried something but it is not as per the requirements. Future Date is fetch from API and need to compare it with current date to get difference. I have attach image with my tried code.
DateTime received from API
2021-10-05T16:30:00Z
Tried Code
final date1 = DateTime.now().toUtc();
final DateTime date2 = DateTime.parse(date).toUtc();
final difference = date2.difference(date1).inDays;
final month1 = date1.month.toInt();
final month2 = date2.month.toInt();
final monthDiff = month1 - month2;
final daysDiff = difference - (monthDiff * 30);
print(difference);
print("monthDiff $monthDiff");
print("daysDiff $daysDiff");
return difference.toString();
This is what I do. There is a problem that I define a month as 30 days.
void main(List<String> args) {
final date1 = DateTime.now();
final date2 = DateTime.parse('2021-10-05T16:30:00Z');
final difference = date2.difference(date1);
final monthDiff = (difference.inDays / 30).floor();
final daysDiff = difference.inDays % 30;
print('monthDiff $monthDiff');
print('daysDiff $daysDiff');
print(difference);
}
Use the build-in function difference:
Taken from the official documentation:
var berlinWallFell = DateTime.utc(1989, DateTime.november, 9);
var dDay = DateTime.utc(1944, DateTime.june, 6);
Duration difference = berlinWallFell.difference(dDay);
print(difference.inDays); //here you can use another getter
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.
I am trying to compare the userr entered date with today's date and update the database accordingly. This is how i am doing..
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("MM-dd-yyyy");
today = df.format(c.getTime());
//===================================================================
try{
ContentValues val1 = new ContentValues();
val1.put(CPUser.Data.TASK_TYPE, "Todays Task");
getContentResolver().update(CPUser.Data.CONTENT_URI, val1, CPUser.Data.TASK_DUE_DATE + "=" +"'"+today+"'",null);
ContentValues val2 = new ContentValues();
val2.put(CPUser.Data.TASK_TYPE, "Overdue Task");
getContentResolver().update(CPUser.Data.CONTENT_URI, val2, CPUser.Data.TASK_DUE_DATE + "<" +"'"+today+"'",null);
ContentValues val3 = new ContentValues();
val3.put(CPUser.Data.TASK_TYPE, "Active Task");
getContentResolver().update(CPUser.Data.CONTENT_URI, val3, CPUser.Data.TASK_DUE_DATE + ">" +"'"+today+"'",null);
}
Catch(Exception ex)
{ }
If you want to store dates as text in the database, you always have to use "yyyy-MM-dd" format, otherwise you would not be able to do comparisons other than equal ("="). What I do is to save all dates, times and timestamps as INT using Unix Epoch. This allows you to display dates in different formats (using locale for example) to display dates, without first parsing the date. It also allows any type of comparison (equals, greater than etc). The functions are straight forward:
public static long timestampFromUnixEpoch(long unixepoch) {
if (unixepoch == 0)
return 0;
return (unixepoch * 1000) - TimeZone.getDefault().getRawOffset();
}
public static long unixEpochFromTimestamp(long timestampMS) {
if (timestampMS == 0)
return 0;
return ((timestampMS + TimeZone.getDefault().getRawOffset()) / 1000);
}
public static long dateToUnixEpoch(Date date) {
if (date == null)
return 0;
return unixEpochFromTimestamp(date.getTime());
}
public static Date unixEpochToDate(long unixepoch) {
if (unixepoch == 0)
return null;
return new Date(timestampFromUnixEpoch(unixepoch));
}
how to get current date in DD-MM-YYYY format in BlackBerry
i have already tried the following, but it gives me output of 1318502493
long currentTime = System.currentTimeMillis() / 1000;
System.out.println("Current time in :" + currentTime);
private String pattern = "dd-MM-yyyy";
String dateInString =new SimpleDateFormat(pattern).format(new Date());
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
return formatter.format(new Date());
Check if you can use SimpleDateFormat. If you can, create an object of this class, and use it in order to format the return provided by System.currentTimeMillis(). Some code below:
import java.util.*;
import java.text.*;
public class DateTest {
public static String getCurrentTimeStamp() {
SimpleDateFormat formDate = new SimpleDateFormat("dd-MM-yyyy");
// String strDate = formDate.format(System.currentTimeMillis()); // option 1
String strDate = formDate.format(new Date()); // option 2
return strDate;
}
public static void main (String args[]) {
System.out.println(getCurrentTimeStamp());
}
}