Setting Calendar fields in Android

2019-08-20 15:59发布

问题:

setting the day field in a calendar using

    myCalender.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);

does is put set the day to the next Friday or the past Friday or maybe the closest?

Also what if I don't set the year or any other field for the calendar, what are the default values?

回答1:

Neither. Yet. It’s complicated. But don’t use Calendar, see below.

From the documentation of the two-arg set method:

Sets the given calendar field to the given value. The value is not interpreted by this method…

So during this call it just sets the day-of-week field to Friday. The year, month and day-of-month stay the same, that is, the date isn’t effectively changed. Yet.

If and when the Calendar eventually computes and resolves its fields,

If there is any conflict in calendar field values, Calendar gives priorities to calendar fields that have been set more recently. The following are the default combinations of the calendar fields. The most recent combination, as determined by the most recently set single field, will be used.

If you have only set the day of week (which will likely have introduced a conflict with the other fields), the following combination applies:

YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK

So it will pick the Friday in the same week.

What defines a week is determined by the Calendar’s first-day-of-week field. Its initial value is determined by the Calendar’s locale, and you can control it through getFirstDayOfWeek() and setFirstDayOfWeek(). This in turn means that the default behaviour for a Calendar in a European locale previously set to a Sunday will go back to the previous Friday, whereas a Calendar in the US locale would pick the next Friday instead.

If you have also set other fields after setting the day-of-week but before fields are calculated, it is a different story.

Default values?

Generally the default values of Calendar fields are current date and time in your JVM’s time zone (usually, but not always, the same as your device’s time zone).

You don’t need to care

The good news is that you don’t need to care. The Calendar class is long outmoded anyway, and it was also (seen in retrospect) poorly designed, so you should not use it. Instead use java.time, the modern Java date and time API. It is so much nicer to work with. Depending on your need, you may for example use LocalDate for a date or ZonedDateTime for a date and time of day with time zone.

The modern classes offer you a great deal of better clarity and more flexibility. For example:

    LocalDate ld = LocalDate.now(ZoneId.of("Pacific/Saipan"));

    // the following calls do what the method names say
    ld = ld.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
    ld = ld.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));
    ld = ld.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
    ld = ld.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY));

    // set to Friday in the same ISO week
    ld = ld.with(ChronoField.DAY_OF_WEEK, DayOfWeek.FRIDAY.getValue());

    // set to Friday in the same US week
    ld = ld.with(WeekFields.SUNDAY_START.dayOfWeek(), 
            DayOfWeek.FRIDAY.get(WeekFields.SUNDAY_START.dayOfWeek()));

Question: Can I use java.time on Android?

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

  • In Java 8 and later and on new Android devices (from API level 26, I’m told) the new API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310, where the modern API was first described).
  • On (older) Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. Make sure you import the date and time classes from package org.threeten.bp and subpackages.

Links

  • Oracle tutorial: Date Time, explaining how to use java.time.
  • ThreeTen Backport project
  • ThreeTenABP, Android edition of ThreeTen Backport
  • Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
  • Java Specification Request (JSR) 310.


回答2:

Its will be nex Friday

Friday, 23 February 2018 year., 20:44:17.353

Default values is this Year



回答3:

what are the default values

 Calendar rightNow = Calendar.getInstance(); //the default is the current time/date

next Friday or the past Friday or maybe the closest?

next time/date, therefore, the answer is next Friday.

see the documentation



回答4:

it turns out that using myCalender.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY) is a complete mess, it may set the day to next or the past Friday, I have been trying a lot but couldn't figure the logic!

Anyway, all I needed was to set the calendar to a particular day in the next week, and I managed to do this using the answer to that question ..

set the calendar to next Thursday