在Java 6上验证回历日期(伊斯兰日历)

时间:2018-11-13 08:53:23

标签: java validation jodatime java-6 hijri

我想确认回历日期。在我的应用程序中,回历日期将以dd/MM/YYYY的格式出现。我想验证日期在Joda Time API中是否有效。

例如,我有日期:

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

能帮我确认回历吗?

我的限制是:

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

3 个答案:

答案 0 :(得分:6)

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

Java 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 Backport

    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());
    }

输出:

  

无效日期:140/02/30

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

        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

Joda-Time

    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的伊斯兰编年史带有四种不同的leap年模式。我尝试了全部四个。它们在1403年第二个月全都产生了29天。很抱歉,这与我能得到的接近。

在Joda-Time主页上:

  

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

Time4J

我请您参考Time4J的作者Meno Hochschild的见多识广的答案。在我看来,Time4J 3.50版可以根据您的要求和Java 6解决您的问题。

但是那个日期有效吗?

  

但是,如果您要查看伊斯兰日历,则该日期为第二个月的有效日期。

您比我更是专家。我似乎了解回历日历的变体存在。根据您的变体,30/02/1403是一个完全有效的日期。 alhabib伊斯兰网络服务给出的版本与您的观点一致:1403年的萨法尔(Safar 30)与公历中的1982年12月16日是同一天。另一方面,根据searchtruth.com,Safar 1403月只有29天(Safar 29,1403对应于1982年12月15日,格里高利安,其后是Rabi Al-Awwal 1,1403对应于12月16日)。

链接

答案 1 :(得分:2)

作为对Ole答案的补充,我在这里使用我的lib Time4J列举了Hijri日历的一些变体和验证结果,它为变体提供了更多支持,并且还提供了额外的static validation method

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

输出为:

  

islamic-eastc => false

     

islamic-easta => false

     

islamic-civil => false

     

islamic-tbla => false

     

islamic-fatimidc => false

     

islamic-fatimida =>假

     

islamic-habashalhasibc => false

     

islamic-habashalhasiba =>假

     

islamic-diyanet => true

     

islamic-umalqura =>是

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

关于您希望解决Joda-Time问题的希望,对不起,没有机会验证1403-02-30是否有效,因为Joda-Time仅支持四个算法变体(作为Time4J支持的子集)。对于Threeten-Backport来说也是如此,后者仅支持“ islamic-tbla”(或“ islamic-civil”-这里没有充分记录该API)。 java.time软件包也仅支持一个变体,但是该变体(umalqura)符合您的期望。但是,java.time不能在Java 6上运行。

如果您愿意考虑Joda-Time的替代方案,该替代方案符合您对验证的期望,那么我主要看到两种方式:

  • 我的库Time4J(在Java 6 + 7上运行的反向版本v3.50)
  • msarhan

答案 2 :(得分:-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");
}