AtanuCSE
AtanuCSE

Reputation: 8940

Compare if two dates are within same week in android

I have two dates.Got them from something like......

Calendar c=Calendar.getInstance();
year=c.get(c.YEAR);
month=c.get(c.MONTH);
month++;
date=c.get(c.DATE);

and other date is broken into date2,month2

Now I want to see if both of them are in the same week.

It's possible through lots of calculation and logic.Problem occurs when 1st date is suppose 03 March and 2nd date is 28Feb. Both of them are in same week but difficult to compare/check that. So I want to know if there is any built in function or any way to compare them easily.Please help..........

Upvotes: 10

Views: 13229

Answers (10)

Jan-David Salchow
Jan-David Salchow

Reputation: 131

I ended up using

date1.with(previousOrSame(MONDAY)).equals(date2.with(previousOrSame(MONDAY)))

assuming that weeks start on Monday.

Upvotes: 2

Sujeet Shetty
Sujeet Shetty

Reputation: 285

Here in Joda's Library I found that the week starts from Monday, but I wanted the week to start from Sunday, so just used the below function :

  public static boolean isSameWeek(final Date initDate, final Date finalDate) {
    if (initDate != null && finalDate != null) {
        Calendar initCalender = Calendar.getInstance();
        Calendar finalCalender = Calendar.getInstance();
        initCalender.setTime(initDate);
        finalCalender.setTime(finalDate);
        if (finalCalender.get(Calendar.YEAR) >= initCalender.get(Calendar.YEAR)) {
            //check for same year
            if (finalCalender.get(Calendar.YEAR) == initCalender.get(Calendar.YEAR)) {
                if (finalCalender.get(Calendar.WEEK_OF_YEAR) == initCalender.get(Calendar.WEEK_OF_YEAR)) {
                    return true;
                }
            } else //check whether next corresponding year
                if (finalCalender.get(Calendar.YEAR) - initCalender.get(Calendar.YEAR) == 1) {
                    if (initCalender.get(Calendar.WEEK_OF_YEAR) == 1 || initCalender.get(Calendar.WEEK_OF_YEAR) == 53) {
                        if (finalCalender.get(Calendar.WEEK_OF_YEAR) == 1) {
                            if (initCalender.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && finalCalender.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
                                return true;
                            }
                        }
                    }
                }
        } else {
            throw new IllegalArgumentException("Final Date should be greater or equal to Initial Date");
        }
    } else {
        throw new IllegalArgumentException("The date must not be null");
    }
    return false;
}

Upvotes: 0

Mirza Ahmed Baig
Mirza Ahmed Baig

Reputation: 5865

this will give true if two dates from same week

fun isEqualWeek(date1: Long, date2: Long):Boolean{
    val cal1 = Calendar.getInstance()
    val cal2 = Calendar.getInstance()
    cal1.time = Date(date1)
    cal2.time = Date(date2)
    return (cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)) && (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(
        Calendar.WEEK_OF_YEAR
    ))
}

Upvotes: 0

deHaar
deHaar

Reputation: 18588

Use java.time

You can get it available the following ways:

Java 8+ and Android API 26+: directly available
Java 6 and 7: ThreeTenBP
Android 25 and lower: ThreeTenABP

It is not recommended to use java.util.Calendar and java.util.Date anymore.

How to find out if two given dates are in the same calendar week?

Using plain java.time:

public boolean inSameCalendarWeek(LocalDate firstDate, LocalDate secondDate) {
    // get a reference to the system of calendar weeks in your defaul locale
    WeekFields weekFields = WeekFields.of(Locale.getDefault());
    // find out the calendar week for each of the dates
    int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
    int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
    /*
     * find out the week based year, too,
     * two dates might be both in a calendar week number 1 for example,
     * but in different years
     */
    int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
    int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
    // return if they are equal or not
    return firstDatesCalendarWeek == secondDatesCalendarWeek
            && firstWeekBasedYear == secondWeekBasedYear;
}

You can do that with simple int values, too:

public static boolean inSameCalendarWeek(int firstYear, int firstMonth, int firstDayOfMonth,
        int secondYear, int secondMonth, int secondDayOfMonth) {
    // create LocalDates using the integers provided
    LocalDate firstDate = LocalDate.of(firstYear, firstMonth, firstDayOfMonth);
    LocalDate secondDate = LocalDate.of(secondYear, secondMonth, secondDayOfMonth);
    // get a reference to the system of calendar weeks in your defaul locale
    WeekFields weekFields = WeekFields.of(Locale.getDefault());
    // find out the calendar week for each of the dates
    int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
    int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
    /*
     * find out the week based year, too,
     * two dates might be both in a calendar week number 1 for example,
     * but in different years
     */
    int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
    int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
    // return if they are equal or not
    return firstDatesCalendarWeek == secondDatesCalendarWeek
            && firstWeekBasedYear == secondWeekBasedYear;
}

In case you have to extend or use legacy code:

public static boolean inSameCalendarWeek(Calendar firstCalendar, Calendar secondCalendar) {
    // create LocalDates from Instants created from the given Calendars
    LocalDate firstDate = LocalDate.from(firstCalendar.toInstant());
    LocalDate secondDate = LocalDate.from(secondCalendar.toInstant());
    // get a reference to the system of calendar weeks in your defaul locale
    WeekFields weekFields = WeekFields.of(Locale.getDefault());
    // find out the calendar week for each of the dates
    int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
    int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
    /*
     * find out the week based year, too,
     * two dates might be both in a calendar week number 1 for example,
     * but in different years
     */
    int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
    int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
    // return if they are equal or not
    return firstDatesCalendarWeek == secondDatesCalendarWeek
            && firstWeekBasedYear == secondWeekBasedYear;
}

The output of the following code

