Reputation: 103
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).
Upvotes: 2
Views: 6966
Reputation: 12478
Another alternative solution. My basic concept is:
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)
Upvotes: 0
Reputation: 19937
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).
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);
}
Upvotes: 1
Reputation: 1
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
Upvotes: 0
Reputation: 2445
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();
}
Upvotes: 0
Reputation: 422
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)
Upvotes: 0
Reputation: 1636
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")
}
}
Upvotes: 0
Reputation: 103
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;
}
Upvotes: 1
Reputation: 195
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);
}
Upvotes: -1