简体   繁体   English

具有未知日、月和/或年的 Java 日期实现

[英]Java Date implementation with unknown day, month and/or year

Some real people do not know what day, month or even year they were born.有些真人不知道自己是哪一天、哪一月甚至哪一年出生的。

This can pose a problem for systems that require a full date of birth.这可能会给需要完整出生日期的系统带来问题。

In the Netherlands the decision was made to code these birthdates with unknowns .在荷兰,决定用未知数对这些生日进行编码。 The following is the birthdate of someone born in 1975, exact date unknown:以下是 1975 年出生的人的生日,确切日期不详:

00-00-1975

How can I handle this in Java?我如何在 Java 中处理这个问题? I'm not asking about parsing a string of "00-00-1975" but an actual date implementation that supports unknown (maybe null?) values.我不是在问解析字符串“00-00-1975”,而是一个支持未知(可能为空?)值的实际日期实现。

Thankfully, decision-makers wisened up in 2014, and now people with an unknown date of birth are given a made-up date.值得庆幸的是,决策者在 2014 年明智了,现在出生日期不详的人得到了一个确定的日期。 https://www.binnenlandsbestuur.nl/bestuur-en-organisatie/nieuws/niet-bestaande-geboortedatum-00-00-jj-blijft.9484714.lynkx https://www.binnenlandsbestuur.nl/bestuur-en-organisatie/nieuws/niet-bestaan​​de-geboortedatum-00-00-jj-blijft.9484714.lynkx

No, no such thing.不,没有这种事。 You can implement your own, eg您可以实现自己的,例如

interface Birthday {
    Optional<LocalDate> fullDate();
    Year year();
}

class UnknownBirthday implements Birthday {
    private final Year year;
    // ctor

    @Override
    public Year year() {
        return year;
    }

    @Override
    public Optional<LocalDate> fullDate() {
        return Optional.empty();
    }
}

class KnownBirthday implements Birthday {
    private final LocalDate date;
    // ctor
    
    @Override
    public Optional<LocalDate> fullDate() {
        return Optional.of(date);
    }

    @Override
    public Year year() {
        return Year.of(date.getYear());
    }
}

One option is to exploit the TemporalAccessor interface.一种选择是利用TemporalAccessor接口。 Nearly all of the date and time classes of java.time implement this interface and certainly those classes that you would use for your uncertain birthdays.几乎所有 java.time 的日期和时间类都实现了这个接口,当然还有那些您将在不确定的生日时使用的类。 Declare a variable a TemporalAccessor , and you may assign a Year or a LocalDate or some other type to it.将变量声明为TemporalAccessor ,您可以为其分配YearLocalDate或其他类型。

Some programmers would be tempted to use instanceof a lot with such a variable, which may be considered not so nice.一些程序员会很想对这样的变量使用instanceof很多,这可能被认为不太好。 Fortunately for many purposes it also isn't necessary.幸运的是,出于许多目的,它也不是必需的。 The isSupported method of TemporalAccessor can be used in most situations. TemporalAccessorisSupported方法可以在大多数情况下使用。

For a demonstration:演示:

    // Example birthdays ordered from the best known to the completely unknown
    TemporalAccessor[] birthdays = {
            LocalDate.of(1955, Month.MARCH, 22),
            YearMonth.of(1978, Month.MAY),
            Year.of(1969),
            IsoEra.CE
    };

    for (TemporalAccessor birthday : birthdays) {
        String yearString = birthday.isSupported(ChronoField.YEAR)
                ? String.valueOf(birthday.get(ChronoField.YEAR))
                : "N/A";
        String monthString = birthday.isSupported(ChronoField.MONTH_OF_YEAR)
                ? Month.from(birthday).toString()
                : "N/A";
        String dateString = birthday.isSupported(ChronoField.DAY_OF_MONTH)
                ? String.valueOf(birthday.get(ChronoField.DAY_OF_MONTH))
                : "N/A";

        System.out.format("%-10s %4s %-9s %3s%n", birthday, yearString, monthString, dateString);
    }

Output from this snippet is:这个片段的输出是:

 1955-03-22 1955 MARCH 22 1978-05 1978 MAY N/A 1969 1969 N/AN/A CE N/AN/AN/A

For a nicer interface you may wrap the TemporalAccessor in a home-made class.为了获得更好的界面,您可以将TemporalAccessor包装在一个自制的类中。 Your class could have getters for Year and LocalDate , for example, which could return an empty Optional or null in the cases where there are not enough data.例如,您的类可能有YearLocalDate getter,在没有足够数据的情况下,它们可能会返回空的Optionalnull You can think of more convenience methods.你可以想到更多方便的方法。 You know your requirements best, so I am leaving the details of the design to yourself.你最了解你的要求,所以我把设计的细节留给你自己。

Joda Time library has Partial class which can be used to create dates with unknown month / day etc. Joda Time 库具有Partial类,可用于创建未知月/日等的日期。

Partial is an immutable partial datetime supporting any set of datetime fields. Partial 是一个不可变的部分日期时间,支持任何一组日期时间字段。

A Partial instance can be used to hold any combination of fields. Partial 实例可用于保存字段的任意组合。 The instance does not contain a time zone, so any datetime is local.该实例不包含时区,因此任何日期时间都是本地的。

    Partial date = new Partial();
    
    // prints 1975
    System.out.println( date.with(year(), 1975) );

    // prints 1975-03
    System.out.println( date.with(monthOfYear(), 3).with(year(), 1975));

    // prints 1975-03-28
    System.out.println( date.with(dayOfMonth(), 28).with(monthOfYear(), 3).with(year(), 1975));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM