Android calculate days between two dates - java

I have written the following code to find days between two dates
startDateValue = new Date(startDate);
endDateValue = new Date(endDate);
long diff = endDateValue.getTime() - startDateValue.getTime();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = (hours / 24) + 1;
Log.d("days", "" + days);
When start and end date are 2/3/2017 and 3/3/2017 respectively the number of days showing is 29.Though when they are of the same day it is showing 1.(The number of days one takes a leave.So if one takes a single day leave,he has to select same start and end date.So in this case he has taken two days leave).
What am I doing wrong?
Thank you for your time.
Note: Please don't use the date constructor. Check the accepted answer below. Use simpledateformat or Joda time. Date constructor is deprecated.

Your code for generating date object:
Date date = new Date("2/3/2017"); //deprecated
You are getting 28 days as answer because according to Date(String) constructor it is thinking day = 3,month = 2 and year = 2017
You can convert String to Date as follows:
String dateStr = "2/3/2017";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse(dateStr);
Use above template to make your Date object. Then use below code for calculating days in between two dates. Hope this clear the thing.
It can de done as follows:
long diff = endDateValue.getTime() - startDateValue.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
Please check link
If you use Joda Time it is much more simple:
int days = Days.daysBetween(date1, date2).getDays();
Please check JodaTime
How to use JodaTime in Java Project

Kotlin
Here is the example to calculate days from today to some date:
val millionSeconds = yourDate.time - Calendar.getInstance().timeInMillis
leftDays.text = TimeUnit.MILLISECONDS.toDays(millionSeconds).toString() + "days"
If you want to calculate two days, then change:
val millionSeconds = yourDate1.time - yourDate2.time
should work.

public static int getDaysDifference(Date fromDate,Date toDate)
{
if(fromDate==null||toDate==null)
return 0;
return (int)( (toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24));
}

Does Android fully support java-8? If yes you can simple use ChronoUnit class
LocalDate start = LocalDate.of(2017,2,3);
LocalDate end = LocalDate.of(2017,3,3);
System.out.println(ChronoUnit.DAYS.between(start, end)); // 28
or same thing using formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
LocalDate start = LocalDate.parse("2/3/2017",formatter);
LocalDate end = LocalDate.parse("3/3/2017",formatter);
System.out.println(ChronoUnit.DAYS.between(start, end)); // 28

java.time and ThreeTenABP
If I understand correctly, you want the number of days from start day through end date inclusive.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/M/u");
String startDate = "2/3/2017";
String endDate = "3/3/2017";
LocalDate startDateValue = LocalDate.parse(startDate, dateFormatter);
LocalDate endDateValue = LocalDate.parse(endDate, dateFormatter);
long days = ChronoUnit.DAYS.between(startDateValue, endDateValue) + 1;
System.out.println("Days: " + days);
Output:
Days: 2
ChronoUnit.DAYS.between() gives us a count of days from start date inclusive to end date exclusive. So to include the end date too we needed to add 1 day just as you did in the question.
What went wrong in your code?
You are using the Date(String) constructor. This constructor has been deprecated since 1997 because it works unreliably across time zones, so don’t use it. Also it’s kind of magical: at least I never really know what I get. Apparently it takes 2/3/2017 to mean February 3, 2017, where you intended 2 March 2017. From February 3 to March 3 inclusive is 29 days (since 2017 wasn’t a leap year). This explains why you got 29. (If necessary, we could spell our way through the documentation and find out why 2/3/2017 is interpreted the way it is, only I’d find that a pointless waste of time to do.)
You can’t convert from milliseconds. Please also note that not only the question but also the very many answers that convert from milliseconds to days are incorrect. Such a conversion assumes that a day is always 24 hours. Because of summer time (DST) and other time anomalies a day is not always 24 hours. All of those answers will count a day too few for example if the leave crosses the spring gap or spring forward when summer time begins.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

What date format do you use? Is it d/M/yyyy or M/d/yyyy?
d = day, M = month, yyyy = year
(see: https://developer.android.com/reference/java/text/SimpleDateFormat.html)
Then the codes:
public static final String DATE_FORMAT = "d/M/yyyy"; //or use "M/d/yyyy"
public static long getDaysBetweenDates(String start, String end) {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
Date startDate, endDate;
long numberOfDays = 0;
try {
startDate = dateFormat.parse(start);
endDate = dateFormat.parse(end);
numberOfDays = getUnitBetweenDates(startDate, endDate, TimeUnit.DAYS);
} catch (ParseException e) {
e.printStackTrace();
}
return numberOfDays;
}
And for getUnitBetweenDates method:
private static long getUnitBetweenDates(Date startDate, Date endDate, TimeUnit unit) {
long timeDiff = endDate.getTime() - startDate.getTime();
return unit.convert(timeDiff, TimeUnit.MILLISECONDS);
}

Very simple, just use Calendar, create two instances for the two dates, convert to milliseconds, subtract and convert to days (rounded up)... like this, basically:
Calendar startDate = Calendar.getInstance();
startDate.set(mStartYear, mStartMonth, mStartDay);
long startDateMillis = startDate.getTimeInMillis();
Calendar endDate = Calendar.getInstance();
endDate.set(mEndYear, mEndMonth, mEndDay);
long endDateMillis = endDate.getTimeInMillis();
long differenceMillis = endDateMillis - startDateMillis;
int daysDifference = (int) (differenceMillis / (1000 * 60 * 60 * 24));

Have look at this code , this is helpful for me ,hope it will help you.
public String get_count_of_days(String Created_date_String, String Expire_date_String) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
Date Created_convertedDate = null, Expire_CovertedDate = null, todayWithZeroTime = null;
try {
Created_convertedDate = dateFormat.parse(Created_date_String);
Expire_CovertedDate = dateFormat.parse(Expire_date_String);
Date today = new Date();
todayWithZeroTime = dateFormat.parse(dateFormat.format(today));
} catch (ParseException e) {
e.printStackTrace();
}
int c_year = 0, c_month = 0, c_day = 0;
if (Created_convertedDate.after(todayWithZeroTime)) {
Calendar c_cal = Calendar.getInstance();
c_cal.setTime(Created_convertedDate);
c_year = c_cal.get(Calendar.YEAR);
c_month = c_cal.get(Calendar.MONTH);
c_day = c_cal.get(Calendar.DAY_OF_MONTH);
} else {
Calendar c_cal = Calendar.getInstance();
c_cal.setTime(todayWithZeroTime);
c_year = c_cal.get(Calendar.YEAR);
c_month = c_cal.get(Calendar.MONTH);
c_day = c_cal.get(Calendar.DAY_OF_MONTH);
}
/*Calendar today_cal = Calendar.getInstance();
int today_year = today_cal.get(Calendar.YEAR);
int today = today_cal.get(Calendar.MONTH);
int today_day = today_cal.get(Calendar.DAY_OF_MONTH);
*/
Calendar e_cal = Calendar.getInstance();
e_cal.setTime(Expire_CovertedDate);
int e_year = e_cal.get(Calendar.YEAR);
int e_month = e_cal.get(Calendar.MONTH);
int e_day = e_cal.get(Calendar.DAY_OF_MONTH);
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.clear();
date1.set(c_year, c_month, c_day);
date2.clear();
date2.set(e_year, e_month, e_day);
long diff = date2.getTimeInMillis() - date1.getTimeInMillis();
float dayCount = (float) diff / (24 * 60 * 60 * 1000);
return ("" + (int) dayCount + " Days");
}

Be carefur if you'd like to use received integer e.g. to indicate specific day in custom calendar implementation. For example, I tried to go in m app from monthly calendar view to daily view and show daily content, by calculating dates from 1970-01-01 to selected one, and each 25-31th day of month shows me as one day earlier, because datesDifferenceInMillis / (24 * 60 * 60 * 1000); may return something like 17645,95833333333, and casting this to int you'll get value lower by 1. In this case correctly number of days you'll get by rounding received float by using NumberFormat class. Here's my code:
NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
numberFormat.setMaximumFractionDigits(0);
numberFormat.setMinimumFractionDigits(0);
int days = numberFormat.parse(numberFormat.format(value)).intValue();
I hope it will be helpful.

