Android 使用非公历

Android Use Non-Gregorian Calendars

我正在创建一个 DatePickerDialogFragment 用户将 select 出生日期。我想确保我可以处理非公历的日期。我无法更改要在我的设备上使用的日历类型。 Android 是否允许用户切换日历类型?如果有,步骤是什么?到目前为止,我在设置中没有成功。

Android 似乎不支持任何其他日历。实际上Calendarclass只有一个直接子class:GregorianCalendar.

请参阅 Android API 参考 Calendar class。

要支持 DatePickerDialogFragment 中的其他日历,您必须自己实施。

关于非公历的选择器对话框的图形用户界面,您真的必须从头开始自己实现它。以下说明是关于其他日历的普遍可用性。

Android 在 API 级别 24

之前的旧状态

好吧,在这里我们(再次)看到 Oracle 和 Android 之间的区别。如果您查看 source of older Android code,那么您只会看到正在实例化的公历:

991     public static synchronized Calendar getInstance() { 
992         return new GregorianCalendar(); 
993     } 

这与 Oracle-Java 所做的相反,在 java.util.Calendar 的基础上描述了两个替代日历(可通过语言环境或 unicode-ca-extension 选择):ThaiBuddhist (仅 1940 年后正确)和 JapaneseImperial(明治时代以来)。

Android-N(API-24级)

但是,从 API-level 24 (Android-N) 开始,Google 引入了从 ICU4J 项目取代的新日历。这些日历可以在包 android.icu.util:

中找到
  • 佛教(1940年后才正确)
  • 中文(有准确性问题)
  • 科普特
  • 埃塞俄比亚
  • 希伯来语
  • 印度(萨卡)
  • 伊斯兰教(4 种变体)
  • 日语(仅供现代使用)
  • 台湾(民国)

Android的当前状态(API-26级或更高)

引入了新的java.time-API,因此合并了以下四个非公历:

  • 伊斯兰-Umalqura(沙特阿拉伯)
  • 日语(仅限明治时代,从 1872 年起)
  • 民国(台湾)
  • 泰国佛教(1940年后才正确)

备选方案?

现实地说,主要有三个第 3 方库承诺为旧的 Android 版本提供替代日历。

=> Threeten-ABP

这是 Java-8 中内置的新时间库的后向端口的薄包装,它引入了 4 个部分新的日历:Islamic-Umalqura(沙特阿拉伯)、Minguo(台湾)、ThaiBuddhist(仅在 1940 年后更正)和日语(仅自明治时代起)。

如果Android开发者接受level 26+那么Threeten-ABP显然是不必要的。否则...

日本日历已在 v1.0.5 版本中修复。但是伊斯兰历仍然是一个负面惊喜,因为它不是 Umalqura 变体,而是与 Microsoft 科威特变体相当,并且只允许通过文件进行笨拙的配置(可在 Android???)。所有日历的另一个大问题是缺乏任何本地化支持,例如:

HijrahDate hd = HijrahDate.now();
System.out.println(DateTimeFormatter.ofPattern("yyyy-MMMM-dd").format(hd)); // 1437-Juli-13

伊斯兰教的第 7 个月正确地称为“Rajab”,而不是“July”(写这篇文章时我们现在是四月 post!)。如前所述,伊斯兰教日可能因伊斯兰历的变体而异,因此计算通常是错误的,这使得该库的整个伊斯兰历无法使用。


=> Joda-Time-Android

这是 Joda-Time 的包装器。它正式提供 8 pluggable calendars。术语“可插入”的意思是,您可以选择一个“年表”并使用此年表配置 LocalDate 类型的对象。

如果您仔细研究提供的日历,那么您会发现真正的非 iso-calendars(非公历)是:

  • 泰国佛教(1940年后才正确)
  • 科普特
  • 埃塞俄比亚
  • 伊斯兰教(没有 Umalqura,而是四种算法变体)
  • 朱利安

为了完整性,还有一个 bridge version(模拟公历和儒略历规则之间的简单切换)。

但是,本地化支持完全缺失,另见 this old issue. And since Joda-Time is officially in maintenance mode,我们不能合理地期待任何进一步的发展:

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).


=>我的图书馆Time4A

这是最大的库(不过 Proguard 可以帮助缩小它)。它提供以下日历:

  • 巴迪

  • 中文(自 1645 年起)

  • 科普特

  • Dangi(老韩语)

  • 埃塞俄比亚语(早上 6 点作为一天的开始)

  • 法国共和党人

  • 希伯来语(以日落作为一天的开始)

  • 印度教(带有 Dershowitz/Reingold 给出的变体)

  • 历史基督教(许多可配置变体)

  • 印度(萨卡)

  • 伊斯兰(Umalqura-沙特阿拉伯、Diyanet-土耳其、8 种算法变体、ICU 模拟、可自定义的日期调整、日落作为一天的开始)

  • 日语(自明治 6 年以前的中年起也有阴阳部分)

  • 主体(朝鲜)

  • 朱利安

  • 民国(台湾)

  • 波斯语

  • ThaiSolar(1941 年之前也有效)

  • 越南语

所有日历都提供广泛的 i18n 支持,主要基于 CLDR 数据。