Форматирование китайской даты, преобразованной по time4j, в григорианскую на Java

Я работаю над проектом на Java, и мне нужно изменить разные типы дат друг на друга, например (григорианский на китайский и наоборот и григорианский на хиджру и наоборот). Я пытаюсь использовать Time4j, у которого есть возможность конвертировать разные типы дат друг в друга, но, к сожалению, я не понял, как работать с этой библиотекой, даже после того, как попытался прочитать ее документацию.

Прямо сейчас я пытаюсь преобразовать григорианскую дату в китайскую дату, но я не могу получить нормальный год в китайской дате, когда я использую object.getYear(), он возвращает циклический год, но мне нужен обычный год, например 2019.

Это мой код:

import net.time4j.PlainDate;
import net.time4j.calendar.ChineseCalendar;
public class DateConverter {

static PlainDate gregorian = PlainDate.nowInSystemTime();
static ChineseCalendar obj = gregorian.transform(ChineseCalendar.axis());

public static void main(String[] args) {

    String result = obj.getMonth() + "/" + obj.getDayOfMonth() + "/" + obj.getYear() ;

    System.out.println(result);         // 8/30/ji-hai(36)
    System.out.println(obj);            // chinese[ji-hai(2019)-8-30]
}
}

Мне нужен этот тип года ji-hai(2019), и он находится в методе toString() по умолчанию, и когда я использую метод object.getYear(), он возвращает ji-hai(36).

Теперь, как мне изменить возвращаемое значение с ji-hai(36) на ji-hai(2019). Кроме того, если я хочу получить дату по григорианскому календарю от пользователя, как мне подготовиться к этому преобразованию? Могу ли я получить его как текст String и привести его к дате по григорианскому календарю, а затем использовать его? Возможно ли?

Также, если вы знаете хороший ресурс, который объясняет использование классов и методов Time4j на примере, поделитесь им со мной.

благодарю вас.


person Ali Ansari    schedule 29.09.2019    source источник


Ответы (1)


Краткое решение:

Вместо того, чтобы пытаться полагаться на toString()-методы различных типов, такие как CyclicYear и т. д., я рекомендую использовать специальный механизм форматирования, способный обрабатывать китайские календари. Time4J имеет собственный механизм форматирования, основанный на классе ChronoFormatter:

    ChineseCalendar obj = PlainDate.nowInSystemTime().transform(ChineseCalendar.axis());

    ChronoFormatter<ChineseCalendar> f =
        ChronoFormatter.ofPattern(
          "d/M/U(r)", 
          PatternType.CLDR, 
          Locale.ROOT, 
          ChineseCalendar.axis());

    System.out.println(f.print(obj));   
    // output today: 1/9/ji-hai(2019)

Выкройка и китайские годы:

Я использовал шаблон "d/M/U(r)". «Нормальный» год китайского календаря ЯВЛЯЕТСЯ циклическим годом, представленным символом шаблона CLDR «U». Циклические годы повторяются через 60 лет, начиная новый цикл. Любое другое определение года явно необычно. Это может удивить западных пользователей, потому что они часто ожидают, что есть какой-то пролептический год, отсчитываемый только вперед. Однако Time4J также поддерживает два других вида года. Один – это год эры, который сейчас представляет только исторический интерес. И другой тип года - это связанный григорианский год (с использованием символа шаблона «r»). Его основная цель - просто сделать циклический год однозначным. Поэтому многим людям нравится структурировать китайские годы как комбинацию циклического года и связанного с ним григорианского года в следующей форме:

U(r) or r(U)

Можно даже определить китайский зодиак, который повторяется всего через 12 лет. Если у вас есть объект китайского календаря, вы можете определить зодиак следующим образом:

    String zodiac = obj.getYear().getZodiac(Locale.ENGLISH);
    System.out.println("Year of " + zodiac); // Year of Pig

Обратный путь (разбор и преобразование в григорианский):

Просто используйте средство форматирования, определенное выше, а затем проанализируйте:

    PlainDate gregorian = f.parse("1/9/ji-hai(2019)").transform(PlainDate.axis());
    System.out.println(gregorian); // output: 2019-09-29

О транскрипциях:

Я использовал корневую локаль для создания средства форматирования. Циклический год выводится простыми латинскими буквами без диакритических знаков. Если вы хотите использовать официальную транскрипцию пиньинь, вы можете вместо этого применить английскую локаль. Тогда циклический год будет отображаться как «jǐ-hài». Специальные транскрипции с использованием других скриптов поддерживаются для языков китайского (тот же скрипт также для корейского и японского), вьетнамского и русского языков.

Документацию по API Time4J можно найти онлайн. Документ уже содержит примеры форматирования и разбора китайского календаря. Но я приветствую любой дальнейший вклад в него или конкретные предложения по его улучшению.

person Meno Hochschild    schedule 29.09.2019
comment
Большое спасибо за исчерпывающую информацию. Я просто хочу упомянуть, что синтаксический анализ и преобразование в григорианский генерируют исключение. (ParseException: требуется цифра). почему это происходит, и можно ли таким же образом менять все остальные доступные типы дат друг на друга или у каждого типа даты есть свой метод конвертации, который работает по-разному? - person Ali Ansari; 30.09.2019
comment
@AliDK а) Да, метод синтаксического анализа объявлен для выдачи проверенного ParseException'. If you have a parse problem then you can open another question describing your input and deliver a compilable and reproducible example, and then I can answer again. b) About transformation, the method transform()', принимает аргумент типа Chronology, совместимый с любым типом Calendrical, поэтому вы можете преобразовать в ChineseCalendar, PlainDate (григорианский), PersianCalendar и т. д. См. также API- документ - person Meno Hochschild; 30.09.2019
comment
@AliDK Сообщение об ошибке при синтаксическом анализе (требуется цифра), о котором вы сообщаете, похоже, указывает на несоответствие между вашим шаблоном и вводом, который вы хотите проанализировать. - person Meno Hochschild; 30.09.2019