<commit_before>/*
 * -----------------------------------------------------------------------
 * Copyright © 2013-2018 <NAME>, <http://www.menodata.de/>
 * -----------------------------------------------------------------------
 * This file (ChineseCalendar.java) is part of project Time4J.
 *
 * Time4J is free software: You can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Time4J is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Time4J. If not, see <http://www.gnu.org/licenses/>.
 * -----------------------------------------------------------------------
 */

package net.time4j.calendar;

import net.time4j.SystemClock;
import net.time4j.Weekday;
import net.time4j.Weekmodel;
import net.time4j.calendar.service.StdIntegerDateElement;
import net.time4j.calendar.service.StdWeekdayElement;
import net.time4j.engine.AttributeQuery;
import net.time4j.engine.CalendarEra;
import net.time4j.engine.ChronoDisplay;
import net.time4j.engine.ChronoElement;
import net.time4j.engine.ChronoEntity;
import net.time4j.engine.ChronoException;
import net.time4j.engine.ChronoUnit;
import net.time4j.engine.Chronology;
import net.time4j.engine.ElementRule;
import net.time4j.engine.FormattableElement;
import net.time4j.engine.IntElementRule;
import net.time4j.engine.TimeAxis;
import net.time4j.engine.ValidationElement;
import net.time4j.format.Attributes;
import net.time4j.format.CalendarType;
import net.time4j.format.DisplayElement;
import net.time4j.format.LocalizedPatternSupport;
import net.time4j.format.TextElement;
import net.time4j.format.TextWidth;
import net.time4j.tz.OffsetSign;
import net.time4j.tz.ZonalOffset;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.text.ParsePosition;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;


/**
 * <p>Represents the Chinese calendar supported in the gregorian range 1645-01-28/3000-01-27. </p>
 *
 * <h4>Introduction</h4>
 *
 * <p>It is a lunisolar calendar which defines years consisting of 12 or 13 months. See also
 * <a href="https://en.wikipedia.org/wiki/Chinese_calendar">Wikipedia</a>. </p>
 *
 * <h4>Following elements which are declared as constants are registered by this class</h4>
 *
 * <ul>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_ORDINAL}</li>
 *  <li>{@link #YEAR_OF_CYCLE}</li>
 *  <li>{@link #YEAR_OF_ERA}</li>
 *  <li>{@link #CYCLE}</li>
 *  <li>{@link #ERA}</li>
 * </ul>
 *
 * <p>Furthermore, all elements defined in {@code EpochDays} and {@link CommonElements} are supported. </p>
 *
 * <h4>Accuracy note</h4>
 *
 * <p>The calculations are based on the algorithms of Dershowitz/Reingold in their book
 * &quot;Calendrical calculations&quot; and astronomical calculations in nowadays precision.
 * Old scholar Chinese astronomers had applied less precise calculations in historic times
 * so tiny deviations for the period 1645-1906 are possible in some rare cases. That means,
 * this class rather models a theoretical ideal than the historic reality. </p>
 *
 * <p>The future data from 1907 onwards had been compared to the published data of Hongkong observatory.
 * Only the dates 2057-09-29 and 2097-08-08 deviate by one day (so all following days of same month).
 * However, the observatory has explicitly declared these dates to be uncertain because their calculations
 * of New Moon are not accurate enough to decide which day exactly is right (the results are very close
 * to local midnight). </p>
 *
 * <h4>Example of usage</h4>
 *
 * <pre>
 *     ChronoFormatter&lt;ChineseCalendar&gt; formatter =
 *       ChronoFormatter.setUp(ChineseCalendar.axis(), Locale.ENGLISH)
 *       .addPattern(&quot;EEE, d. MMMM r(U)&quot;, PatternType.CLDR_DATE).build();
 *     PlainDate today = SystemClock.inLocalView().today();
 *     ChineseCalendar chineseDate = today.transform(ChineseCalendar.class);
 *     System.out.println(formatter.format(chineseDate));
 * </pre>
 *
 * <h4>Support for unicode ca-extensions</h4>
 *
 * <pre>
 *      Locale locale = Locale.forLanguageTag(&quot;en-u-ca-chinese&quot;);
 *      ChronoFormatter&lt;CalendarDate&gt; f = ChronoFormatter.ofGenericCalendarStyle(DisplayMode.FULL, locale);
 *      assertThat(
 *          f.format(PlainDate.of(2017, 10, 1)),
 *          is(&quot;Sunday, M08 12, 2017(dīng-yǒu)&quot;));
 * </pre>
 *
 * @author  <NAME>
 * @since   3.40/4.35
 * @doctags.concurrency {immutable}
 */
