2

First, let me walk you through the process.

I want to custom week calendar which i have made. It is work fine but problem is when i run same code in Samsung SM-T531 and Moto G it will return me previous Week.

Let me explain with code.

 public WeekCalendar(Context context) {
    this.mContext = context;

    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.setFirstDayOfWeek(Calendar.MONDAY);

    Log.e(TAG, "Formatted Current Date Before - " + format.format(calendar.getTime()));
    Log.e(TAG, "Current Date Before - " + calendar.getTime());

    calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

    Log.e(TAG, "Formatted Current Date After - " + format.format(calendar.getTime()));
    Log.e(TAG, "Current Date After - " + calendar.getTime());

    String[] days = new String[7];
    for (int i = 0; i < 7; i++) {

        days[i] = format.format(calendar.getTime());
        calendar.add(Calendar.DAY_OF_MONTH, 1);

        Log.e(TAG, "List days " + "" + days[i]);
    }

    weekDataModel.setDays(days);
    weekDataModel.setCurruntdate(Utility.getCurrentDate());

}

Output of This code

    Formatted Current Date Before - 2018-04-20
    Current Date Before - Fri Apr 20 15:25:58 GMT+05:30 2018

    Formatted Current Date After - 2018-04-09
    Current Date After - Mon Apr 09 15:25:58 GMT+05:30 2018

    List days 2018-04-09
    List days 2018-04-10
    List days 2018-04-11
    List days 2018-04-12
    List days 2018-04-13
    List days 2018-04-14
    List days 2018-04-15

Current date is 20-4-2018 from calendar.getTime() it is correct but after adding below line current date changed, i am not understand why it is happen.

calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

You can see my output before and after date.

Umesh AHIR
  • 738
  • 6
  • 20
  • 1
    As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use `java.time`, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Apr 20 '18 at 10:55
  • I cannot reproduce. On my computer I get `Formatted Current Date After - 2018-04-16` and then `Current Date After - Mon Apr 16 13:02:57 CEST 2018`. That is, the Monday in the same week. This agrees with [the documentation](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html). As I read it, `Calendar` should resolve the date from the fields `YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK`. – Ole V.V. Apr 20 '18 at 11:03
  • 1
    It could be some peculiarity (bug?) in the Android implementation of `Calendar`. And the difference between devices could be because of different versions of Android. Which versions have those devices got? – Ole V.V. Apr 20 '18 at 11:14
  • Similar: [Android Calendar problem with day of the week](https://stackoverflow.com/questions/7299621/android-calendar-problem-with-day-of-the-week) – Ole V.V. Apr 20 '18 at 11:22
  • I am using Samsung OS 5.0.2 and Moto G OS 6 which i am getting issue. – Umesh AHIR Apr 20 '18 at 12:11
  • Please edit the title to be more specific. – Basil Bourque Apr 21 '18 at 18:30

1 Answers1

3
    LocalDate date = LocalDate.now(ZoneId.of("Asia/Colombo"));
    System.out.println(date);

    WeekFields wf = WeekFields.ISO;
    // set to first day of week (Monday for ISO, Sunday for USA)
    date = date.with(wf.dayOfWeek(), 1);

    System.out.println(date);

Output today:

2018-04-21
2018-04-16

Please fill in your desired time zone if it didn’t happen to be Asia/Colombo.

I was assuming that you really wanted to iterate over the days of the current week, so the above snippet sets the date to the first day of the week. I have specified ISO weeks, that is, weeks that begin on Monday, so you will have the Monday of the same week. If you really just wanted the latest Monday, it would be more correct to use date = date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));.

The key to the definition of a week is the WeekFields object. Say that instead you wanted American weeks that begin on Sunday:

    WeekFields wf = WeekFields.SUNDAY_START;

With this change you get the Sunday instead:

2018-04-21
2018-04-15

Or to use weeks according to the device’s locale setting:

    WeekFields wf = WeekFields.of(Locale.getDefault(Locale.Category.DISPLAY));

For iteration use LocalDate.plusDays():

    WeekFields wf = WeekFields.ISO;
    date = date.with(wf.dayOfWeek(), 1);

    System.out.println(date);

    LocalDate[] days = new LocalDate[7];
    for (int i = 0; i < 7; i++) {

        days[i] = date;
        date = date.plusDays(1);

        System.out.println("List days " + "" + days[i]);
    }

Output:

2018-04-16
List days 2018-04-16
List days 2018-04-17
List days 2018-04-18
List days 2018-04-19
List days 2018-04-20
List days 2018-04-21
List days 2018-04-22

I am using and recommending java.time, the modern Java date and time API. The Calendar class is long outdated, and java.time is so much nicer to work with. An added advantage is that LocalDate.toString() gives you the date format you used, so you no longer need an explicit formatter (it’s ISO 8601 format). And if there’s a bug or similar in the Calendar implementation on some devices, you’re obviously free of that.

Question: Can I use java.time on Android?

Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26, I’m told) the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161