openplanning

Hướng dẫn và ví dụ Java JapaneseEra

  1. JapaneseEra
  2. Japanese Era List
  3. JapaneseEra Examples
  4. of(int japaneseEra)
  5. valueOf(String japaneseEra)
  6. values()
  7. getValue()
  8. range(TemporalField)
  9. getDisplayName(TextStyle, Locale)

1. JapaneseEra

Lớp JapaneseEra đại diện cho một kỷ nguyên (era) trong hệ thống lịch hoàng gia Nhật Bản, một hệ thống lịch được sử dụng chủ yếu tại đất nước này.
Về cơ bản một kỷ nguyên trong hệ thống lịch hoàng gia Nhật Bản tương ứng với khoảng thời gian trị vì của một vị vua. Khi một kỷ nguyên bắt đầu, năm sẽ được đánh số bắt đầu từ 1, ngày và tháng không thay đổi và giống với hệ thống lịch ISO.
public final class JapaneseEra implements Era, Serializable
Để đơn giản chúng ta hãy xem hình minh hoạ dưới đây:
Nhật hoàng Akihito trị vì Nhật Bản từ ngày 8 tháng 1 năm 1989 đến ngày 30 tháng 4 năm 2019. Khoảng thời gian ông trị vì được gọi là kỷ nguyên Heisei (Heisei era). Khi một kỷ nguyên mới bắt đầu, năm sẽ được đánh số bắt đầu từ 1, ngày và tháng không thay đổi.
Như vậy theo lịch hoàng gia Nhật Bản, ngày đầu tiên trong kỷ nguyên Heisei là ngày 8 tháng 1 năm 01 và ngày cuối cùng là ngày 30 tháng 4 năm 31.

2. Japanese Era List

Có rất nhiều triều đại trong lịch sử Nhật Bản, mỗi triều đại sẽ tương ứng một một kỷ nguyên (era), trong bài viết này tôi không có ý định giới thiệu về tất cả các kỷ nguyên đó. Nếu quan tâm bài viết dưới đây sẽ có ích cho bạn:
Các hệ thống lịch đầu tiên xuất hiện tại Nhật Bản từ năm 604 dựa trên lịch mặt trăng của Trung Quốc. Hệ thống lịch này tồn tại cho cuối năm 1872 trước khi được thay thế bởi hệ thống lịch Gregorian (hay còn gọi là ISO). Hệ thống lịch hoàng gia Nhật Bản giai đoạn trước ngày 1 tháng 1 năm 1873 không được Java hỗ trợ.
Danh sách các kỷ nguyên được hỗ trợ trong Java:
getValue()
Era Name
Emperor
ISO Date
From
To
-1
明治 (Meiji)
Mutsuhito
1868-09-08
1873-01-01(*)
1912-07-29
0
大正 (Taisho)
Yoshihito
1912-07-30
1926-12-24
1
昭和 (Showa)
Hirohito
1926-12-25
1989-01-07
2
平成 (Heisei)
Akihito
1989-01-08
2019-04-30
3
令和 (Reiwa)
Naruhito
2019-05-01
present
JapaneseEra.MEIJI
Khoảng thời gian từ 23 tháng 10 năm 1868 đến ngày 29 tháng 7 năm 1912 là thời kỳ cai trị của Nhật hoàng Meiji, ông tên thật là Mutsuhito (Sinh ngày 3 tháng 12 năm 1852, mất ngày 30 tháng 7 năm 1912). Đây là thời kỳ nửa đầu của đế quốc Nhật Bản, khi người Nhật chuyển từ xã hội phong kiến cô lập có nguy cơ bị xâm chiếm bởi phương Tây thành một nước tư bản công nghiệp hiện đại.
Trong kỷ nguyên Meiji hệ thống lịch có sự thay đổi lớn:
Từ ngày 23 tháng 10 năm 1868 đến 31 tháng 12 năm 1872: Nhật Bản sử dụng hệ thống lịch hoàng gia với ngày và tháng dựa trên lịch mặt trăng, nhưng năm được đánh số dựa trên tuổi của kỷ nguyên hiện tại. (Java không hỗ trợ giai đoạn này)
Từ ngày 1 tháng 1 năm 1973 đến nay: Nhật Bản duy trì 2 hệ thống lịch là Gregorian và hệ thống lịch hoàng gia cải tiến (Ngày và tháng dựa trên lịch Gregorian nhưng năm được đánh số dựa trên tuổi của kỷ nguyên hiện tại).
JapaneseEra.TAISHO
Ngày 30 tháng 7 năm 1912 Nhật hoàng Meiji qua đời, thái tử Yoshihito (sinh ngày 31 tháng 8 năm 1879, mất ngày 25 tháng 12 năm 1926) lên ngôi và mở ra kỷ nguyên Taisho bắt đầu từ 30 tháng 7 năm 1912 đến ngày 24 tháng 12 năm 1926. Taisho có nghĩa là "chính nghĩa vĩ đại" (great righteousness).
JapaneseEra.SHOWA
Nhật hoàng Shōwa (Sinh ngày 29 tháng 4 năm 1901, mất ngày 7 tháng 1 năm 1989), tên thật là Hirohito, ông là vị hoàng đế thứ 124 của Nhật Bản, cai trị Nhật Bản từ ngày 25 tháng 12 năm 1926 đến ngày 7 tháng 1 năm 1989.
JapaneseEra.HEISEI
Nhật hoàng Heisei sinh ngày 23 tháng 12 năm 1933, tên thật là Akihito và là con trai đầu tiên của Nhật hoàng Shōwa. Ngày 8 tháng 1 năm 1989 ông lên ngôi hoàng đế và cai trị Nhật Bản cho tới ngày 30 tháng 4 năm 2019. Trong tiếng Nhật Heisei có nghĩa là "hoà bình ở khắp mọi nơi" (peace everywhere).
JapaneseEra.REIWA
Ngày 30 tháng 4 năm 2019, Nhật hoàng Heisei thoái vị vì vấn đề sức khoẻ, con trai ông là Naruhito lên ngôi hoàng đế và trở thành vị hoàng đế thứ 126 của Nhật Bản. Ông lấy tên kỷ nguyên là Reiwa, có nghĩa là "Sự hài hoà đẹp đẽ" (beautiful harmony). Kỷ nguyên Reiwa bắt đầu từ ngày 1 tháng 5 năm 2019 và là kỷ nguyên hiện tại của Nhật Bản.

