How can you calculate the number of weeks between two dates in Android? I have done something like this
int week1 = calendar1.get(Calendar.WEEK_OF_YEAR);
int week2 = calendar2.get(Calendar.WEEK_OF_YEAR);
int calendarWeekDifference = week2 - week1;
However this does not work when the two dates are in different years. How can I achieve a solution so that it will work across different years?
EDIT
I have tried doing the following with Joda-Time:
public static int weeksTouched(Calendar fromDate, Calendar toDate){
DateTime fromDateTime = new DateTime(fromDate);
DateTime toDateTime = new DateTime(toDate);
DateTime epoch = new DateTime(0);
Weeks fromWeeks = Weeks.weeksBetween(epoch, fromDateTime);
Weeks toWeeks = Weeks.weeksBetween(epoch, toDateTime);
int betweenWeeks = toWeeks.getWeeks() - fromWeeks.getWeeks();
return betweenWeeks;
}
This almost works but for some reason it thinks the start of a week is Thursday. I want the start of a week to be Monday so that a Monday to the next Saturday would return 0 (same week) but a Saturday to the next day Sunday would return 1 (different weeks).
public int getWeekDifference(long fromDateInMills, long toDateInMills) {
int weeks = Weeks.weeksBetween(new DateTime(fromDateInMills), new DateTime(toDateInMills)).getWeeks();
// when we select any future date than week difference comes in negative so
// just interchange millisecond You will get week difference in positive
if (weeks < 0) {
weeks = Weeks.weeksBetween(new DateTime(toDateInMills), new DateTime(fromDateInMills)).getWeeks();
}
return weeks;
}
Some answers here give wrong results, and some require an extra library. I managed to come up with a method that calculates the week-diff using standard Calendar APIs.
It correctly handles edge cases like 2000-01-01 to 2000-12-31 (54 weeks implies a difference of 53).
getWeeksBetween() using Calendar API
public static int getWeeksBetween(final Date start, final Date end) {
final Calendar c1 = Calendar.getInstance(Locale.US);
final Calendar c2 = Calendar.getInstance(Locale.US);
// Skip time part! Not sure if this is needed, but I wanted clean dates.
CalendarUtils.setDateWithNoTime(c1, start);
CalendarUtils.setDateWithNoTime(c2, end);
CalendarUtils.goToFirstDayOfWeek(c1);
CalendarUtils.goToFirstDayOfWeek(c2);
int weeks = 0;
while (c1.compareTo(c2) < 0) {
c1.add(Calendar.WEEK_OF_YEAR, 1);
weeks++;
}
return weeks;
}
And some helper methods:
public static int goToFirstDayOfWeek(final Calendar calendar) {
final int firstDayOfWeek = calendar.getFirstDayOfWeek();
calendar.set(Calendar.DAY_OF_WEEK, firstDayOfWeek);
return firstDayOfWeek;
}
public static void setDateWithNoTime(final Calendar calendar, final Date date) {
calendar.setTime(date);
clearTime(calendar);
}
public static void clearTime(final Calendar calendar) {
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
Without using JodaTime, I came up with this solution to calculate number of weeks:
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")
}
}
I would recommend that instead of calculating the difference in weeks you should try to find the difference in days and the result you can divide by 7.
So it would be weeks = (daysBetweenDates / 7)
using java 8
public void weeks_between_two_dates_in_java_with_java8 () {
LocalDate startDate = LocalDate.of(2005, Month.JANUARY, 1);
LocalDate endDate = LocalDate.of(2006, Month.JANUARY, 1);
long weeksInYear = ChronoUnit.WEEKS.between(startDate, endDate);
}
or using joda time api
public void weeks_between_two_dates_in_java_with_joda () {
DateTime start = new DateTime(2005, 1, 1, 0, 0, 0, 0);
DateTime end = new DateTime(2006, 1, 1, 0, 0, 0, 0);
Weeks weeks = Weeks.weeksBetween(start, end);
int weeksInYear = weeks.getWeeks();
}
What about a sort of low tech solution just using maths?
You have the Week_OF_YEAR from each date. Also the the YEAR number for each.
Multiply each Year number by 52, add that to the WEEK_OF_YEAR then subtract the two numbers.
for example....
2018 Week 50
to
2019 Week 2
2018*52 = 104936 + 50 weeks = 104986
2019*52 = 104988 + 2 weeks = 104990
104990 - 104986 = 4 weeks
Another alternative solution. My basic concept is:
Trim given dates to the respective Mondays 00:00:00.000
Calculate milliseconds between those trimmed dates and then divide it by milliseconds of a week.
A sample in Java:
public class Main {
public static void main(String[] args) {
Calendar Monday = Calendar.getInstance();
Monday.set(2020, 11, 28, 12, 34, 56); // 2020-12-28T12:34:56
Calendar Saturday = Calendar.getInstance();
Saturday.set(2021, 0, 2, 21, 43, 57); // 2021-01-02T21:43:57
Calendar Sunday = Calendar.getInstance();
Sunday.set(2021, 0, 3, 0, 1, 2); // 2021-01-03T00:01:02
Calendar NextMonday = Calendar.getInstance();
NextMonday.set(2021, 0, 4, 1, 23, 45); // 2021-01-04T01:23:45
System.out.println(String.format(": %d week(s)", weeksTouched(Monday, Sunday)));
System.out.println(String.format(": %d week(s)", weeksTouched(Saturday, Sunday)));
System.out.println(String.format(": %d week(s)", weeksTouched(Sunday, NextMonday)));
}
public static int weeksTouched(Calendar fromDate, Calendar toDate){
System.out.print(String.format("%s -> %s", fromDate.getTime(), toDate.getTime()));
return (int) (
(trimToMonday(toDate).getTimeInMillis() - trimToMonday(fromDate).getTimeInMillis())
/ (1000 * 60 * 60 * 24 * 7)
);
}
private static Calendar trimToMonday(Calendar input) {
Calendar output = (Calendar) input.clone();
switch (output.get(Calendar.DAY_OF_WEEK)) {
case Calendar.TUESDAY:
output.add(Calendar.DAY_OF_MONTH, -1);
break;
case Calendar.WEDNESDAY:
output.add(Calendar.DAY_OF_MONTH, -2);
break;
case Calendar.THURSDAY:
output.add(Calendar.DAY_OF_MONTH, -3);
break;
case Calendar.FRIDAY:
output.add(Calendar.DAY_OF_MONTH, -4);
break;
case Calendar.SATURDAY:
output.add(Calendar.DAY_OF_MONTH, -5);
break;
case Calendar.SUNDAY:
output.add(Calendar.DAY_OF_MONTH, -6);
break;
}
output.set(Calendar.HOUR_OF_DAY, 0);
output.set(Calendar.MINUTE, 0);
output.set(Calendar.SECOND, 0);
output.set(Calendar.MILLISECOND, 0);
return output;
}
}
Output:
Mon Dec 28 12:34:56 JST 2020 -> Sun Jan 03 00:01:02 JST 2021: 0 week(s)
Sat Jan 02 21:43:57 JST 2021 -> Sun Jan 03 00:01:02 JST 2021: 0 week(s)
Sun Jan 03 00:01:02 JST 2021 -> Mon Jan 04 01:23:45 JST 2021: 1 week(s)
This will give you number of weeks b/w two dates.
public void getNoOfWeek()
{
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.clear();
date1.set(2015, 12, 29); // set date 1 (yyyy,mm,dd)
date2.clear();
date2.set(2016, 02, 7); //set date 2 (yyyy,mm,dd)
long diff = date2.getTimeInMillis() - date1.getTimeInMillis();
float dayCount = (float) diff / (24 * 60 * 60 * 1000);
int week = (int) (dayCount / 7);
System.out.println(week);
}
I have the following Oracle SQL Statement in my SQL Select clause, which transform a date like 01.04.2015 into 78, 01.07.2015 into 79 and so on (the value of beginDate could be 01.04.2015 or 01.07.2015):
SELECT to_char(beginDate, 'q') + 4 * to_char(beginDate, 'yy') + 16
FROM myDateValuesTable;
Now it is important for me to transform always the current Date into the same values in Java by using the same kind of math expression. I have no idea, how I can programming these steps in Java? Here is a first idea:
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR); // the value is 2015
int month = calendar.get(Calendar.MONTH); // the value is 09
int quarter = (month / 3) + 1; // the value is 3
For the 01.04.2015 it must be transformed into 78 and for the 01.07.2015 into 79. How can I solve this problem?
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
System.out.println(month / 3 + 1 + 4 * (year % 100) + 16);
Oracle 'q' returns the quarter of the year. This is obtained in Java by getting the month value and calculating month / 3 + 1.
Then, Oracle 'yy' returns the last two digits of the year. This is obtained in Java by getting the year value and calculating year % 100.
You can test it with the following code:
public static void main(String args[]) throws Exception {
System.out.println(getNumber("01.04.2015")); // prints 78
System.out.println(getNumber("01.07.2015")); // prints 79
}
private static int getNumber(String dateStr) throws ParseException {
Date date = new SimpleDateFormat("dd.MM.yyyy").parse(dateStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
return month / 3 + 1 + 4 * (year % 100) + 16;
}
here is my code,
int txtSubsDay = Integer.parseInt(this.textSubDay.getText());
int txtDay = Integer.parseInt(this.textDay.getText());
int txtMonth = Integer.parseInt(this.textMonth.getText());
int txtYear = Integer.parseInt(this.textYear.getText());
int daysToSubs = txtSubsDay;
int convertedYears = (int)(daysToSubs / 360);
int convertedMonths = (int)((daysToSubs % 360) / 30);
int convertedDays = (int)((daysToSubs % 360) % 30);
Calendar calendar = new GregorianCalendar(txtYear, txtMonth-1, txtDay);
calendar.add(Calendar.MONTH, -convertedMonths);
calendar.add(Calendar.DAY_OF_MONTH, -convertedDays);
calendar.add(Calendar.YEAR, -convertedYears);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MM yyyy");
SimpleDateFormat dayFormat = new SimpleDateFormat("d MMM yyyy");
String lastDate = dateFormat.format(calendar.getTime());
String lastDate2 = dayFormat.format(calendar.getTime());
labelOutput.setText(lastDate);
labelOutput2.setText(lastDate2);
It was what i wanted.////////////////////////////////////////
it saved my time.
int totalDays = 548;
int years = (int)(totalDays / 360);
int months = (int((totalDays % 360) / 30);
int days = (int)((totalDays % 360) % 30);
System.out.println("years: " + years + "; months: " + months + "; days: " + days);
// Result: years: 1; months: 6; days: 8
Still, I don't really understand why you insist on using 360 for years and 30 for months. If you just want to subtract days from one date to receive the correct date in the past, use this instead:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date dateInstance = dateFormat.parse("27/07/2015");
int daysSubstracted = 548;
Calendar cal = Calendar.getInstance();
cal.setTime(dateInstance);
cal.add(Calendar.DATE, -daysSubstracted);
Date dateInPast = cal.getTime();
System.out.println(dateFormat.format(dateInPast));
// Result: 25/01/2014
you need to find number of days between two dates
//we have two dates, now and day 0
Date d1 = new Date(0);
Date d2 = new Date();
//substract times from each other, and divide this by number milisecond in day
int days =(int)((d2.getTime()-d1.getTime()) /(1000*60*60 *24) );
//and display your result
System.out.println(days+" days = "+(days/360)+" years "+((days%360)/30)+" month "+days%30);
I need to claculate the number of days between two dates without using any date or calendar classes provided by any library.
Here's my idea:
numberOfDays = Math.abs((toYear - fromYear) * 365);
numberOfDays = numberOfDays + Math.abs((toMonth - fromMonth) * 12);
numberOfDays = numberOfDays + Math.abs((toDay - fromDay));
Thoughts?
How many days between the start date and the end of the month?
How many days in each full month until the end of the year?
How many days in each full year until the year of the end date (counting leap years)?
How many days in each full month until the last month?
How many days from the start of the last month until the end date?
Some of these numbers may be zero.
In Java 8 you can do the following:
long days = ChronoUnit.DAYS.between(LocalDate.of(2014, Month.MARCH, 01), LocalDate.of(2014, Month.FEBRUARY, 15));
Would something like this do?
//get 2 random dates
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = new Date();
Date date2 = sdf.parse("2014-9-12");
final long msInADay = 24*60*60*1000; //turn a day to ms
//divide time difference by the ms of a day
int difference = (int)((date2.getTime() - date1.getTime()) / msInADay);
System.out.println(Math.abs(difference));//Math.abs so you can subtract dates in any order.
EDIT after updating your question:
You can do this:
static int calcDayDiff(int startY, int startM, int startD, int endY, int endM, int endD){
int result = (startY - endY) * 365;
result += (startM - endM) * 31;
result += (startD - endD);
return Math.abs(result);
}
Testing with: System.out.println(calcDayDiff(2014,9,13,2013,8,12)); will print 397
Note though that this is not a very good solution since not every month contains 31 days and not every year 365. You can fix the month day difference by adding some simple logic inside the method to not always multiply by 31. Since it's an assignment i guess you will be ok to consider every year having 365 days.
public class test {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(2014, 8, 1, 0, 0, 0);
Date s = cal.getTime();
Date e = new Date();
System.out.println(days(s,e));
}
public static int days(Date start, Date end){
double aTms = Math.floor(start.getTime() - end.getTime());
return (int) (aTms/(24*60*+60*1000));
}
}
This question already has answers here:
Calculating the difference between two Java date instances
(45 answers)
Closed 9 years ago.
hello I am trying to calculate how many days are left in a pregnancy term but I think my algorithm is incorrect
public int getDaysPregnantRemainder_new() {
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
long diffDays = 280 - ((getDueDate().getTime() - calendar.getTime()
.getTime()) / (24 * 60 * 60 * 1000));
return (int) Math.abs((diffDays) % 7);
}
I am basing it off of a 280 day term, getDueDate() is a Date object and getTime() returns millisecond unix time
On some real world days the number reported is off by one, sometimes, and I am starting to think my algorithm is just wrong, or the millisecond time get gradually further and further off, or the millisecond time is not precise enough, or the gregorian calendar function rounds weird.
All in all I'm not sure, any insight appreciated
I don't know about your algorithm, but this (is basically) the one I used while tracking my wife's pregency...nerds...
Save yourself a lot of "guess" work and get hold of Joda-Time
public class TestDueDate {
public static final int WEEKS_IN_PREGNANCY = 40;
public static final int DAYS_IN_PREGNANCY = WEEKS_IN_PREGNANCY * 7;
public static void main(String[] args) {
DateTime dueDate = new DateTime();
dueDate = dueDate.plusDays(DAYS_IN_PREGNANCY);
System.out.println("dueDate = " + dueDate);
DateTime today = DateTime.now();
Days d = Days.daysBetween(today, dueDate);
int daysRemaining = d.getDays();
int daysIn = DAYS_IN_PREGNANCY - daysRemaining;
int weekValue = daysIn / 7;
int weekPart = daysIn % 7;
String week = weekValue + "." + weekPart;
System.out.println("Days remaining = " + daysRemaining);
System.out.println("Days In = " + daysIn);
System.out.println("Week = " + week);
}
}
This will output...
dueDate = 2014-02-25T14:14:31.159+11:00
Days remaining = 279
Days In = 1
Week = 0.1