/*[deutsch]
 * <p>Repr&auml;sentiert den chinesischen Kalender mit dem unterst&uuml;tzen (gregorianischen)
 * Bereich 1645-01-28/3000-01-27. </p>
 *
 * <h4>Einleitung</h4>
 *
 * <p>Es handelt sich um einen lunisolaren Kalender, dessen Jahre aus 12 oder 13 Monaten bestehen.
 * Siehe auch <a href="https://en.wikipedia.org/wiki/Chinese_calendar">Wikipedia</a>. </p>
 *
 * <h4>Registriert sind folgende als Konstanten deklarierte Elemente</h4>
 *
 * <ul>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_ORDINAL}</li>
 *  <li>{@link #YEAR_OF_CYCLE}</li>
 *  <li>{@link #YEAR_OF_ERA}</li>
 *  <li>{@link #CYCLE}</li>
 *  <li>{@link #ERA}</li>
 * </ul>
 *
 * <p>Au&slig;erdem werden alle Elemente von {@code EpochDays} und {@link CommonElements} unterst&uuml;tzt. </p>
 *
 * <h4>Hinweis zur Genauigkeit</h4>
 *
 * <p>Die Berechnungen fu&szlig;en auf den Algorithmen von Dershowitz/Reingold in ihrem Buch
 * &quot;Calendrical calculations&quot; und astronomischen Verfahren in der heute verf&uuml;gbaren
 * Genauigkeit. Chinesische Astronomen der alten Schule hatten weniger genaue Berechnungsverfahren
 * zur Hand, so da&szlig; kleine Abweichungen f&uuml;r die Periode 1645-1906 in seltenen F&auml;llen
 * m&ouml;glich sind. Das bedeutet, diese Klasse modelliert eher ein theoretisches Ideal als die
 * historische Wirklichkeit. </p>
 *
 * <p>Zuk&uuml;nftige Datumsangaben von 1907 aufw&auml;rts wurden mit den ver&ouml;ffentlichten Daten
 * des Observatoriums von Hongkong verglichen. Nur die Tage 2057-09-29 und 2097-08-08 weichen um einen
 * Tag ab (so auch die folgenden Tage des jeweils gleichen Monats). Allerdings hat das Observatorium
 * ausdr&uuml;cklich diese Tage als ungesichert erkl&auml;rt, weil dessen Berechnungen nicht genau genug
 * sind, um zu entscheiden, welcher Monatsbeginn wirklich der richtige ist (die Ergebnisse sind sehr
 * nahe zur &ouml;rtlichen Mitternacht). </p>
 *
 * <h4>Anwendungsbeispiel</h4>
 *
 * <pre>
 *     ChronoFormatter&lt;ChineseCalendar&gt; formatter =<commit_msg>improved javadoc<commit_after>/*
 * -----------------------------------------------------------------------
 * Copyright © 2013-2018 <NAME>, <http://www.menodata.de/>
 * -----------------------------------------------------------------------
 * This file (ChineseCalendar.java) is part of project Time4J.
 *
 * Time4J is free software: You can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Time4J is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Time4J. If not, see <http://www.gnu.org/licenses/>.
 * -----------------------------------------------------------------------
 */

package net.time4j.calendar;

import net.time4j.SystemClock;
import net.time4j.Weekday;
import net.time4j.Weekmodel;
import net.time4j.calendar.service.StdIntegerDateElement;
import net.time4j.calendar.service.StdWeekdayElement;
import net.time4j.engine.AttributeQuery;
import net.time4j.engine.CalendarEra;
import net.time4j.engine.ChronoDisplay;
import net.time4j.engine.ChronoElement;
import net.time4j.engine.ChronoEntity;
import net.time4j.engine.ChronoException;
import net.time4j.engine.ChronoUnit;
import net.time4j.engine.Chronology;
import net.time4j.engine.ElementRule;
import net.time4j.engine.FormattableElement;
import net.time4j.engine.IntElementRule;
import net.time4j.engine.TimeAxis;
import net.time4j.engine.ValidationElement;
import net.time4j.format.Attributes;
import net.time4j.format.CalendarType;
import net.time4j.format.DisplayElement;
import net.time4j.format.LocalizedPatternSupport;
import net.time4j.format.TextElement;
import net.time4j.format.TextWidth;
import net.time4j.tz.OffsetSign;
import net.time4j.tz.ZonalOffset;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.text.ParsePosition;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;