3. JapaneseEra Examples

Lớp JapaneseEraUtils dưới đây cung cấp các phương thức tiện ích giúp bạn tìm kiếm ngày đầu tiên và cuối cùng trong một kỷ nguyên (era) được chỉ định:
JapaneseEraUtils.java
package org.o7planning.japaneseera.util;

import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.ValueRange;

public class JapaneseEraUtils {
    public static final JapaneseDate FIRST_SUPPORTED_JP_DATE = JapaneseDate.of(JapaneseEra.MEIJI, 6, 1, 1);

    public static JapaneseDate getFirstDateInSameEra(final JapaneseDate japaneseDate) {
        final JapaneseEra thisEra = japaneseDate.getEra();

        // Valid Japanese Year range with the same given day & month & era.
        ValueRange validYearRange = japaneseDate.range(ChronoField.YEAR_OF_ERA); // Ex: 1-64

        // Valid Min Japanese year with the same given day & month
        int validMinYear = (int) validYearRange.getMinimum(); // 1

        if (thisEra.equals(JapaneseEra.MEIJI)) {
            if (validMinYear < 6) {
                validMinYear = 6;
            }
        }
        final JapaneseDate jpDate2 = JapaneseDate.of(thisEra, validMinYear, 12, 31);

        ValueRange dayOfY2 = jpDate2.range(ChronoField.DAY_OF_YEAR);

        // First date in the same year with jpDate2.
        final JapaneseDate jpDate3 = jpDate2.minus(dayOfY2.getMaximum() - dayOfY2.getMinimum(), ChronoUnit.DAYS);

        if (!jpDate3.isAfter(FIRST_SUPPORTED_JP_DATE)) {
            return jpDate3;
        }
        final JapaneseDate jpDate4 = jpDate3.minus(1, ChronoUnit.DAYS);
        final JapaneseEra era4 = jpDate4.getEra();

        if (!thisEra.equals(era4)) {
            return jpDate3;
        }
        ValueRange dayOfY4 = jpDate4.range(ChronoField.DAY_OF_YEAR);
        // First date in the same Era with given japaneseDate.
        final JapaneseDate jpDate5 = jpDate4.minus(dayOfY4.getMaximum() - dayOfY4.getMinimum(), ChronoUnit.DAYS);
        return jpDate5;
    }

