0

How to get next week dates if today is Sunday? I want get dates of Monday to Saturday of next week.

I am using following code get dates:

private String[] getDaysOfWeek() {
    String[] days = new String[6];
    SimpleDateFormat format = new SimpleDateFormat("dd");
    Calendar c = GregorianCalendar.getInstance();
    c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

    for (int i = 0; i < 6; i++) {
        if (i == 0) {
            days[i] = format.format(c.getTime());
        } else {
            c.add(Calendar.DATE, 1);
            days[i] = format.format(c.getTime());
        }
        System.out.println("DateTest" + days[i]);
    }
    return days;
}

It works fine when I set device Language english(US), but it returns previous week date if device is set to Language english(UK).

vinS
  • 1,417
  • 5
  • 24
  • 37
Joe
  • 550
  • 2
  • 11
  • 21
  • 1
    In the US, Sunday is the first day of the week. In the UK, Monday is. One might suspect that this somehow causes the different results. – Ole V.V. Dec 10 '17 at 09:35
  • 1
    As an aside, it’s simpler to keep the `i == 0` case outside the loop: `days[0] = …;` and then `for (int i = 1; …)`, and you won’t need the `if`-`else` statement inside the loop. – Ole V.V. Dec 10 '17 at 09:38
  • Do I understand correctly that no matter the current day-of.week you want the day-of-month of Monday through Saturday of current week, regarding Sunday as the first day of the week? – Ole V.V. Dec 10 '17 at 09:41
  • The different first days of the week are the problem. For US, we are currently already in week 50, because today is Sunday, which is the first week for Locals.US. In UK, we are still in "last week", i.e. week 49. If you would start your program tomorrow (on a Monday), the results would be equal. So what would be your expected result for each case? – Modus Tollens Dec 10 '17 at 09:45
  • 2
    FYI, you are using terribly troublesome old date-time classes now supplanted by the modern java.time classes. – Basil Bourque Dec 10 '17 at 16:31

2 Answers2

3

I recommend you use java.time, the modern Java date and time API also known as JSR-310, for non-trivial date operations like this one. Can you do that on a not-brand-new Android device? Most certainly! Get ThreeTenABP and start coding. This is the Android Backport of JSR-310. There is a thorough explanation in this question: How to use ThreeTenABP in Android Project.

private static String[] getDaysOfWeek() {
    String[] days = new String[6];
    DateTimeFormatter dayOfMonthFormatter = DateTimeFormatter.ofPattern("dd");
    LocalDate today = LocalDate.now(ZoneId.of("America/Montreal"));
    // go back to Sunday, then forward 1 day to get Monday
    LocalDate day = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY))
            .plusDays(1);
    days[0] = day.format(dayOfMonthFormatter);
    for (int i = 1; i < 6; i++) {
        day = day.plusDays(1);
        days[i] = day.format(dayOfMonthFormatter);
    }
    return days;
}

Calling this method today (Sunday, Dec 10 in Montréal) I get the day-of-week for the coming week:

[11, 12, 13, 14, 15, 16]

I changed my Mac’s regional setting from Denmark (Europe) to USA and got the same result.

Since it is never the same date in all time zones on Earth, I recommend giving explicit time zone for obtaining today’s date. Please substitute your desired time zone where I put America/Montreal. Can’t we use the device’s time zone setting? Maybe. You can use the JVM’s time zone setting (which is also what your code in the question tacitly does). I recommend you make that explicit in the code too by specifying ZoneId.systemDefault() as time zone. The JVM setting may be changed by other parts of your program or other programs running in the same JVM, however, so it is not guaranteed to give you the preference setting of the device.

One source for learning java.time is the Oracle tutorial. Your search engine can point you to many others.

PS I had expected that WeekFields.SUNDAY_START might have been helpful for this task, but I didn’t find a good way to use it for it. If anybody can spot something I missed, I’d be grateful for a hint.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Application should work on any country not specific to any country should I use LocalDate.now(ZoneId.systemDefault()); – Joe Dec 10 '17 at 11:15
  • @Joe I am still not sure what result you want to get. You want the next week days if today is Sunday, and that is exactly what your original code is providing. Only that "next week" may differ for locales. For what you specified, the code works, but I guess you expected a different result? – Modus Tollens Dec 10 '17 at 11:19
  • 1
    @Joe either that or you would have to have the user specify their desired time zone. For most applications I suppose that `LocalDate.now(ZoneId.systemDefault())` would be OK. – Ole V.V. Dec 10 '17 at 11:30
  • 1
    @Joe You cannot get the same result simultaneously around the world. Times zones range over 26 hours, possibly 27 with anomalies like Daylight Saving Time. For any given moment, the date varies around the globe by zone. Example: When Christmas begins in India after midnight on the 25th of December, in Québec it is still “yesterday”, Christmas Eve on the 24th. So you **must specify a desired/expected time zone** to provide a context for the date and therefore a day-of-week. – Basil Bourque Dec 10 '17 at 16:30
  • @OleV.V. Regarding `WeekFields.SUNDAY_START`, the Question seems to be written in ISO 8601 standard (Monday-Sunday, where Monday is first day of week) with wording that says Monday is *next* week after this Sunday. So [`WeekFields.ISO`](https://docs.oracle.com/javase/9/docs/api/java/time/temporal/WeekFields.html#ISO) is appropriate, not `WeekFields.SUNDAY_START`. – Basil Bourque Dec 10 '17 at 22:56
0

The Answer by Ole V.V. is correct and useful:

  • You should be using java.time classes. Never use Calendar.
  • Use TemporalAdjusters.previousOrSame to get the date of the next desired day of the week. Or TemporalAdjusters.nextOrSame depending on your business logic which is not clear in your Question.

Stream from LocalDate::datesUntil

If you want to get fancy, you could replace the for loop in that Answer with a Stream using the LocalDate.datesUntil method added in Java 9 and later.

Get today, and from there the next Monday.

LocalDate today = LocalDate.now( ZoneId.of( "Pacific/Auckland" ) ) ;
LocalDate nextOrSameMonday = today.with( TemporalAdjusters.nextOrSame( DayOfWeek.MONDAY ) ) ;

Make a stream of the dates of that week.

Stream<LocalDate> stream = nextOrSameMonday.datesUntil( nextOrSameMonday.plusWeeks( 1 ) ) ;

Collect stream to a List.

List< LocalDate > dates = stream.collect( Collectors.toList() ) ;

Dump to console.

System.out.println( dates ) ;

[2019-04-08, 2019-04-09, 2019-04-10, 2019-04-11, 2019-04-12, 2019-04-13, 2019-04-14]

If you want just the day number:

for ( LocalDate date : dates )
{
    System.out.println( date.getDayOfMonth() );
}

Or alter the stream handling to collect a list of integer numbers, the day of month numbers.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154