/**
 * <p>Represents the Chinese calendar supported in the gregorian range 1645-01-28/3000-01-27. </p>
 *
 * <h4>Introduction</h4>
 *
 * <p>It is a lunisolar calendar which defines years consisting of 12 or 13 months. See also
 * <a href="https://en.wikipedia.org/wiki/Chinese_calendar">Wikipedia</a>. </p>
 *
 * <h4>Following elements which are declared as constants are registered by this class</h4>
 *
 * <ul>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_ORDINAL}</li>
 *  <li>{@link #YEAR_OF_CYCLE}</li>
 *  <li>{@link #YEAR_OF_ERA}</li>
 *  <li>{@link #CYCLE}</li>
 *  <li>{@link #ERA}</li>
 * </ul>
 *
 * <p>Furthermore, all elements defined in {@code EpochDays} and {@link CommonElements} are supported. </p>
 *
 * <h4>Accuracy note</h4>
 *
 * <p>The calculations are based on the algorithms of Dershowitz/Reingold in their book
 * &quot;Calendrical calculations&quot; and astronomical calculations in nowadays precision.
 * Old scholar Chinese astronomers had applied less precise calculations in historic times
 * so tiny deviations for the period 1645-1906 are possible in some rare cases. That means,
 * this class rather models a theoretical ideal than the historic reality. </p>
 *
 * <p>The future data from 1907 onwards had been compared to the published data of
 * <a href="http://www.hko.gov.hk/gts/time/conversion.htm">Hongkong observatory</a>.
 * Only the dates 2057-09-29 and 2097-08-08 deviate by one day (so all following days of same month).
 * However, the observatory has explicitly declared these dates to be uncertain because their calculations
 * of New Moon are not accurate enough to decide which month start exactly is right (the results are very
 * close to local midnight). </p>
 *
 * <h4>Example of usage</h4>
 *
 * <pre>
 *     ChronoFormatter&lt;ChineseCalendar&gt; formatter =
 *       ChronoFormatter.setUp(ChineseCalendar.axis(), Locale.ENGLISH)
 *       .addPattern(&quot;EEE, d. MMMM r(U)&quot;, PatternType.CLDR_DATE).build();
 *     PlainDate today = SystemClock.inLocalView().today();
 *     ChineseCalendar chineseDate = today.transform(ChineseCalendar.class);
 *     System.out.println(formatter.format(chineseDate));
 * </pre>
 *
 * <h4>Support for unicode ca-extensions</h4>
 *
 * <pre>
 *      Locale locale = Locale.forLanguageTag(&quot;en-u-ca-chinese&quot;);
 *      ChronoFormatter&lt;CalendarDate&gt; f = ChronoFormatter.ofGenericCalendarStyle(DisplayMode.FULL, locale);
 *      assertThat(
 *          f.format(PlainDate.of(2017, 10, 1)),
 *          is(&quot;Sunday, M08 12, 2017(dīng-yǒu)&quot;));
 * </pre>
 *
 * @author  <NAME>
 * @since   3.40/4.35
 * @doctags.concurrency {immutable}
 */
/*[deutsch]
 * <p>Repr&auml;sentiert den chinesischen Kalender mit dem unterst&uuml;tzen (gregorianischen)
 * Bereich 1645-01-28/3000-01-27. </p>
 *
 * <h4>Einleitung</h4>
 *
 * <p>Es handelt sich um einen lunisolaren Kalender, dessen Jahre aus 12 oder 13 Monaten bestehen.
 * Siehe auch <a href="https://en.wikipedia.org/wiki/Chinese_calendar">Wikipedia</a>. </p>
 *
 * <h4>Registriert sind folgende als Konstanten deklarierte Elemente</h4>
 *
 * <ul>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_ORDINAL}</li>
 *  <li>{@link #YEAR_OF_CYCLE}</li>
 *  <li>{@link #YEAR_OF_ERA}</li>
 *  <li>{@link #CYCLE}</li>
 *  <li>{@link #ERA}</li>
 * </ul>
 *
 * <p>Au&slig;erdem werden alle Elemente von {@code EpochDays} und {@link CommonElements} unterst&uuml;tzt. </p>
 *
 * <h4>Hinweis zur Genauigkeit</h4>
 *
 * <p>Die Berechnungen fu&szlig;en auf den Algorithmen von Dershowitz/Reingold in ihrem Buch
 * &quot;Calendrical calculations&quot; und astronomischen Verfahren in der heute verf&uuml;gbaren
 * Genauigkeit. Chinesische Astronomen der alten Schule hatten weniger genaue Berechnungsverfahren
 * zur Hand, so da&szlig; kleine Abweichungen f&uuml;r die Periode 1645-1906 in seltenen F&auml;llen
 * m&ouml;glich sind. Das bedeutet, diese Klasse modelliert eher ein theoretisches Ideal als die
 * historische Wirklichkeit. </p>
 *
 * <p>Zuk&uuml;nftige Datumsangaben von 1907 aufw&auml;rts wurden mit den ver&ouml;ffentlichten Daten
 * des <a href="http://www.hko.gov.hk/gts/time/conversion.htm">Observatoriums von Hongkong</a> verglichen.
 * Nur die Tage 2057-09-29 und 2097-08-08 weichen um einen Tag ab (so auch die folgenden Tage des jeweils
 * gleichen Monats). Allerdings hat das Observatorium ausdr&uuml;cklich diese Tage als ungesichert
 * erkl&auml;rt, weil dessen Berechnungen nicht genau genug sind, um zu entscheiden, welcher Monatsbeginn
 * wirklich der richtige ist (die Ergebnisse sind sehr nahe an der &ouml;rtlichen Mitternacht). </p>
 *
 * <h4>Anwendungsbeispiel</h4>
 *
 * <pre>
 *     ChronoFormatter&lt;ChineseCalendar&gt; formatter =
{'fraction_non_alphanumeric': 0.1504870904012535, 'fraction_numerical': 0.023979835138633422, 'mean_word_length': 3.9294828744123573, 'pattern_counts': {'":': 0, '<': 197, '<?xml version=': 0, '>': 197, 'https://': 4, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6960004', 'n_tokens_mistral': 5109, 'n_tokens_neox': 4949, 'n_words': 1313}