    public static JapaneseDate getLastDateInSameEra(final JapaneseDate japaneseDate) {
        final JapaneseEra thisEra = japaneseDate.getEra();

        // Valid Japanese Year range with the same given day & month & era.
        ValueRange validYearRange = japaneseDate.range(ChronoField.YEAR_OF_ERA); // Ex: 1-64

        // Valid Max Japanese year with the same given day & month
        int validMaxYear = (int) validYearRange.getMaximum(); // Ex: 64

        final JapaneseDate jpDate2 = JapaneseDate.of(thisEra, validMaxYear, 1, 1);
        ValueRange dayOfY2 = jpDate2.range(ChronoField.DAY_OF_YEAR);

        // Last date in the same year with jpDate2.
        final JapaneseDate jpDate3 = jpDate2.plus(dayOfY2.getMaximum() - dayOfY2.getMinimum(), ChronoUnit.DAYS);

        final JapaneseDate jpDate4 = jpDate3.plus(1, ChronoUnit.DAYS);
        final JapaneseEra era4 = jpDate4.getEra();

        if (!thisEra.equals(era4)) {
            return jpDate3;
        }
        ValueRange dayOfY4 = jpDate4.range(ChronoField.DAY_OF_YEAR);
        // Last date in the same Era with given japaneseDate.
        final JapaneseDate jpDate5 = jpDate4.plus(dayOfY4.getMaximum() - dayOfY4.getMinimum(), ChronoUnit.DAYS);
        return jpDate5;
    }

    public static JapaneseDate getFirstDateInEra(final JapaneseEra era) {
        JapaneseDate jpDate = FIRST_SUPPORTED_JP_DATE;
        while (true) {
            JapaneseEra jpEra = jpDate.getEra();
            if (era.equals(jpEra)) {
                return getFirstDateInSameEra(jpDate);
            }
            jpDate = getLastDateInSameEra(jpDate);
            jpDate = jpDate.plus(1, ChronoUnit.DAYS); // First Date in next era.
        }
    }

    public static JapaneseDate getLastDateInEra(final JapaneseEra era) {
        JapaneseDate jpDate = FIRST_SUPPORTED_JP_DATE;
        while (true) {
            JapaneseEra jpEra = jpDate.getEra();
            if (era.equals(jpEra)) {
                return getLastDateInSameEra(jpDate);
            }
            jpDate = getLastDateInSameEra(jpDate);
            jpDate = jpDate.plus(1, ChronoUnit.DAYS); // First Date in next era.
        }
    }
}
Ví dụ: In ra ngày đầu tiên và ngày cuối cùng của mỗi kỷ nguyên (era) trong hệ thống lịch hoàng gia Nhật Bản được Java hỗ trợ.
JapaneseEra_printAllEras_ex1.java
for (JapaneseEra era : JapaneseEra.values()) {
    JapaneseDate jpFirstDate = JapaneseEraUtils.getFirstDateInEra(era);
    JapaneseDate jpLastDate = JapaneseEraUtils.getLastDateInEra(era);

    System.out.printf("Era: %s, era.getValue(): %d%n", era, era.getValue());
    System.out.printf(" >> First Date: %s ~ ISO Date: %s%n", jpFirstDate, LocalDate.from(jpFirstDate));
    System.out.printf(" >> Last Date: %s ~ ISO Date: %s%n%n", jpLastDate, LocalDate.from(jpLastDate));
}
Output:
Era: Meiji, era.getValue(): -1
 >> First Date: Japanese Meiji 6-01-01 ~ ISO Date: 1873-01-01
 >> Last Date: Japanese Meiji 45-07-29 ~ ISO Date: 1912-07-29

Era: Taisho, era.getValue(): 0
 >> First Date: Japanese Taisho 1-07-30 ~ ISO Date: 1912-07-30
 >> Last Date: Japanese Taisho 15-12-24 ~ ISO Date: 1926-12-24

Era: Showa, era.getValue(): 1
 >> First Date: Japanese Showa 1-12-25 ~ ISO Date: 1926-12-25
 >> Last Date: Japanese Showa 64-01-07 ~ ISO Date: 1989-01-07

Era: Heisei, era.getValue(): 2
 >> First Date: Japanese Heisei 1-01-08 ~ ISO Date: 1989-01-08
 >> Last Date: Japanese Heisei 31-04-30 ~ ISO Date: 2019-04-30

Era: Reiwa, era.getValue(): 3
 >> First Date: Japanese Reiwa 1-05-01 ~ ISO Date: 2019-05-01
 >> Last Date: Japanese Reiwa 292276977-04-04 ~ ISO Date: +292278995-04-04

4. of(int japaneseEra)

public static JapaneseEra of(int japaneseEra)

5. valueOf(String japaneseEra)

public static JapaneseEra valueOf(String japaneseEra)

6. values()

public static JapaneseEra[] values()

7. getValue()

public int getValue()

8. range(TemporalField)

public ValueRange range(TemporalField field)

9. getDisplayName(TextStyle, Locale)

public String getDisplayName(TextStyle style, Locale locale)