簡體   English   中英

具有未知日、月和/或年的 Java 日期實現

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

有些真人不知道自己是哪一天、哪一月甚至哪一年出生的。

這可能會給需要完整出生日期的系統帶來問題。

在荷蘭,決定用未知數對這些生日進行編碼。 以下是 1975 年出生的人的生日,確切日期不詳:

00-00-1975

我如何在 Java 中處理這個問題? 我不是在問解析字符串“00-00-1975”,而是一個支持未知(可能為空?)值的實際日期實現。

值得慶幸的是,決策者在 2014 年明智了,現在出生日期不詳的人得到了一個確定的日期。 https://www.binnenlandsbestuur.nl/bestuur-en-organisatie/nieuws/niet-bestaan​​de-geboortedatum-00-00-jj-blijft.9484714.lynkx

不,沒有這種事。 您可以實現自己的,例如

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

一種選擇是利用TemporalAccessor接口。 幾乎所有 java.time 的日期和時間類都實現了這個接口,當然還有那些您將在不確定的生日時使用的類。 將變量聲明為TemporalAccessor ,您可以為其分配YearLocalDate或其他類型。

一些程序員會很想對這樣的變量使用instanceof很多,這可能被認為不太好。 幸運的是,出於許多目的,它也不是必需的。 TemporalAccessorisSupported方法可以在大多數情況下使用。

演示:

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

這個片段的輸出是:

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

為了獲得更好的界面,您可以將TemporalAccessor包裝在一個自制的類中。 例如,您的類可能有YearLocalDate getter,在沒有足夠數據的情況下,它們可能會返回空的Optionalnull 你可以想到更多方便的方法。 你最了解你的要求,所以我把設計的細節留給你自己。

Joda Time 庫具有Partial類,可用於創建未知月/日等的日期。

Partial 是一個不可變的部分日期時間,支持任何一組日期時間字段。

Partial 實例可用於保存字段的任意組合。 該實例不包含時區,因此任何日期時間都是本地的。

    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