SUPER SIMPLE
use LocalDate() include implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1' to use in android
Example
IN KOTLIN
val daysDifferene = LocalDate.of(2017,3,3).toEpochDay() - LocalDate.of(2017,3,2)
even better
create extension function to LocalDate class
private operator fun LocalDate.minus(other: LocalDate) = toEpochDay() - other.toEpochDay()
now just say
val daysDifference = localDate1 - localDate2 // you get number of days in Long type
IN JAVA
long daysDifference = LocalDate.of(2017,3,3).toEpochDay() - LocalDate.of(2107,3,2)

I modified Jitendra's answer in Kotlin:
fun getDaysBetweenDates(firstDateValue: String, secondDateValue: String, format: String): String
{
val sdf = SimpleDateFormat(format, Locale.getDefault())
val firstDate = sdf.parse(firstDateValue)
val secondDate = sdf.parse(secondDateValue)
if (firstDate == null || secondDate == null)
return 0.toString()
return (((secondDate.time - firstDate.time) / (1000 * 60 * 60 * 24)) + 1).toString()
}
and call it like
val days = getDaysBetweenDates("31-03-2020", "24-04-2020","dd-MM-yyyy")

fun countDaysBetweenTwoCalendar(calendarStart: Calendar, calendarEnd: Calendar) : Int{
val millionSeconds = calendarEnd.timeInMillis - calendarStart.timeInMillis
val days = TimeUnit.MILLISECONDS.toDays(millionSeconds) //this way not round number
val daysRounded = (millionSeconds / (1000.0 * 60 * 60 * 24)).roundToInt()
return daysRounded
}

while none of these worked for me, here is an easy way to implement your code with a very simple fonction :
private long getDaysDifference(Date fromDate,Date toDate) {
if(fromDate == null || toDate == null)
return 0;
int a = Integer.parseInt(DateFormat.format("dd", fromDate)+"");
int b = Integer.parseInt(DateFormat.format("dd", toDate)+"");
if ( b <= a){
return Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH) + b - a;
}
return b - a;
}
EnJoY

You can use joda time, it so simple
fun getBetweenDates(startDate: Long, endDate: Long): String {
val period = Period(startDate, endDate, PeriodType.yearMonthDayTime())
val formatter = PeriodFormatterBuilder()
.appendYears().appendSuffix(" year ")
.appendMonths().appendSuffix(" month ")
.appendDays().appendSuffix(" days ")
.appendHours().appendSuffix(" hours ")
.appendMinutes().appendSuffix(" minutes ")
.appendSeconds().appendSuffix(" seconds ")
.appendMillis().appendSuffix(" millis ")
.toFormatter()
return formatter.print(period)
}
start and end dates millisecond, and result example: "2 year 1 month ..."

use this way :
fun stringDateToCalendar(dateString: String?, formatString: String): Calendar? {
if (dateString == null || dateString.isEmpty() || formatString.isBlank())
return null
val inputDateFormat = SimpleDateFormat(formatString, Locale.ENGLISH)
return try {
inputDateFormat.parse(dateString)?.let {
val cal = Calendar.getInstance()
cal.time = it
cal
}
} catch (e: ParseException) {
null
}
}
val calendarFrom = stringDateToCalendar(
"2021-12-12",
"yyyy-MM-dd"
)
val calendarTo = CalendarUtils.stringDateToCalendar(
"2022-03-20",
"yyyy-MM-dd"
)
val msDiff = calendarTo?.timeInMillis?.minus(calendarFrom?.timeInMillis ?: 0) ?: 0
val daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff)

Here the simply common function Kotlin code
Here comparing these formatted dates "2022-11-04", "2022-11-20"
Output will be 16 Days
open fun dateSubstraction(date1: String, date2: String): String {
val dateFormatter = SimpleDateFormat("yyyy-MM-dd") //Define input date format here
val formatedDate1= dateFormat.parse(date1) //formated date1
val formatedDate2= dateFormat.parse(date2) //formated date2
val millionSeconds = formatedDate2.time - formatedDate1.time
return TimeUnit.MILLISECONDS.toDays(millionSeconds).toString()+"Days"
}

I have done this work in past. This was very simple
val currentCalendar = Calendar.getInstance()
val targetCalendar = Calendar.getInstance().apply {
set(2023, Calendar.APRIL, 9, 23, 59, 59)
}//your input: date, month, and time
val difference = targetCalendar.timeInMillis - currentCalendar.timeInMillis
val differenceInDays = TimeUnit.MILLISECONDS.toDays(difference)
val remainingMonths = differenceInDays / 30//remaining months
val remainingDays = differenceInDays % 30//remaining days
val differenceInSeconds = TimeUnit.MILLISECONDS.toSeconds(difference)
val differenceInMinutes = TimeUnit.MILLISECONDS.toMinutes(difference)
val differenceInHours = TimeUnit.MILLISECONDS.toHours(difference)
val remainingSeconds = differenceInSeconds % 60//remaining seconds
val remainingMinutes = differenceInMinutes % 60//remaining minutes
val remainingHours = differenceInHours % 24// remaining hours
Thats It We have done it

Related

Checking dates if it is in a range

My Java FX app handles hours worked. I have work start and end time in 2 date fields. I succeeded in calculating the differences between 2 datesTime; but now how could I check if the result is in a night or day range???? The day begin at 6 and ends at 22h. For example someone who worked between 3Am till 11Pm.
Here is below how I did to have the total number of hours worked.
public void CalculNbreJourTravaille() {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyy HH:mm");
try {
Date ddtt = format.parse(ddt.getText());
Date dftt = format.parse(dft.getText());
long diff = dftt.getTime() - ddtt.getTime();
long diffhours = diff / (60*60*1000)%24;
long diffdays = diff/(24*60*60*1000);
long total = diffhours + (diffdays*24);
result.setText(total + " Hours");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
We have workers who can work beyond 10PM, and the pay would not be the same. If they work after 10pm, they will have a special pay. We pay at the end of the work. They could would work only 10 days or more.
You should use the new DateTimeFormatter class to give you a LocalDateTime object, which you can pull the hour from.
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
LocalDateTime localDateTimeFrom = format.parse(dateFrom.getText(), LocalDateTime::from);
LocalDateTime localDateTimeTo = format.parse(dateTo.getText(), LocalDateTime::from);
int hoursFrom = localDateTimeFrom.getHour();
int hoursTo = localDateTimeTo.getHour();
boolean workedNight = hoursFrom < 6 || hoursTo > 22;
Here’s my attempt to cover all of your requirements. I wrote the code before reading that you don’t require that summer time (DST) is taken into account, so I am using ZonedDateTime to get correct hours also across summer time transitions. For the same reason I need to iterate over each day. For each date I calculate the hours worked at night time and the hours worked at day time.
If you want to make sure that summer time is not taken into account, use LocalDateTime instead of ZonedDateTime. In this case there may also be a possible performance gain in calculating the whole work days in one lump rather than one day at a time.
The code below uses 28/03/2018 03:00 and 29/03/2018 23:30 as example start and end time. Expected total hours worked are 44.5 since one day is 24 hours and there are 20.5 hours from 03:00 to 23:30. The expected day time hours are 32 since there are 16 daytime hours each of the two days. This leaves 12.5 hours as night time. And indeed the code prints
Day 32.0 hours; night 12.5 hours
The program follows. Please fill in the correct time zone where I put America/Monterey.
static ZoneId zone = ZoneId.of("America/Monterrey");
static LocalTime dayStart = LocalTime.of(6, 0);
static LocalTime dayEnd = LocalTime.of(22, 0);
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/uuuu H:mm");
public static void main(String[] args) {
String workStartString = "28/03/2018 03:00";
String workEndString = "29/03/2018 23:30";
calculateWorkingHours(workStartString, workEndString);
}
public static void calculateWorkingHours(String workStartString, String workEndString) {
ZonedDateTime workStart
= LocalDateTime.parse(workStartString, formatter).atZone(zone);
ZonedDateTime workEnd
= LocalDateTime.parse(workEndString, formatter).atZone(zone);
if (workEnd.isBefore(workStart)) {
throw new IllegalArgumentException("Work end must not be before work start");
}
LocalDate workStartDate = workStart.toLocalDate();
LocalDate workEndDate = workEnd.toLocalDate();
Duration workedDaytime = Duration.ZERO;
// first calculate work at nighttime before the start date, that is, work before 06:00
Duration workedNighttime
= calculateNightTime(workStartDate.minusDays(1), workStart, workEnd);
for (LocalDate d = workStartDate; ! d.isAfter(workEndDate); d = d.plusDays(1)) {
workedDaytime = workedDaytime.plus(calculateDayTime(d, workStart, workEnd));
workedNighttime = workedNighttime.plus(calculateNightTime(d, workStart, workEnd));
}
double dayHours = workedDaytime.toMinutes() / (double) TimeUnit.HOURS.toMinutes(1);
double nightHours = workedNighttime.toMinutes() / (double) TimeUnit.HOURS.toMinutes(1);
System.out.println("Day " + dayHours + " hours; night " + nightHours + " hours");
}
/**
* Calculates amount of work in daytime on d,
* that is between 06:00 and 22:00 on d.
* Only time that falls with in workStart to workAnd
* and also falls within 06:00 to 22:00 on d is included.
*
* #param d The date for which to calculate day work
* #param workStart
* #param workEnd
* #return Amount of daytime work on the said day
*/
private static Duration calculateDayTime(LocalDate d, ZonedDateTime workStart, ZonedDateTime workEnd) {
ZonedDateTime dayStartToday = d.atTime(dayStart).atZone(zone);
ZonedDateTime dayEndToday = d.atTime(dayEnd).atZone(zone);
if (workStart.isAfter(dayEndToday) || workEnd.isBefore(dayStartToday)) {
return Duration.ZERO;
}
// restrict calculation to daytime on d
if (workStart.isBefore(dayStartToday)) {
workStart = dayStartToday;
}
if (workEnd.isAfter(dayEndToday)) {
workEnd = dayEndToday;
}
return Duration.between(workStart, workEnd);
}
/**
* Calculates amount of night work in the night after d,
* that is from 22:00 on d until 06:00 the next morning.
*
* #param d The date for which to calculate night work
* #param workStart
* #param workEnd
* #return Amount of nighttime work in said night
*/
private static Duration calculateNightTime(LocalDate d, ZonedDateTime workStart, ZonedDateTime workEnd) {
assert ! workEnd.isBefore(workStart);
ZonedDateTime nightStart = d.atTime(dayEnd).atZone(zone);
ZonedDateTime nightEnd = d.plusDays(1).atTime(dayStart).atZone(zone);
if (workEnd.isBefore(nightStart) || workStart.isAfter(nightEnd)) {
return Duration.ZERO;
}
// restrict calculation to the night after d
if (workStart.isBefore(nightStart)) {
workStart = nightStart;
}
if (workEnd.isAfter(nightEnd)) {
workEnd = nightEnd;
}
return Duration.between(workStart, workEnd);
}
You can check the LocalTime part of a LocalDateTime to have a simple check using isAfter and isBefore.
I will use those values for this example.
LocalDateTime start = LocalDateTime.of(2018, Month.APRIL, 30, 23, 0);
LocalDateTime end = LocalDateTime.of(2018, Month.MAY, 1, 5, 0);
Then define the limit for the night.
LocalTime startNight = LocalTime.of(22, 0);
LocalTime endNight = LocalTime.of(6, 0);
And simply use get the LocalTime of both date and check if they are in the range. You can get the value using toLocalTime.
if(start.toLocalTime().isAfter(startNight) &&
end.toLocalTime().isBefore(endNight)){
System.out.println("NIGHT TIME");
} else {
System.out.println("DAY TIME");
}
NIGHT TIME
The output is valid since we start at 23:00 and end at 05:00.
Using this allow a simpler solution if you need to define a time like LocalTime.of(5,45) for 5:45
This is an example, this might need some adaptation if it is allowed to start part 22 but keep working after 6. This is just an example on how to use those methods.
This is easier, if you use the java.time API. You simply need to check, if the dates differ or if the starting time not in the range from 6:00 to 22:00:
private static final LocalTime START_TIME = LocalTime.of(6, 0); // 06:00
private static final LocalTime END_TIME = LocalTime.of(22, 0); // 22:00
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
// parse from input strings
LocalDateTime start = LocalDateTime.parse(startText, FORMATTER);
LocalDateTime end = LocalDateTime.parse(endText, FORMATTER);
boolean nightTime =
!start.toLocalDate().equals(end.toLocalDate())
|| start.toLocalTime().isBefore(START_TIME)
|| end.toLocalTime().isAfter(END_TIME);
// todo: change output to gui
System.out.println("night time: " + nightTime);
System.out.println("duration : " + Duration.between(start, end).toHours());
Define two formatters. One Fromatter to get date with time from edittext. And other On to get 12AM of that day. Now we need Date Objects corresponding to 6AM and 11PM of the same day. We can get those by adding that much milliseconds to the 12AM Object. These added dates can be used for comparison.
SimpleDateFormat df_zero_hours = new SimpleDateFormat("dd/MM/yyy");
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date ddtt = format.parse(ddt.getText()); //Work Start Time
Date dftt = format.parse(dft.getText()); //Work End Time
Date dateStart = df_zero_hours.parse(ddt.getText()); //12AM of the day job started
Date dayStart = new Date();
dayStart.setTime(dateStart.getTime()+6*60*60*1000); // Get 6AM of that day
Date dayEnd = new Date();
dayEnd.setTime(dateStart.getTime()+22*60*60*1000); //Get 10PM of that day
// Now check the worked hours. in Whatever way you need
boolean isBefore6AM = (dayStart.getTime()-ddtt.getTime())>0;
boolean isAfter10PM = (dftt.getTime()-dayEnd.getTime())>0;

Android Days between two dates

I want to compare two dates for my Android application, but I got a really weird issue.
For example:
If I set the back in the past date to 127 days ago:
this.dateEvent = System.currentTimeMillis() - (127 * 24 * 3600 * 1000)
And then compare it to the current date (Days between)
Calendar sDate = getDatePart(new Date(this.dateEvent));
Calendar eDate = getDatePart(new Date(System.currentTimeMillis()));
int daysBetween = 0;
while (sDate.before(eDate))
{
sDate.add(Calendar.DAY_OF_MONTH, 1);
daysBetween ++;
}
while (sDate.after(eDate))
{
eDate.add(Calendar.DAY_OF_MONTH, 1);
daysBetween ++;
}
return daysBetween;
It will return 22 which is not at all what was expected.
Did I make something wrong or is that an issue with the Calendar class ?
Here's a two line solution:
long msDiff = Calendar.getInstance().getTimeInMillis() - testCalendar.getTimeInMillis();
long daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff);
In this example it gets the number of days between date "testCalendar" and the current date.
Please refer this code, this may help you.
public String getCountOfDays(String createdDateString, String expireDateString) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
Date createdConvertedDate = null, expireCovertedDate = null, todayWithZeroTime = null;
try {
createdConvertedDate = dateFormat.parse(createdDateString);
expireCovertedDate = dateFormat.parse(expireDateString);
Date today = new Date();
todayWithZeroTime = dateFormat.parse(dateFormat.format(today));
} catch (ParseException e) {
e.printStackTrace();
}
int cYear = 0, cMonth = 0, cDay = 0;
if (createdConvertedDate.after(todayWithZeroTime)) {
Calendar cCal = Calendar.getInstance();
cCal.setTime(createdConvertedDate);
cYear = cCal.get(Calendar.YEAR);
cMonth = cCal.get(Calendar.MONTH);
cDay = cCal.get(Calendar.DAY_OF_MONTH);
} else {
Calendar cCal = Calendar.getInstance();
cCal.setTime(todayWithZeroTime);
cYear = cCal.get(Calendar.YEAR);
cMonth = cCal.get(Calendar.MONTH);
cDay = cCal.get(Calendar.DAY_OF_MONTH);
}
/*Calendar todayCal = Calendar.getInstance();
int todayYear = todayCal.get(Calendar.YEAR);
int today = todayCal.get(Calendar.MONTH);
int todayDay = todayCal.get(Calendar.DAY_OF_MONTH);
*/
Calendar eCal = Calendar.getInstance();
eCal.setTime(expireCovertedDate);
int eYear = eCal.get(Calendar.YEAR);
int eMonth = eCal.get(Calendar.MONTH);
int eDay = eCal.get(Calendar.DAY_OF_MONTH);
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.clear();
date1.set(cYear, cMonth, cDay);
date2.clear();
date2.set(eYear, eMonth, eDay);
long diff = date2.getTimeInMillis() - date1.getTimeInMillis();
float dayCount = (float) diff / (24 * 60 * 60 * 1000);
return ("" + (int) dayCount + " Days");
}
I've finally found the easiest way to deal with that. Here is my code:
public int getTimeRemaining()
{
Calendar sDate = toCalendar(this.dateEvent);
Calendar eDate = toCalendar(System.currentTimeMillis());
// Get the represented date in milliseconds
long milis1 = sDate.getTimeInMillis();
long milis2 = eDate.getTimeInMillis();
// Calculate difference in milliseconds
long diff = Math.abs(milis2 - milis1);
return (int)(diff / (24 * 60 * 60 * 1000));
}
private Calendar toCalendar(long timestamp)
{
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
Hope it helps.
You should never use formula such 24 * 60 * 60 * 1000! Why? Because there is day saving time, and not all days have 24 hours, also what about leap year, that has +1 day. That's why there is a calendar class.
If you do not want to put any external library to your project like Jodatime, you could use pure Calendar class with very efficient function:
public static int numDaysBetween(final Calendar c, final long fromTime, final long toTime) {
int result = 0;
if (toTime <= fromTime) return result;
c.setTimeInMillis(toTime);
final int toYear = c.get(Calendar.YEAR);
result += c.get(Calendar.DAY_OF_YEAR);
c.setTimeInMillis(fromTime);
result -= c.get(Calendar.DAY_OF_YEAR);
while (c.get(Calendar.YEAR) < toYear) {
result += c.getActualMaximum(Calendar.DAY_OF_YEAR);
c.add(Calendar.YEAR, 1);
}
return result;
}
public long Daybetween(String date1,String date2,String pattern)
{
SimpleDateFormat sdf = new SimpleDateFormat(pattern,Locale.ENGLISH);
Date Date1 = null,Date2 = null;
try{
Date1 = sdf.parse(date1);
Date2 = sdf.parse(date2);
}catch(Exception e)
{
e.printStackTrace();
}
return (Date2.getTime() - Date1.getTime())/(24*60*60*1000);
}
Date userDob = new SimpleDateFormat("yyyy-MM-dd").parse(dob);
Date today = new Date();
long diff = today.getTime() - userDob.getTime();
int numOfYear = (int) ((diff / (1000 * 60 * 60 * 24))/365);
int numOfDays = (int) (diff / (1000 * 60 * 60 * 24));
int hours = (int) (diff / (1000 * 60 * 60));
int minutes = (int) (diff / (1000 * 60));
int seconds = (int) (diff / (1000));
I had the same need, I finally ended up using Joda Time, it is very convenient and offers lots of additional functions including the one you are looking for.
You can download the files from here.
Once you included the jar file into your project, you can easily do for example the following:
int daysBetween = Days.daysBetween(new DateTime(sDate), new DateTime(eDate)).getDays();
the best way :-
long fromCalender = Calender.getInstance();
fromCalender.set...// set the from dates
long toCalender = Calender.getInstance();
fromCalender.set...// set the to dates
long diffmili = fromCalender - toCalender;
long hours = TimeUnit.MILLISECONDS.toHours(diffmili);
long days = TimeUnit.MILLISECONDS.toDays(diffmili);
long min = TimeUnit.MILLISECONDS.toMinutes(diffmili);
long sec = TimeUnit.MILLISECONDS.toSeconds(diffmili);
Do like this it supports all Api Levels
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm:ss",
Locale.ENGLISH);
try {
String datestart="June 14 2018 16:02:37";
cal.setTime(sdf.parse(datestart));// all done
Calendar cal1=Calendar.getInstance();
String formatted = sdf.format(cal1.getTime());//formatted date as i want
cal1.setTime(sdf.parse(formatted));// all done
long msDiff = cal1.getTimeInMillis() - cal.getTimeInMillis();
long daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff);
Toast.makeText(this, "days="+daysDiff, Toast.LENGTH_SHORT).show();
} catch (ParseException e) {
e.printStackTrace();
}
fun TimeZone.daysBetween(from: Date, to: Date): Int {
val offset = rawOffset + dstSavings
return ((to.time + offset) / 86400000).toInt() - ((from.time + offset) / 86400000).toInt()
}
Have a try:
val f = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").apply {
timeZone = TimeZone.getTimeZone("GMT")
}
val df = f.parse("2019-02-28 22:59:59")
val dt = f.parse("2019-02-28 23:00:00")
TimeZone.getTimeZone("GMT").daysBetween(df, dt) // 0
TimeZone.getTimeZone("GMT+1").daysBetween(df, dt) // 1
java.time and ThreeTenABP
I should like to contribute the modern answer: Use java.time, the modern Java date and time API for your date work. If developing for Android API level 25 or lower, then through the backport for Android, ThreeTenABP (link at the bottom).
LocalDate eDate = LocalDate.now(ZoneId.of("Europe/Paris"));
LocalDate sDate = eDate.minusDays(127);
long daysBetween = ChronoUnit.DAYS.between(sDate, eDate);
System.out.println(daysBetween);
When I ran this code today, the output was the expected:
127
Notice that the code is not only shorter, just one line for finding the difference; it is also clearer and more natural to read. The classes Date and Calendar that you used are poorly designed and long outdated. I recommend you don’t use them.
What went wrong in your code?
You’ve got an int overflow in your conversion of 127 days to milliseconds. In mathematics 127 * 24 * 3600 * 1000 equals 10 972 800 000. Since the numbers you multiply are ints, Java performs the multiplication in int, and the largest number an int can hold is 2 147 483 647, far from enough for your expected result. In this situation it would have been nice if Java would have thrown an exception or in some other way have made us aware of the error. It doesn’t. It tacitly throws away the high order bits, giving us a result of -1 912 101 888. Subtracting this negative number from the current time is equivalent to adding 22 days and a few hours. This explains why you got 22. Funny that 13 answers have been posted and it seems that no one has spotted this …
Even when doing the multiplication using the long type, it still doesn’t calculate 127 days correctly, though. If the 127 days cross a transition to or from summer time (DST), which in France is the case during 254 of the 365 days of a year, the day of the transition is not 24 hours, but either 23 or 25. Which causes an incorrect number of milliseconds.
You should always leave date math to proven library methods. Never hand code it yourself. It’s more complicated than most of us think, so the risk of doing it incorrectly is high.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
The best solution that worked for me is :
private static int findDaysDiff(long unixStartTime,long unixEndTime)
{
Calendar calendar1 = Calendar.getInstance();
calendar1.setTimeInMillis(unixStartTime);
calendar1.set(Calendar.HOUR_OF_DAY, 0);
calendar1.set(Calendar.MINUTE, 0);
calendar1.set(Calendar.SECOND, 0);
calendar1.set(Calendar.MILLISECOND, 0);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTimeInMillis(unixEndTime);
calendar2.set(Calendar.HOUR_OF_DAY, 0);
calendar2.set(Calendar.MINUTE, 0);
calendar2.set(Calendar.SECOND, 0);
calendar2.set(Calendar.MILLISECOND, 0);
return (int) ((calendar2.getTimeInMillis()-calendar1.getTimeInMillis())/(24 * 60 * 60 * 1000));
}
Since it first converts Hour , Minute, Second and Millisecond to 0 and now the difference will be only in days.
the answer is not correct in some dates like "2019/02/18" , "2019/02/19" but i edit and resolve bug
this is best method :
public int getCountOfDays(String createdDateString, String expireDateString) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date createdConvertedDate = null;
Date expireCovertedDate = null;
try {
createdConvertedDate = dateFormat.parse(createdDateString);
expireCovertedDate = dateFormat.parse(expireDateString);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar start = new GregorianCalendar();
start.setTime(createdConvertedDate);
Calendar end = new GregorianCalendar();
end.setTime(expireCovertedDate);
long diff = end.getTimeInMillis() - start.getTimeInMillis();
float dayCount = (float) diff / (24 * 60 * 60 * 1000);
return (int) (dayCount);
}
Enjoy and if was helpefull +vote to this answer ;)
Kotlin Extension:
fun Date?.getDaysBetween(dest: Date?): Int {
if(this == null || dest == null) return 0
val diff = abs(this.time - dest.time)
val dayCount = diff.toFloat() / (24 * 60 * 60 * 1000)
return dayCount.toInt()
}
I am count the days between last submission date and current date if it is less than zero then student cannot give submission. I am working with kotlin. The below code helps you.
var calendar=Calendar.getInstance().time
var dateFormat= SimpleDateFormat("dd/M/yyyy")
var d2=dateFormat.parse(data.get("date").toString())
var cd=dateFormat.format(calendar)
var d1=dateFormat.parse(cd)
var diff=d2.time-d1.time
var ddd= TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS)
This is the Java 8 java.time version which works perfectly for me. You might want to make sure that startDate and endDate are set to the same time, otherwise days might vary by +-1!
These are the Kotlin versions I just copy/pasted.
private fun getDawnOfDay(instant: Instant): Temporal =
LocalDate.from(instant.atZone(ZoneOffset.UTC)).atStartOfDay()
fun getNumberOfDaysInBetween(startDate: Date, endDate: Date) =
Duration.between(getDawnOfDay(startDate.toInstant()), getDawnOfDay(endDate.toInstant()))
.toDays()
I have just modified a little bit most popular answer.
Here is my solution:
daysBetween() - Return days count between two dates.
public static long daysBetween(Date date1, Date date2) {
long msDiff = resetTimeToDateStart(date1).getTime() - resetTimeToDateStart(date2).getTime();
return TimeUnit.MILLISECONDS.toDays(msDiff);
}
private static Date resetTimeToDateStart(Date dDate){
if (Utils.isNull(dDate)){
return null;
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(dDate);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
int difference in days=(present_year - oldyear) * 365 + (present_month - oldmonth)*30 + (present_date-olddate);
All above answers calculating millis_diff / (24 * 60 * 60 * 1000) is simply wrong if you consider 23:59:59 ~ 00:00:00 as two different days and expect offset day count as 1, instead of 0.
A kotlin version gives you count 1, based on #oleksandr-albul answer above.
fun getDayCountBetween(to: Long, from: Long): Int {
if (to <= from) return 0
val calendar = Calendar.getInstance()
var count = 0
// get day count between 'to' and Jan 1st.
calendar.timeInMillis = to
val year = calendar.get(Calendar.YEAR)
count += calendar.get(Calendar.DAY_OF_YEAR)
// minus day count between 'from' and Jan 1st.
calendar.timeInMillis = from
count -= calendar.get(Calendar.DAY_OF_YEAR)
// plus day count of all the gap years.
while (calendar.get(Calendar.YEAR) < year) {
count += calendar.getActualMaximum(Calendar.DAY_OF_YEAR)
calendar.add(Calendar.YEAR, 1)
}
return count
}

Get the number of weeks between two Dates.

Im working in a project and I got two types in Date. I want to calculate the number of weeks between these two dates. The dates can be in diffrent years. Is there any good solution for this?
I have tried to implemenent this with Joda-time which was suggested in other topics..
Im not familar with this library, but I tried to do something like this:
public static int getNumberOfWeeks(Date f, Date l){
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(f);
c2.setTime(l);
DateTime start = new DateTime(c1.YEAR, c1.MONTH, c1.DAY_OF_MONTH, 0, 0, 0, 0);
DateTime end = new DateTime(c2.YEAR, c2.MONTH, c2.DAY_OF_MONTH, 0, 0, 0, 0);
Interval interval = new Interval(start, end);
Period p = interval.toPeriod();
return p.getWeeks();
}
But this is completely wrong... any suggestions ?
Updating answer to account for Java 8
// TechTrip - ASSUMPTION d1 is earlier than d2
// leave that for exercise
public static long getFullWeeks(Calendar d1, Calendar d2){
Instant d1i = Instant.ofEpochMilli(d1.getTimeInMillis());
Instant d2i = Instant.ofEpochMilli(d2.getTimeInMillis());
LocalDateTime startDate = LocalDateTime.ofInstant(d1i, ZoneId.systemDefault());
LocalDateTime endDate = LocalDateTime.ofInstant(d2i, ZoneId.systemDefault());
return ChronoUnit.WEEKS.between(startDate, endDate);
}
It is pretty easy with joda time:
DateTime dateTime1 = new DateTime(date1);
DateTime dateTime2 = new DateTime(date2);
int weeks = Weeks.weeksBetween(dateTime1, dateTime2).getWeeks();
tl;dr
ChronoUnit
.WEEKS
.between(
myJavaUtilDate_Start.toInstant().atZone( ZoneId.of( "Asia/Tokyo" ) ) ,
myJavaUtilDate_Stop.toInstant().atZone( ZoneId.of( "Asia/Tokyo" ) )
)
7
java.time
The java.time framework is built into Java 8 and later. These new classes supplant the old date-time classes bundled with the earliest versions of Java.
The java.time classes also supplant the highly successful Joda-Time framework. Both java.time and Joda-Time are led by Stephen Colbourne.
Instant replaces java.util.Date
The modern class Instant replaces the legacy class java.util.Date. Both represent a moment in UTC, a specific point on the timeline. Both internally use a count since the same epoch reference of the first moment of 1970 in UTC, 1970-01-01T00:00Z. The old class uses a count of milliseconds, while Instant uses a finer count of nanoseconds.
To convert, call new methods added to the old classes.
Instant start = myJavaUtilDateStart.toInstant() ;
Instant stop = myJavaUtilDateStop.toInstant() ;
Let's make this concrete with some example values.
Instant start = OffsetDateTime.of( 2020 , 1 , 23 , 15 , 30 , 0 , 0 , ZoneOffset.UTC ).toInstant();
Instant stop = OffsetDateTime.of( 2020 , 1 , 23 , 15 , 30 , 0 , 0 , ZoneOffset.UTC ).plusWeeks(7 ).toInstant();
Moments versus dates
Both of our Instant objects represent a moment. The goal is a count of weeks. Weeks means days, and days mean certain dates on the calendar.
So we have a bit of a mismatch. For any given moment, the date varies around the globe by time zone. A few minutes after midnight in Paris France is a new date. Meanwhile in Montréal Québec, being several hours behind, that same moment is still “yesterday”, the date before on the calendar. So we cannot directly calculate weeks from a pair of moments.
You must first decide on the time zone by which you want to perceive a calendar for those moments.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime
Apply this ZoneId to our Instant objects to adjust into a time zone, yielding a pair of ZonedDateTime objects.
ZonedDateTime startZdt = start.atZone( z ) ;
ZonedDateTime stopZdt = stop.atZone( z ) ;
ChronoUnit.WEEKS
Now we can use the ChronoUnit enum to calculate elapsed weeks.
long weeks = ChronoUnit.WEEKS.between( startZdt , stopZdt );
Dump to console.
System.out.println( "start.toString() = " + start );
System.out.println( "stop.toString() = " + stop );
System.out.println( "startZdt.toString() = " + startZdt );
System.out.println( "stopZdt.toString() = " + stopZdt );
System.out.println( "weeksCount: " + weeksCount );
See this code run live at IdeOne.com.
start.toString() = 2020-01-23T15:30:00Z
stop.toString() = 2020-03-12T15:30:00Z
startZdt.toString() = 2020-01-23T10:30-05:00[America/Montreal]
stopZdt.toString() = 2020-03-12T11:30-04:00[America/Montreal]
weeksCount: 7
ThreeTen-Extra
The ThreeTen-Extra project adds functionality to the java.time framework built into Java 8 and later.
Weeks class
That project includes a Weeks class to represent a number of weeks. Not only can it calculate, it is also meant to be used in your code as a type-safe object. Such use also helps to make your code self-documenting.
You can instantiate by providing a pair of points in time with the Weeks.between method. Those points in time can be anything implementing java.time.temporal.Temporal including Instant, LocalDate, OffsetDateTime, ZonedDateTime, Year, YearMonth, and more.
Your java.util.Date objects can be easily converted to Instant objects, moments on the timeline in UTC with a resolution in nanoseconds. Look at new methods added to the old date-time classes. For going from Date to Instant, call java.util.Date::toInstant.
Weeks weeks = Weeks.between( startZdt , stopZdt );
You can ask for the number of weeks.
int weeksNumber = weeks.getAmount(); // The number of weeks in this Weeks object.
You can also do much more.
Generate a string in standard ISO 8601 format. The P marks the beginning. The W indicates a number of weeks.
PW7
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Using the date arithmetic in java.util.Calendar:
public static int getWeeksBetween (Date a, Date b) {
if (b.before(a)) {
return -getWeeksBetween(b, a);
}
a = resetTime(a);
b = resetTime(b);
Calendar cal = new GregorianCalendar();
cal.setTime(a);
int weeks = 0;
while (cal.getTime().before(b)) {
// add another week
cal.add(Calendar.WEEK_OF_YEAR, 1);
weeks++;
}
return weeks;
}
public static Date resetTime (Date d) {
Calendar cal = new GregorianCalendar();
cal.setTime(d);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
If your requirement is like the start date is 03-Apr-2020 and end date is 07-Apr-2020. the difference between the two dates is 4 days. Now the number of weeks between two dates as 1 for this you can use below snippet.
ChronoUnit.WEEKS.between(LocalDate startDate, LocalDate endDate);
But If your requirement is like 03-Apr-2020 is in one week and 07-Apr-2020 is in another week so you want the number of weeks between two dates as 2 you can use the below snippet.
LocalDate actualStartDate=...
LocalDate actualEndDate=...
LocalDate startDate = actualStartDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY))
LocalDate endDate = actualEndDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SATURDAY))
long daysBetweenTwoDates = ChronoUnit.DAYS.between(startDate, endDate);
int numberOfWeeks = (int)Math.ceil(daysBetweenTwoDates/7.0);
Tested in java 1.8
Calendar a = new GregorianCalendar(2002,1,22);
Calendar b = new GregorianCalendar(2002,1,28);
System.out.println(a.get(Calendar.WEEK_OF_YEAR));
System.out.println(b.get(Calendar.WEEK_OF_YEAR));
int weeks = b.get(Calendar.WEEK_OF_YEAR)-a.get(Calendar.WEEK_OF_YEAR);
System.out.println(weeks);
try this must work
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(2007, 01, 10);
calendar2.set(2007, 07, 01);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
int diffWeeks = (int)diff / (7*24 * 60 * 60 * 1000);
Here are 2 methods I wrote that not based on an external library.
The first method is when Monday is the first day of the week.
The second method is when Sunday is the first day of the week.
Please read the comments inside the code, there is an option to return the number of the full weeks between 2 dates, and also with the fraction of the remaining days before and after the 2 dates.
public static int getNumberOfFullWeeks(LocalDate startDate,LocalDate endDate)
{
int dayBeforeStartOfWeek = 0;
int daysAfterLastFullWeek = 0;
if(startDate.getDayOfWeek() != DayOfWeek.MONDAY)
{
// get the partial value before loop starting
dayBeforeStartOfWeek = 7-startDate.getDayOfWeek().getValue() + 1;
}
if(endDate.getDayOfWeek() != DayOfWeek.SUNDAY)
{
// get the partial value after loop ending
daysAfterLastFullWeek = endDate.getDayOfWeek().getValue();
}
LocalDate d1 = startDate.plusDays(dayBeforeStartOfWeek); // now it is the first day of week;
LocalDate d2 = endDate.minusDays(daysAfterLastFullWeek); // now it end in the last full week
// Count how many days there are of full weeks that start on Mon and end in Sun
// if the startDate and endDate are less than a full week the while loop
// will not iterate at all because d1 and d2 will be the same date
LocalDate looper = d1;
int counter = 1;
while (looper.isBefore(d2))
{
counter++;
looper = looper.plusDays(1);
}
// Counter / 7 will always be an integer that will represents full week
// because we started to count at Mon and stop counting in Sun
int fullWeeks = counter / 7;
System.out.println("Full weeks between dates: "
+ fullWeeks + " Days before the first monday: "
+ dayBeforeStartOfWeek + " "
+ " Days after the last sunday: " + daysAfterLastFullWeek);
System.out.println(startDate.toString() + " - " + endDate.toString());
// You can also get a decimal value of the full weeks plus the fraction if the days before
// and after the full weeks
float full_weeks_decimal = (float)fullWeeks;
float fraction = ((float)dayBeforeStartOfWeek + (float)daysAfterLastFullWeek) / 7.0F;
System.out.println("Full weeks with fraction: " + String.valueOf(fraction + full_weeks_decimal));
return fullWeeks;
}
public static int getNumberOfFullWeeks_WeekStartAtSunday(LocalDate startDate,LocalDate endDate)
{
int dayBeforeStartOfWeek = 0;
int daysAfterLastFullWeek = 0;
if(startDate.getDayOfWeek() != DayOfWeek.SUNDAY)
{
// get the partial value before loop starting
dayBeforeStartOfWeek = 7-getDayOfWeekBySundayIs0(startDate.getDayOfWeek()) + 1;
}
if(endDate.getDayOfWeek() != DayOfWeek.SATURDAY)
{
// get the partial value after loop ending
daysAfterLastFullWeek = 1+getDayOfWeekBySundayIs0(endDate.getDayOfWeek());
}
LocalDate d1 = startDate.plusDays(dayBeforeStartOfWeek); // now it is the first day of week;
LocalDate d2 = endDate.minusDays(daysAfterLastFullWeek); // now it end in the last full week
// Count how many days there are of full weeks that start on Sun and end in Sat
// if the startDate and endDate are less than a full week the while loop
// will not iterate at all because d1 and d2 will be the same date
LocalDate looper = d1;
int counter = 1;
while (looper.isBefore(d2))
{
counter++;
looper = looper.plusDays(1);
}
// Counter / 7 will always be an integer that will represents full week
// because we started to count at Sun and stop counting in Sat
int fullWeeks = counter / 7;
System.out.println("Full weeks between dates: "
+ fullWeeks + " Days before the first sunday: "
+ dayBeforeStartOfWeek + " "
+ " Days after the last saturday: " + daysAfterLastFullWeek);
System.out.println(startDate.toString() + " - " + endDate.toString());
// You can also get a decimal value of the full weeks plus the fraction if the days before
// and after the full weeks
float full_weeks_decimal = (float)fullWeeks;
float fraction = ((float)dayBeforeStartOfWeek + (float)daysAfterLastFullWeek) / 7.0F;
System.out.println("Full weeks with fraction: " + String.valueOf(fraction + full_weeks_decimal));
return fullWeeks;
}
public static int getDayOfWeekBySundayIs0(DayOfWeek day)
{
if(day == DayOfWeek.SUNDAY)
{
return 0;
}
else
{
// NOTE: getValue() is starting to count from 1 and not from 0
return day.getValue();
}
}
If you want exact number of full weeks use below method, where end date is exclusive:
public static long weeksBetween(Date date1, Date date2) {
return WEEKS.between(date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
}
If you want a ceil version of this, use below:
public static long weeksBetween(Date date1, Date date2) {
long daysBetween = DAYS.between(date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) + 1;
return daysBetween / 7 + (daysBetween % 7 == 0 ? 0 : 1);
}
You may do it the following way:
// method header not shown
// example dates:
f = new GregorianCalendar(2009,Calendar.AUGUST,1);
l = new GregorianCalendar(2010,Calendar.SEPTEMBER,1);
DateTime start = new DateTime(f);
DateTime end = new DateTime(l);
// Alternative to above - example dates with joda:
// DateTime start = new DateTime(2009,8,1,0,0,0,0);
// DateTime end = new DateTime(2010,9,1,0,0,0,0);
Interval interval = new Interval(start,end);
int weeksBetween = interval.toPeriod(PeriodType.weeks()).getWeeks();
// return weeksBetween;
This should give you an int representing the number of weeks between the two dates.
Joda Time computes weeks with durations of two dates which may not meet our requirements in some cases. I have a method with Joda Time to compute natural weeks between two dates. Hope it can help you. If you don't use Joda Time, you may modify the code with Calendar to do the same thing.
//Unlike Joda Time Weeks.weeksBetween() that returns whole weeks computed
//from duration, we return natural weeks between two dates based on week of year
public static int weeksBetween(ReadablePartial date1, ReadablePartial date2) {
int comp = date1.compareTo(date2);
if (comp == 0) {
return 0;
}
if (comp > 0) {
ReadablePartial mid = date2;
date2 = date1;
date1 = mid;
}
int year1 = date1.get(DateTimeFieldType.weekyear());
int year2 = date2.get(DateTimeFieldType.weekyear());
if (year1 == year2) {
return date2.get(DateTimeFieldType.weekOfWeekyear()) - date1.get(DateTimeFieldType.weekOfWeekyear());
}
int weeks1 = 0;
LocalDate lastDay1 = new LocalDate(date1.get(DateTimeFieldType.year()), 12, 31);
if (lastDay1.getWeekyear() > year1) {
lastDay1 = lastDay1.minusDays(7);
weeks1++;
}
weeks1 += lastDay1.getWeekOfWeekyear() - date1.get(DateTimeFieldType.weekOfWeekyear());
int midWeeks = 0;
for (int i = year1 + 1; i < year2; i++) {
LocalDate y1 = new LocalDate(i, 1, 1);
int yearY1 = y1.getWeekyear();
if (yearY1 < i) {
y1 = y1.plusDays(7);
midWeeks++;
}
LocalDate y2 = new LocalDate(i, 12, 31);
int yearY2 = y2.getWeekyear();
if (yearY2 > i) {
y2 = y2.minusDays(7);
midWeeks++;
}
midWeeks += y2.getWeekOfWeekyear() - y1.getWeekOfWeekyear();
}
int weeks2 = 0;
LocalDate firstDay2 = new LocalDate(date2.get(DateTimeFieldType.year()), 1, 1);
if (firstDay2.getWeekyear() < firstDay2.getYear()) {
firstDay2 = firstDay2.plusDays(7);
weeks2++;
}
weeks2 += date2.get(DateTimeFieldType.weekOfWeekyear()) - firstDay2.getWeekOfWeekyear();
return weeks1 + midWeeks + weeks2;
}
int startWeek = c1.get(Calendar.WEEK_OF_YEAR);
int endWeek = c2.get(Calendar.WEEK_OF_YEAR);
int diff = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
int deltaYears = 0;
for(int i = 0;i < diff;i++){
deltaYears += c1.getWeeksInWeekYear();
c1.add(Calendar.YEAR, 1);
}
diff = (endWeek + deltaYears) - startWeek;
Includes the year differences.
This worked for me :)
private int weeksBetween(Calendar startDate, Calendar endDate) {
startDate.set(Calendar.HOUR_OF_DAY, 0);
startDate.set(Calendar.MINUTE, 0);
startDate.set(Calendar.SECOND, 0);
int start = (int)TimeUnit.MILLISECONDS.toDays(
startDate.getTimeInMillis())
- startDate.get(Calendar.DAY_OF_WEEK);
int end = (int)TimeUnit.MILLISECONDS.toDays(
endDate.getTimeInMillis());
return (end - start) / 7;
}
if this method returns 0 they are in the same week
if this method return 1 endDate is the week after startDate
if this method returns -1 endDate is the week before startDate
you get the idea
Without using JodaTime, I was able to accurately calculate the number of weeks between 2 calendars (which accounts for leap years etc.)
private fun calculateNumberOfWeeks() {
val calendarFrom = Calendar.getInstance()
calendarFrom.set(Calendar.HOUR_OF_DAY, 0)
calendarFrom.set(Calendar.MINUTE, 0)
calendarFrom.set(Calendar.SECOND, 0)
calendarFrom.set(Calendar.MILLISECOND, 0)
val calendarTo = Calendar.getInstance()
calendarTo.add(Calendar.MONTH, months)
calendarTo.set(Calendar.HOUR_OF_DAY, 0)
calendarTo.set(Calendar.MINUTE, 0)
calendarTo.set(Calendar.SECOND, 0)
calendarTo.set(Calendar.MILLISECOND, 0)
var weeks = -1
while (calendarFrom.timeInMillis < calendarTo.timeInMillis) {
calendarFrom.add(Calendar.DATE, 7)
weeks++
Log.d(Constants.LOG_TAG, "weeks $weeks")
}
}
Easy way
Calendar cal1 = new GregorianCalendar();
Calendar cal2 = new GregorianCalendar();
cal1.set(2014, 3, 3);
cal2.set(2015, 3, 6);
weekscount.setText("weeks= "+ ( (cal2.getTime().getTime() - cal1.getTime().getTime()) / (1000 * 60 * 60 * 24))/7);
Here is a simple way to find the number of weeks between two dates.
SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String classStartData = "31 01 2021";
String classEndData = "08 03 2021";
Date dateClassStart = myFormat.parse(classStartData);
Date dateClassEnd = myFormat.parse(classEndData);
long differenceWeek = dateClassEnd.getTime() - dateClassStart.getTime();
int programLength = (int)(TimeUnit.DAYS.convert(differenceWeek, TimeUnit.MILLISECONDS)/7);
System.out.println("Class length in weeks: " +programLength);
After referring many solution, this worked for me.
{Provided I did not want to use external Libraries}
public static int getNumberOfWeeks(Date date1, Date date2) {
if (date1.after(date2)) {
return getNumberOfWeeks(date2, date1);
}
Date date = date1;
int days = 0;
while (date.before(date2)) {
days++;
date = addDays(date, 1);
}
return days/7;
}
To add days to a date :
Date addDays(Date date, int days) {
if (days == 0) {
return date;
} else {
Date shiftedDate = new Date(date.getTime() + (long)days * 86400000L);
return shiftedDate;
}
}
Take a look at the following article: Java - calculate the difference between two dates
The daysBetween method will allow you to get the number of days between dates. Then you can simply divide by 7 to get the number of full weeks.
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.clear();
date1.set(datePicker1.getYear(), datePicker1.getMonth(),
datePicker1.getDayOfMonth());
date2.clear();
date2.set(datePicker2.getYear(), datePicker2.getMonth(),
datePicker2.getDayOfMonth());
long diff = date2.getTimeInMillis() - date1.getTimeInMillis();
float dayCount = (float) diff / (24 * 60 * 60 * 1000);
int week = (dayCount / 7) ;
Hope this might Help you
public int diffInWeeks(Date start, Date end) {
long diffSeconds = (end.getTime() - start.getTime())/1000;
return (int)diffSeconds/(60 * 60 * 24 * 7);
}

unable to get difference of days between two dates in java

I want to calculate the difference of days between two dates. My code works fine when the year of the date does not change, but when I calculate the difference between two dates like so: (13/01/2012 to 13/12/2011), it gives a negative value. It also gives wrong values of difference when I calculate the difference between today's date and a future date. Please help me. Thank you in advance. Here is my code:
//getting values from text box
String fromtext = from.getText().toString();
String totext = to.getText().toString();
//sdf if a simple date formatter
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date fromdate = (Date) sdf.parse(fromtext);
Date todate = (Date) sdf.parse(totext);
Calendar fromcal = Calendar.getInstance();
Calendar tocal = Calendar.getInstance();
fromcal.setTime(fromdate);
tocal.setTime(todate);// setting to date
int reportDays=(int)(todate.getTime()-fromdate.getTime())/(3600*24*1000);
please tell me what is the best way to calculate the difference in days.
Dates input : 13/01/2012, 13/12/2011
format seems dd/MM/yyyy and you are using wrong one (i.e. MM/dd/yyyy)
tl;dr
ChronoUnit.DAYS.between(
LocalDate.parse( "13/01/2012" , DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ) ,
LocalDate.parse( "13/12/2011" , DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) )
)
Using java.time
Much easier with the modern java.time classes that supplant the troublesome old legacy date-time classes such as Date & Calendar.
(13/01/2012 to 13/12/2011),
The LocalDate class represents a date-only value without time-of-day and without time zone.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate start = LocalDate.parse( "13/01/2012" , f );
LocalDate stop = LocalDate.parse( "13/12/2011" , f );
Use ChronoUnit to calculate elapsed days.
long days = ChronoUnit.DAYS.between( start , stop );
Of course the number of days is negative when going back in time. Notice how your stop date is earlier than your start date.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
You can use ChronoUnit again to count days into the future.
long days = ChronoUnit.DAYS.between( today , today.plusMonths( 7 ) );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
In addition to the format issue already mentionned, you are likely to have an overflow.
Try this:
int reportDays=(int)((todate.getTime()-fromdate.getTime())/(3600*24*1000));
I think you should try better googling....
http://www.java2s.com/Code/Java/Development-Class/DateDiffcomputethedifferencebetweentwodates.htm
Using joda time would be the simplest way.
check this code:
import java.util.Calendar;
public class DateDifferent{
public static void main(String[] args){
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(2007, 01, 10);
calendar2.set(2007, 07, 01);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffSeconds = diff / 1000;
long diffMinutes = diff / (60 * 1000);
long diffHours = diff / (60 * 60 * 1000);
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("\nThe Date Different Example");
System.out.println("Time in milliseconds: " + diff + " milliseconds.");
System.out.println("Time in seconds: " + diffSeconds + " seconds.");
System.out.println("Time in minutes: " + diffMinutes + " minutes.");
System.out.println("Time in hours: " + diffHours + " hours.");
System.out.println("Time in days: " + diffDays + " days.");
}
}
Here's a simple little class I wrote for this purpose:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DifferenceInDays
{
public int dateOffset(String incomingDate) throws ParseException
{
// parse dates
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date date = (Date) formatter.parse(incomingDate);
// convert to milliseconds
long millisecs = date.getTime();
// convert to days
int offsetInDays = (int) Math.abs(millisecs / (1000 * 60 * 60 * 24));
return offsetInDays;
}
}
It takes care of negative offsets using the absolute value method.
If you try this with a locale that has daylight saving, and the from and to dates are before and after a daylight saving change the result may be different by 1 day. This is because Date and Calendar use timezones.
If you are only going to be dealing with dates between the years 1900 and 2100, there is a simple calculation which will give you the number of days since 1900:
public static int daysSince1900(Date date) {
Calendar c = new GregorianCalendar();
c.setTime(date);
int year = c.get(Calendar.YEAR);
if (year < 1900 || year > 2099) {
throw new IllegalArgumentException("daysSince1900 - Date must be between 1900 and 2099");
}
year -= 1900;
int month = c.get(Calendar.MONTH) + 1;
int days = c.get(Calendar.DAY_OF_MONTH);
if (month < 3) {
month += 12;
year--;
}
int yearDays = (int) (year * 365.25);
int monthDays = (int) ((month + 1) * 30.61);
return (yearDays + monthDays + days - 63);
}
Thus, to get the difference in days between two dates, you calculate their days since 1900 and calc the difference. Our daysBetween method looks like this:
public static Integer getDaysBetween(Date date1, Date date2) {
if (date1 == null || date2 == null) {
return null;
}
int days1 = daysSince1900(date1);
int days2 = daysSince1900(date2);
if (days1 < days2) {
return days2 - days1;
} else {
return days1 - days2;
}
}
And don't ask me where this calculation came from because we've used it since the early '90s.
I would do it like this!
package javaapplication2;
//#author Ibrahim Yesilay
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class JavaApplication2 {
public static void main(String[] args) throws ParseException {
Scanner scan = new Scanner(System.in);
System.out.println("First dates Day :");
int d = scan.nextInt();
System.out.println("First dates Mounth :");
int m = scan.nextInt();
System.out.println("First dates Year :");
int y = scan.nextInt();
String date;
date = Integer.toString(d) + "/" + Integer.toString(m) + "/" + Integer.toString(y);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date firstdate = null;
firstdate = dateFormat.parse(date);
System.out.println(dateFormat.format(firstdate));
System.out.println("Second dates Day :");
d = scan.nextInt();
System.out.println("Second dates Month :");
m = scan.nextInt();
System.out.println("Second dates Year :");
y = scan.nextInt();
date = Integer.toString(d) + "/" + Integer.toString(m) + "/" + Integer.toString(y);
Date seconddate = null;
seconddate = dateFormat.parse(date);
System.out.println(dateFormat.format(seconddate));
if (seconddate.getTime() > firstdate.getTime()) {
long sonuc = (long)(seconddate.getTime()- firstdate.getTime())/(3600*24*1000);
System.out.println("" + sonuc);
} else if (firstdate.getTime() > seconddate.getTime()) {
long sonuc = (long)(firstdate.getTime()- seconddate.getTime())/(3600*24*1000);
System.out.println("" + sonuc);
} else {
System.out.println("The dates are equal!");
}
}
}

What is the equivalent of getTime(), which is a method in Date, in joda.time.LocalDate?

I was doing a simple calculation to get the difference between two dates. If I was using a Date class I can do like this:
Date d1 = new GregorianCalendar(2000, 11, 31, 23, 59).getTime();
/** Today's date */
Date today = new Date();
// Get msec from each, and subtract.
long diff = today.getTime() - d1.getTime();
System.out.println("The 21st century (up to " + today + ") is "
+ (diff / (1000 * 60 * 60 * 24)) + " days old.");
}
But I couldn't find a method like getTime() in Local date. Is there any way so I can easily get what I am trying to achieve?
I even tried to change my LocalDate object to a temporary date object like this:
LocalDate date=new LocalDate();
Date d=date.toDate();
but the method toDate() isnt working . i.e it says it is not recognized method.(so compile time error) but from what I can see it is in the Documentation
Thank you for your time and of course happy Thanksgiving.
Days.daysBetween() is the answer.
LocalDate now = new LocalDate();
LocalDate past = now.minusDays(300);
int days = Days.daysBetween(past,now).getDays();
Never convert a LocalDate to a Java Date (two completey different beasts) if you are just dealing with dates. A Jodatime Localdate is a true "Calendar date", i.e. , a tuple of {day,month,year} (together with a Gregorian calendar specification), and has nothing to do with "physical time", with seconds, hours, etc. If you need to do dates arithmetic, stick with Localdate and you'll never need to worry about stupid bugs (timezones, DST, etc) which could arise if you dates arithmetic using java Dates.
Try something like this:
LocalDate date = new LocalDate();
Date utilDate = date.toDateTimeAtStartOfDay( timeZone ).toDate( );
or refer to this post
How to convert Joda LocalDate to java.util.Date?
I tested this sample code to find out the difference in days, you can find the difference as per your needs.
Please see http://joda-time.sourceforge.net/key_period.html
LocalDate currentDate = new LocalDate();
LocalDate previousDate = currentDate.minusDays(1);
System.out.println(currentDate);
System.out.println(previousDate);
Period periodDifference = new Period(currentDate, previousDate, PeriodType.days());
System.out.println(periodDifference);
private long diff(Calendar c1, Calendar c2) {
long d1 = c1.getTimeInMillis();
long d2 = c2.getTimeInMillis();
return ((d2 - d1) / (60*60*24*1000));
}
Have not found any equivalents for LocalDate as they are not exact.
But there are several equivalents for LocalDateTime:
LocalDateTime localDateTime = LocalDateTime.now();
long longValue = ZonedDateTime.of(localDateTime, ZoneId.systemDefault()).toInstant().toEpochMilli();
or
long longValue = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
or
long longValue = localDateTime.toInstant(OffsetDateTime.now().getOffset()).toEpochMilli();
or
long longValue = Timestamp.valueOf(localDateTime).getTime();

Categories