23

I have the following code for getting the last Sunday before the current date:

Calendar calendar=Calendar.getInstance();
calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR)-1);
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
Log.e("first day", String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));

But this code doesn't work. Please, tell me, how can I fix it?

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
malcoauri
  • 11,904
  • 28
  • 82
  • 137
  • 1
    What exactly does 'this code doesn't work' mean, e.g. any exceptions? – home Oct 08 '12 at 13:50
  • No, it shows me incorrect date. Sorry. – malcoauri Oct 08 '12 at 13:52
  • Sunday is the first day of the week in certain locales - is that your issue? It would be nice with an example to show what is wrong. – Anders R. Bystrup Oct 08 '12 at 13:55
  • Have a look at this example: http://stackoverflow.com/questions/12369844/joda-time-get-first-second-last-sunday-of-month, the question is very similar. – dngfng Oct 08 '12 at 14:01
  • 1
    If you are on a Sunday, which Sunday you want then?? Current or the last one?? – Rohit Jain Oct 08 '12 at 14:01
  • 1
    Using your code, it shows me the correct answer today (i.e it prints 7th October 2012). Doesn't mean it is generally correct. – Duncan Jones Oct 08 '12 at 14:05
  • I have just used it in simple Java application and it works, but I'm developing the Android application, and it shows the next (not last) Sunday. – malcoauri Oct 08 '12 at 14:07
  • 1
    What Android version are you testing this on? It looks like there's a bug in `Calendar.get(Calendar.WEEK_OF_YEAR)` in Android version < 2.2 (Froyo). See http://www.anddev.org/other-coding-problems-f5/calendar-returns-wrong-week-of-year-in-api-8-t49274.html – David Wasser Oct 08 '12 at 14:47
  • FYI, the terribly flawed date-time classes such as `java.util.Date`, `java.util.Calendar`, & `java.text.SimpleDateFormat` are now legacy, supplanted by [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) classes. Most *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android (<26) in [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP). See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Jan 23 '20 at 01:14

7 Answers7

37

java.time.temporal.TemporalAdjuster

This can be easily achieved by a TemporalAdjuster implementation found in TemporalAdjusters along with the DayOfWeek enum. Specifically, previous​(DayOfWeek dayOfWeek).

 LocalDate
 .now()
 .with(
     TemporalAdjusters.previous( DayOfWeek.SUNDAY )
 ) ;

If today is Sunday and you would like the result to be today rather than a week ago, call previousOrSame​(DayOfWeek dayOfWeek).

 LocalDate
 .now()
 .with(
     TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY )
 ) ;

These classes are built into Java 8 and later, and built into Android 26 and later. For Java 6 & 7, most of the functionality is back-ported in ThreeTen-Backport. For earlier Android, see ThreeTenABP.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Grzegorz Gajos
  • 2,253
  • 19
  • 26
27

This will work. We first get the day count, and then subtract that with the current day and add 1 ( for sunday)

Calendar cal=Calendar.getInstance();
cal.add( Calendar.DAY_OF_WEEK, -(cal.get(Calendar.DAY_OF_WEEK)-1)); 
System.out.println(cal.get(Calendar.DATE));

Edit : As pointed out by Basil Bourque in the comment, see the answer by Grzegorz Gajos for Java 8 and later.

Jimmy
  • 2,589
  • 21
  • 31
  • 1
    FYI: The `Calendar` class is now outmoded, legacy. For modern solution, see Answer by [Grzegorz Gajos](https://stackoverflow.com/a/43410239/642706). – Basil Bourque Jan 23 '20 at 01:26
  • 1
    Thanks for bringing the attention @BasilBourque, I updated my answer with a link to the solution. – Jimmy Jan 23 '20 at 16:23
6

You could iterate back in steps of one day until you arrive on a Sunday:

Calendar cal = Calendar.getInstance();
while (cal.get( Calendar.DAY_OF_WEEK ) != Calendar.SUNDAY)
    cal.add( Calendar.DAY_OF_WEEK, -1 );

or, in only one step, substract the difference in days between sunday and now:

Calendar cal = Calendar.getInstance();
int dayOfTheWeek = cal.get( Calendar.DAY_OF_WEEK );
cal.add( Calendar.DAY_OF_WEEK, Calendar.SUNDAY - dayOfTheWeek );
dapek
  • 291
  • 1
  • 4
1
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(cal.getTimeInMillis() //
     // Saturday is the 7th day of week, so use modulo to get it : remove day between todoay
     - (( cal.get(Calendar.DAY_OF_WEEK) % 7) * 86400000)); // 86400000=24*60*60*1000

System.out.println(cal.getTime());
. . .
cl-r
  • 1,264
  • 1
  • 12
  • 26
0

The following works for me irrespective of which month and year.

 Calendar cal = Calendar.getInstance(TimeZone.getDefault());
 Date date = cal.getTime();
 int days = cal.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
 date.setTime(date.getTime() - (long) (days*1000*60*60*24));
 cal.setTime(date);
Viswanath Lekshmanan
  • 9,945
  • 1
  • 40
  • 64
0

Here is a snippet to calculate any last day of the week with Joda:

import org.joda.time.DateTime
import org.joda.time.DateTimeConstants

DateTime now = DateTime();
int offset = ((now.dayOfWeek - DateTimeConstants.THURSDAY) + 7) % 7;
DateTime lastThursday = now.minusDays(offset);

Just replace DateTimeConstants.THURSDAY with your day of choice.

Oxymoron
  • 1,380
  • 2
  • 19
  • 47
linqu
  • 11,320
  • 8
  • 55
  • 67
0

Here's how to do it with a Kotlin extension and the Joda Time library.
Answer is based on linqu's answer but this also fixes a bug in that answer. The bug was that it did not work if the current date was the same day you're trying to get.

/**
 * E.g., DateTimeConstants.SUNDAY
 */
fun DateTime.previousDayOfWeek(day: Int): DateTime {
    var date = this
    if(date.dayOfWeek == day) date = date.minusDays(1)

    val offset = (date.dayOfWeek - day + 7) % 7
    return date.minusDays(offset)
}

fun DateTime.previousSunday(): DateTime {
    return previousDayOfWeek(DateTimeConstants.SUNDAY)
}
Markymark
  • 2,804
  • 1
  • 32
  • 37
  • FYI: The [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode). Its creator, [Stephen Colebourne](https://stackoverflow.com/users/38896/jodastephen), went on to lead [JSR 310](https://jcp.org/en/jsr/detail?id=310) defining the [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) classes built into Java 8+. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 23 '20 at 01:13