在 java 中将 Jalali 日历转换为格鲁吉亚日历

Convert Jalali calendar to Georgian in java

我正在使用 class shown in this Question to convert Jalali (shamsi) 格鲁吉亚语日期。

然后使用以下命令,我将回历日期转换为格鲁吉亚

Date dt = JalaliCalendar.getGregorianDate("1397/01/14");
    Toast.makeText(getApplicationContext(), dt.toString(), Toast.LENGTH_LONG).show();

我要显示结果如下:2018/04/03

尝试使用 SimpleDateFormatter 如下:

    DateFormat df= new SimpleDateFormat( "YYYY/MM/dd" );
    String formattedDate = df.format(dt);

警告: 除了花了两分钟浏览维基百科页面外,我对这两者一无所知 Jalali calendar nor Hijri calendar。但我也许可以帮助您部分解决问题。

java.time

您正在使用多年前被 java.time classes 取代的麻烦的旧 date-time classes。

java.timeclasses 与 HijrahChronology implementation of Chronology 捆绑在一起。

建议:实施java.time.chrono.Chronology

我没有看到 Chronology for the Jalali calendar either bundled with java.time nor in the ThreeTen-Extra project that does provide other chronologies 的任何实现。

我想如果有人确实贡献了这样的实现可能是理想的。也许可以按照 HijrahChronology 与 Java.

捆绑在一起的示例来编写这样的实现

回历(不是贾拉利语)

这是我无知地尝试使用 HijrahDate class。

LocalDate ld = LocalDate.of( 2018, Month.APRIL , 3 ) ;  // Western calendar, defined in `IsoChronology` class:  https://docs.oracle.com/javase/10/docs/api/java/time/chrono/IsoChronology.html
HijrahDate hd = HijrahDate.from( ld  );  // Using class java.time.chrono.HijrahChronology  https://docs.oracle.com/javase/10/docs/api/java/time/chrono/HijrahChronology.html

ld.toString(): 2018-04-03

hd.toString(): Hijrah-umalqura AH 1439-07-17

Iranian Calendar Converter 页面所示,这似乎适用于回历。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes.

从哪里获得java.time classes?

  • Java SE 8, Java SE 9,及以后
    • Built-in。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
    • java.time 的大部分功能是 back-ported 到 Java ThreeTen-Backport 中的 6 和 7。
  • Android
    • Android java.time classes.
    • 捆绑实施的更高版本
    • 对于较早的 Android (<26),ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

使用我的库 Time4J(或 Android 上的 Time4A)启用以下开箱即用的简短解决方案:

String input = "1397/01/14";
PersianCalendar jalali =
    ChronoFormatter
        .ofPattern("yyyy/MM/dd", PatternType.CLDR, Locale.ROOT, PersianCalendar.axis())
        .parse(input);
PlainDate gregorian = jalali.transform(PlainDate.axis());
String iso8601 = Iso8601Format.EXTENDED_DATE.format(gregorian);
System.out.println(iso8601); // 2018-04-03

无需实现自己的日历年表(这通常是一项复杂的任务)。如果你想用斜线而不是 ISO-format 得到结果,那么只需使用另一个格式化程序:

String output = ChronoFormatter
        .ofPattern("yyyy/MM/dd", PatternType.CLDR, Locale.ROOT, PlainDate.axis())
        .format(gregorian);

更新评论中的问题:

如果输入包含时间部分,那么整个事情就是时间戳而不是日历日期。所以用户可以改为解析片刻。

TZID tzid = () -> "Asia/Tehran"; // used as default time zone for parsing
ChronoFormatter<Moment> f =
  ChronoFormatter.setUpWithOverride(Locale.ENGLISH, PersianCalendar.axis())
    .addPattern("yyyy/MM/dd HH:mm[:ss]", PatternType.CLDR) // optional seconds
    .build()
    .withTimezone(tzid);
Moment expected =
  PlainTimestamp.of(2018, 4, 3, 10, 15, 5).inTimezone(tzid);
assertThat(
  f.parse("1397/01/14 10:15:05"),
  is(expected));

解析后的时刻可以通过这种方式转换回波斯历:

assertThat(
  expected.toGeneralTimestamp(PersianCalendar.axis(), tzid, StartOfDay.MIDNIGHT).toDate(),
  is(PersianCalendar.of(1397, 1, 14)));