4

我想验证回历日期。在我的应用程序中,回历日期将采用dd/MM/YYYY. 我想在 Joda Time API 中验证日期是否有效。

例如,我有日期:

String date = "30/02/1403";
String Pattern = "dd/MM/YYYY";

你能帮我验证回历日期吗?

我的限制是:

  • 我想在 Java 6 中验证。我不能在 Java 8 中使用。
  • 我必须用伊斯兰日历验证。用回历日期验证。我的日期已经是回历格式。我必须使用伊斯兰日历验证该日期是否有效。
  • 在伊斯兰历 1403 年 2 月 30 日是第二个月的有效日期。
4

3 回答 3

7

java.time

java.time,现代 Java 日期和时间 API,可以这样做:

    DateTimeFormatter hijrahFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
                .withChronology(HijrahChronology.INSTANCE);
    try {
        HijrahDate date = hijrahFormatter.parse("30/02/1403", HijrahDate::from);
        System.out.println("A valid date: " + date);
    } catch (DateTimeParseException dtpe) {
        System.out.println("Not a valid date: " + dtpe.getMessage());
    }

此代码段的输出是:

有效日期:Hijrah-umalqura AH 1403-02-30

格式模式字母区分大小写。您需要小写yyyy日历年(或uuuu预测年)。

爪哇6?三个选项。

我想在 Java 6 中验证。我不能在 Java 8 中使用。

现在已经过时了(Java 11 已经发布)。我的建议是:

  1. 使用 ThreeTen Backport,它是 java.time 到 Java 6 和 7 的反向移植。事实证明,它并不适合您的情况,但您可以。
  2. 正如您从一开始就询问的那样,使用 Joda-Time。
  3. 使用 Time4J。

不过,前两个选项将拒绝您的日期 30/02/1403,但相信 1403 年的第二个月只有 29 天。

ThreeTen 后端口

    DateTimeFormatter hijrahFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
            .withChronology(HijrahChronology.INSTANCE);
    String dateString = "30/02/1403";
    try {
        TemporalAccessor parsed = hijrahFormatter.parse(dateString);
        HijrahDate date = HijrahChronology.INSTANCE.date(parsed.get(ChronoField.YEAR),
                parsed.get(ChronoField.MONTH_OF_YEAR),
                parsed.get(ChronoField.DAY_OF_MONTH));
        if (date.format(hijrahFormatter).equals(dateString)) {
            System.out.println("A valid date: " + date);
        } else {
            System.out.println("Not a valid date: " + dateString);
        }
    } catch (DateTimeParseException dtpe) {
        System.out.println("Not a valid date: " + dtpe.getMessage());
    }

输出:

无效日期:30/02/1403

根据我的理解,以下构造日期的更简单方法应该可以工作,但不能:

        HijrahDate date = HijrahDate.from(parsed);

我明白了org.threeten.bp.DateTimeException: Field not found: EpochDay。我构造日期的方式是宽松的,也就是说,它接受月份中的某天超出范围并生成Hijrah-umalqura AH 1403-03-01. 因此,为了完成验证,我将日期格式化,并要求我再次获取原始字符串。

如果不是30/02/1403我尝试使用29/02/1403,我得到

有效日期:Hijrah-umalqura AH 1403-02-29

乔达时间

    DateTimeFormatter islamicFormatter = DateTimeFormat.forPattern("dd/MM/yyyy")
            .withChronology(IslamicChronology.getInstance());
    try {
        LocalDate date = LocalDate.parse("30/02/1403", islamicFormatter);
        System.out.println("A valid date: " + date);
    } catch (IllegalArgumentException iae) {
        System.out.println("Not a valid date: " + iae.getMessage());
    }

Joda-Time 也认为这个月有 29 天,并非常清楚地表明:

无效日期:无法解析“30/02/1403”:dayOfMonth 的值 30 必须在 [1,29] 范围内

有一串29/02/1403我得到了:

有效日期:1403-02-29

Joda-Time 的伊斯兰年表有四种不同的闰年模式。我尝试了所有四个。它们都在 1403 年的第二个月产生了 29 天。对不起,这是我能得到的最接近的结果。

来自 Joda-Time 主页:

请注意,Joda-Time 被认为是一个基本上“完成”的项目。没有计划进行重大改进。如果使用 Java SE 8,请迁移到java.time(JSR-310)。

时间4J

我建议您参考 Time4J 的作者 Meno Hochschild 的知识渊博的回答。在我看来,Time4J 3.50 版根据您的要求和 Java 6 解决了您的问题。

但是那个日期是否有效?

但是,如果您检查伊斯兰日历,则它是第 2 个月的有效日期。

你比我更专业。我似乎理解回历的变体存在。根据您的变体 30/02/1403 是一个完全有效的日期。alhabib Islam web services 提供的版本与您的一致:Safar 30, 1403 与公历 1982 年 12 月 16 日是同一天。另一方面,根据 searchtruth.com,Safar 1403 月份只有 29 天(Safar 29, 1403 对应于公历 1982 年 12 月 15 日,随后是 Rabi Al-Awwal 1, 1403 对应于 12 月 16 日)。

链接

于 2018-11-13T09:21:03.633 回答
2

作为对 Ole 答案的补充,我在这里列举了一些回历日历的变体和使用我的 lib Time4J 的验证结果,它为变体提供了更多支持,还提供了额外的静态验证方法

String variant;
for (HijriAlgorithm ha : HijriAlgorithm.values()) {
    variant = ha.getVariant();
    System.out.println(variant + "=>" + HijriCalendar.isValid(variant, 1403, 2, 30));
}
variant = HijriCalendar.VARIANT_DIYANET;
System.out.println(variant + "=>" + HijriCalendar.isValid(variant, 1403, 2, 30));
variant = HijriCalendar.VARIANT_UMALQURA;
System.out.println(variant + "=>" + HijriCalendar.isValid(variant, 1403, 2, 30));

输出是:

伊斯兰东c=>假

伊斯兰东=>假

伊斯兰公民=>假

伊斯兰-tbla=>假

伊斯兰法蒂玛=>假

伊斯兰法蒂米达=>假

伊斯兰-habashalhasibc=>假

伊斯兰-habashalhasiba=>假

伊斯兰-diyanet=>真

伊斯兰-umalqura=>真

所以我们可以看到回历的所有算法变体都不支持您的期望,但 diyanet 和 umalqura 变体。可能您想要 umalqura 变体(沙特阿拉伯的官方日历,但如果您有更多关于您的期望的详细信息,请澄清)。

关于您希望使用 Joda-Time 解决问题的愿望,抱歉,没有机会验证 1403-02-30 是否有效,因为 Joda-Time 仅支持四种算法变体(作为 Time4J 支持的子集)。对于只支持“islamic-tbla”(或“islamic-civil”——这里的 API 没有很好的文档记录)的 Threeten-Backport 也可以这样说。-packagejava.time也仅支持一种变体,但该变体 (umalqura) 符合您的期望。但是,java.time不能在 Java 6 上运行。

如果您愿意考虑替代 Joda-Time 来满足您对验证的期望,那么我主要看到两种方法:

于 2018-11-14T05:32:58.523 回答
-1

这就是我使用的:

//import the regex class

#import java.util.regex.*;

Add the below inside your main class.

String pattern = "(?:[0-2]\d)|(?:30)\/[0-1]\d\/14\d{2}";

if(Pattern.matches(pattern, yourdate)) {
    System.out.println("hijra date");
}
于 2018-11-13T09:04:06.040 回答