I'm creating a DatePickerDialogFragment
where the user will select date of birth. I am wanting to make sure I can handle dates which are non-gregorian. I have not been able to change which type of calendar to use on my device. Does Android give the user the capability to switch the calendar type? If so what are the steps? I have had no success in the settings so far.
问题:
回答1:
Android does not seem to support any other calendars. In fact, the Calendar
class only has one direct subclass: GregorianCalendar
.
See the Android API reference for the Calendar class.
For supporting another calendar in the DatePickerDialogFragment
you will have to implement it yourself.
回答2:
About the graphical user interface of a picker dialog for a non-gregorian calendar, you have really to implement it yourself from the scratch. The following notes are about the general availability of other calendars.
Old status of Android before API-level 24
Well, here we see (again) a difference between Oracle and Android. If you look at the source of older Android code then you see only the gregorian calendar being instantiated:
991 public static synchronized Calendar getInstance() {
992 return new GregorianCalendar();
993 }
This is in contrast to what Oracle-Java does where two alternative calendars are described on the base of java.util.Calendar
(selectable by locale or unicode-ca-extension): ThaiBuddhist (correct after 1940 only) and JapaneseImperial (since Meji-era).
Android-N (API-level 24)
However, starting with API-level 24 (Android-N), Google has introduced new calendars overtaken from ICU4J-project. These calendars can be found in the package android.icu.util:
- Buddhist (correct only after 1940)
- Chinese (with accuracy problems)
- Coptic
- Ethiopic
- Hebrew
- Indian (Saka)
- Islamic (4 variants)
- Japanese (use for modern times only)
- Taiwan (Minguo)
Current status of Android (API-level 26 or higher)
The new java.time
-API has been introduced, so following four non-gregorian calendars have been incorporated:
- Islamic-Umalqura (Saudi-Arabia)
- Japanese (since Meji era only, from 1872 onwards)
- Minguo (Taiwan)
- ThaiBuddhist (correct only after 1940)
Alternatives?
To be realistic, there are mainly three 3rd-party libraries which promise to offer alternative calendars also for older Android versions.
=> Threeten-ABP
This is a thin wrapper around the backport of new time library built into Java-8 which has introduced 4 partially new calendars: Islamic-Umalqura (Saudi-Arabia), Minguo (Taiwan), ThaiBuddhist (correct only after 1940) and Japanese (since Meji era only).
If Android developers accept the level 26+ then Threeten-ABP is obviously unnecessary. Otherwise...
The Japanese calendar has been fixed in version v1.0.5. But the islamic calendar is still a negative surprise because it is NOT the Umalqura-variant but rather comparable to Microsoft Kuwaiti variant and only allows an awkward configuration via a file (accessible on Android???). Another big problem of all calendars is the lack of any localization support, example:
HijrahDate hd = HijrahDate.now();
System.out.println(DateTimeFormatter.ofPattern("yyyy-MMMM-dd").format(hd)); // 1437-Juli-13
The 7th islamic month is correctly called "Rajab", not "July" (and we are now in April at the time of writing this post!). And as said before, the islamic day can vary dependent on the variant of islamic calendar so the calculation is often wrong which makes the whole islamic calendar of this library unuseable.
=> Joda-Time-Android
This is a wrapper around Joda-Time. It officially offers 8 pluggable calendars. The term "pluggable" means, you can choose a "chronology" and configure an object of type LocalDate
with this chronology.
If you carefully study the offered calendars then you will see that the real non-iso-calendars (non-gregorian) are:
- ThaiBuddhist (correct only after 1940)
- Coptic
- Ethiopic
- Islamic (no Umalqura, instead four algorithmic variants)
- Julian
For completeness, there is also a bridge version (modelling a simple switch between gregorian and julian calendar rules).
But again, localization support is completely missing, see also this old issue. And since Joda-Time is officially in maintenance mode, we cannot reasonably expect any further development:
Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).
=> my library Time4A
This is the biggest library (Proguard can help to shrink it however). It offers following calendars:
- Badi
- Chinese (since 1645)
- Coptic
- Dangi (old Korean)
- Ethiopic (with 6am as start of day)
- French Republican
- Hebrew (with sunset as start of day)
- Historic Christian (many configurable variants)
- Indian (Saka)
- Islamic (Umalqura-Saudi-Arabia, Diyanet-Turkey, 8 algorithmic variants, ICU-simulation, customizable day adjustments, sunset as start of day)
- Japanese (also with lunisolar part since midage before Meiji 6)
- Juche (North Korea)
- Julian
- Minguo (Taiwan)
- Persian
- ThaiSolar (also valid before 1941)
- Vietnamese
All calendars offer wide i18n-support mostly based on CLDR-data.