public static void main(String[] args) {
    // a date from calendar week 1 in the week based year 2020
    LocalDate janFirst2020 = LocalDate.of(2020, 1, 1);
    // another date from calendar week 1 in the week based year 2020 
    LocalDate decThirtyFirst2019 = LocalDate.of(2019, 12, 31);
    System.out.println(inSameCalendarWeek(janFirst2020, decThirtyFirst2019));

    // then a third date from calendar week 1, but this time in the week based year 2021
    LocalDate janSeventh2021 = LocalDate.of(2021, 1, 7);
    System.out.println(inSameCalendarWeek(janSeventh2021, decThirtyFirst2019));
}

is therefore

true
false

in my locale.

Upvotes: 5

Anatolii
Anatolii

Reputation: 14680

Let's say, a week starts one year and ends the next year and we pick 2 dates from this week so that they are in different years. Then, the accepted answer yields the wrong result as it checks that the dates are in the SAME YEAR!.

To improve the solution, one could obtain a date corresponding to some day (it could be Monday) of its week and then check that both dates belong to the same day. However, before doing so make sure that both Calendar objects are in the SAME time zone. So, set the time zone of one to another. Also, the solution below works for every API level as it doesn't require the usage of getWeekOfWeekyear() or getWeekYear() (these work with API 24 and higher.

public boolean isSameWeek(Calendar calendar1, Calendar calendar2) {
    Calendar calendar2Copy = (Calendar) calendar2.clone();
    calendar2Copy.setTimeZone(calendar1.getTimeZone());
    calendar1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    calendar2Copy.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

    return calendar1.get(Calendar.YEAR) == calendar2Copy.get(Calendar.YEAR)
            && calendar1.get(Calendar.DAY_OF_YEAR) == calendar2Copy.get(Calendar.DAY_OF_YEAR);
}

Upvotes: 0

FabianCook
FabianCook

Reputation: 20587

use something like this:

Calendar c = Calendar.getInstance();
Integer year1 = c.get(c.YEAR);
Integer week1 = c.get(c.WEEK_OF_YEAR);

Calendar c = Calendar.getInstance();
c.setTimeInMillis(/*Second date in millis here*/);
Integer year2 = c.get(c.YEAR);
Integer week2 = c.get(c.WEEK_OF_YEAR);

if(year1 == year2) {
    if(week1 == week2) {
         //Do what you want here
    }
}

This should do it :D

Upvotes: 16

Viviano Cantu
Viviano Cantu

Reputation: 109

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

Upvotes: 0

velval
velval

Reputation: 3312

Just posting a slightly modified solution based on @FabianCook and as pointed out by @harshal his solution doesn't cater for two dates on different years but in the same week.

The modification is to actually set the DAY_OF_WEEK in both Calendar dates to point to Monday.....in this case both dates will be set to the same day even if they are in different years and then we can compare them.

Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
int year1 = cal1.get(Calendar.YEAR);
int week1 = cal1.get(Calendar.WEEK_OF_YEAR);

Calendar cal2 = Calendar.getInstance();
cal2.setTimeInMillis(/*Second date in millis here*/);
cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
int year2 = cal2.get(Calendar.YEAR);
int week2 = cal2.get(Calendar.WEEK_OF_YEAR);

if(year1 == year2 && week1 == week2){
    //Do what you want here
}

Upvotes: 4

Pritesh Mhatre
Pritesh Mhatre

Reputation: 4065

It's a java solution. Following code segment checks if two dates are within same week. It also covers edge cases, where week starts in one calendar year (December) and ends in next year (January).

Note: Code has a dependency on joda-time:

compile 'joda-time:joda-time:2.3'


public static boolean isSameWeek(final Date d1, final Date d2) {
    if ((d1 == null) || (d2 == null))
        throw new IllegalArgumentException("The date must not be null");

    return isSameWeek(new DateTime(d1), new DateTime(d2));
}

public static boolean isSameWeek(final DateTime d1, final DateTime d2) {
    if ((d1 == null) || (d2 == null))
        throw new IllegalArgumentException("The date must not be null");

    // It is important to use week of week year & week year

    final int week1 = d1.getWeekOfWeekyear();
    final int week2 = d2.getWeekOfWeekyear();

    final int year1 = d1.getWeekyear();
    final int year2 = d2.getWeekyear();

    final int era1 = d1.getEra();
    final int era2 = d2.getEra();

    // Return true if week, year and era matches
    if ((week1 == week2) && (year1 == year2) && (era1 == era2))
        return true;

    // Return false if none of the conditions are satisfied
    return false;
}

Test case:

public class TestDateUtil {

@Test
public void testIsSameWeek() {

    final DateTime d1 = new DateTime(2014, 12, 31, 0, 0);
    final DateTime d2 = new DateTime(2015, 1, 1, 0, 0);
    final DateTime d3 = new DateTime(2015, 1, 2, 0, 0);
    final DateTime d4 = new DateTime(2015, 1, 8, 0, 0);

    assertTrue(isSameWeek(d1, d2));
    assertTrue(isSameWeek(d2, d1));

    assertTrue(isSameWeek(d2, d3));
    assertTrue(isSameWeek(d3, d2));

    assertFalse(isSameWeek(d2, d4));
    assertFalse(isSameWeek(d4, d2));

    assertFalse(isSameWeek(d1, d4));
    assertFalse(isSameWeek(d4, d1));

}
}

Upvotes: 1

Oleg Mikheev
Oleg Mikheev

Reputation: 17444

You can get the week number for your date using c.get(Calendar.WEEK_OF_YEAR) and compare the results for your two dates.

Also accessing constants via instance variables (c.YEAR) is not recommended - access them using classes (Calendar.YEAR).

Upvotes: 5

Related Questions