<commit_before>/*
 * -----------------------------------------------------------------------
 * Copyright © 2013-2016 <NAME>, <http://www.menodata.de/>
 * -----------------------------------------------------------------------
 * This file (PlainDate.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;

import net.time4j.base.GregorianDate;
import net.time4j.base.GregorianMath;
import net.time4j.base.MathUtils;
import net.time4j.base.ResourceLoader;
import net.time4j.base.TimeSource;
import net.time4j.base.UnixTime;
import net.time4j.engine.AttributeQuery;
import net.time4j.engine.CalendarDate;
import net.time4j.engine.CalendarEra;
import net.time4j.engine.CalendarSystem;
import net.time4j.engine.Calendrical;
import net.time4j.engine.ChronoElement;
import net.time4j.engine.ChronoEntity;
import net.time4j.engine.ChronoException;
import net.time4j.engine.ChronoExtension;
import net.time4j.engine.ChronoMerger;
import net.time4j.engine.DisplayStyle;
import net.time4j.engine.ElementRule;
import net.time4j.engine.EpochDays;
import net.time4j.engine.FormattableElement;
import net.time4j.engine.IntElementRule;
import net.time4j.engine.Normalizer;
import net.time4j.engine.ThreetenAdapter;
import net.time4j.engine.TimeAxis;
import net.time4j.engine.TimeSpan;
import net.time4j.engine.ValidationElement;
import net.time4j.format.Attributes;
import net.time4j.format.CalendarText;
import net.time4j.format.CalendarType;
import net.time4j.format.ChronoPattern;
import net.time4j.format.DisplayMode;
import net.time4j.format.Leniency;
import net.time4j.format.LocalizedPatternSupport;
import net.time4j.format.TemporalFormatter;
import net.time4j.tz.TZID;
import net.time4j.tz.Timezone;
import net.time4j.tz.TransitionHistory;
import net.time4j.tz.ZonalOffset;
import net.time4j.tz.ZonalTransition;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.time.LocalDate;
import java.time.chrono.IsoChronology;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQueries;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;


/**
 * <p>Represents a plain calendar date in conformance to ISO-8601-standard. </p>
 *
 * <p>The value range also contains negative years down to {@code -999999999}.
 * These years cannot be interpreted in a historic way, as in general no past
 * year, too. Instead such related dates can and must rather be interpreted
 * as a different way of counting days - like epoch days. The rules of
 * gregorian calendar are applied in a proleptic way that is backwards into
 * the past even before the earliest introduction of gregorian calendar in
 * Rome (a non-historic mathematical abstraction). </p>
 *
 * <p>Following elements which are declared as constants are registered by
 * this class: </p>
 *
 * <ul>
 *  <li>{@link #COMPONENT}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_QUARTER}</li>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_NUMBER}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #QUARTER_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #YEAR}</li>
 *  <li>{@link #YEAR_OF_WEEKDATE}</li>
 * </ul>
 *
 * <p>Furthermore, all elements of class {@link Weekmodel} and class
 * {@link EpochDays} are supported. </p>
 *
 * @author      <NAME>
 * @doctags.concurrency {immutable}
 */
/*[deutsch]
 * <p>Repr&auml;sentiert ein reines Kalenderdatum im ISO-8601-Standard. </p>
 *
 * <p>Der Wertebereich fasst auch negative Jahre bis zu {@code -999999999}.
 * Diese Jahre sind nicht historisch zu interpretieren, sondern vielmehr
 * als eine andere Z&auml;hlweise &auml;hnlich zur Z&auml;hlung von
 * Epochentagen. Die Schaltjahrregeln des gregorianischen Kalenders werden
 * proleptisch, also r&uuml;ckwirkend auch in die ferne Vergangenheit
 * angewandt (eine ahistorische mathematische Abstraktion). </p>
 *
 * <p>Registriert sind folgende als Konstanten deklarierte Elemente: </p>
 *
 * <ul>
 *  <li>{@link #COMPONENT}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_QUARTER}</li>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_NUMBER}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #QUARTER_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #YEAR}</li>
 *  <li>{@link #YEAR_OF_WEEKDATE}</li>
 * </ul>
 *
 * <p>Dar&uuml;berhinaus sind alle Elemente der Klasse {@link Weekmodel}
 * und der Klasse {@link EpochDays} nutzbar. </p>
 *
 * @author      <NAME>
 * @doctags.concurrency {immutable}
 */
@CalendarType("iso8601")
public final class PlainDate
    extends Calendrical<IsoDateUnit, PlainDate>
    implements GregorianDate, Normalizer<CalendarUnit>, ThreetenAdapter, LocalizedPatternSupport {

    //~ Statische Felder/Initialisierungen --------------------------------

    /** Fr&uuml;hestm&ouml;gliches Datum [-999999999-01-01]. */
    static final PlainDate MIN =
        new PlainDate(GregorianMath.MIN_YEAR, 1, 1);

    /** Sp&auml;testm&ouml;gliches Datum [+999999999-12-31]. */
    static final PlainDate MAX =
        new PlainDate(GregorianMath.MAX_YEAR, 12, 31);

    /** Entspricht dem Jahr {@code -999999999}. */
    static final Integer MIN_YEAR =
        Integer.valueOf(GregorianMath.MIN_YEAR);

    /** Entspricht dem Jahr {@code +999999999}. */<commit_msg>document PlainDate as historizable<commit_after>/*
 * -----------------------------------------------------------------------
 * Copyright © 2013-2016 <NAME>, <http://www.menodata.de/>
 * -----------------------------------------------------------------------
 * This file (PlainDate.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;

import net.time4j.base.GregorianDate;
import net.time4j.base.GregorianMath;
import net.time4j.base.MathUtils;
import net.time4j.base.ResourceLoader;
import net.time4j.base.TimeSource;
import net.time4j.base.UnixTime;
import net.time4j.engine.AttributeQuery;
import net.time4j.engine.CalendarDate;
import net.time4j.engine.CalendarEra;
import net.time4j.engine.CalendarSystem;
import net.time4j.engine.Calendrical;
import net.time4j.engine.ChronoElement;
import net.time4j.engine.ChronoEntity;
import net.time4j.engine.ChronoException;
import net.time4j.engine.ChronoExtension;
import net.time4j.engine.ChronoMerger;
import net.time4j.engine.DisplayStyle;
import net.time4j.engine.ElementRule;
import net.time4j.engine.EpochDays;
import net.time4j.engine.FormattableElement;
import net.time4j.engine.IntElementRule;
import net.time4j.engine.Normalizer;
import net.time4j.engine.ThreetenAdapter;
import net.time4j.engine.TimeAxis;
import net.time4j.engine.TimeSpan;
import net.time4j.engine.ValidationElement;
import net.time4j.format.Attributes;
import net.time4j.format.CalendarText;
import net.time4j.format.CalendarType;
import net.time4j.format.ChronoPattern;
import net.time4j.format.DisplayMode;
import net.time4j.format.Leniency;
import net.time4j.format.LocalizedPatternSupport;
import net.time4j.format.TemporalFormatter;
import net.time4j.tz.TZID;
import net.time4j.tz.Timezone;
import net.time4j.tz.TransitionHistory;
import net.time4j.tz.ZonalOffset;
import net.time4j.tz.ZonalTransition;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.time.LocalDate;
import java.time.chrono.IsoChronology;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQueries;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;


/**
 * <p>Represents a plain calendar date in conformance to ISO-8601-standard using the gregorian calendar rules
 * for all times. </p>
 *
 * <p>The value range also contains negative years down to {@code -999999999}.
 * These years cannot be directly interpreted in a historic way, as in general no past
 * year, too. Instead such related dates can and must rather be interpreted
 * as a different way of counting days - like epoch days. The rules of
 * gregorian calendar are applied in a proleptic way that is backwards into
 * the past even before the earliest introduction of gregorian calendar in
 * Rome (a non-historic mathematical abstraction). </p>
 *
 * <p>However, this class enables <strong>full historization via a historic extension mechanism</strong>
 * (i18n-module). When formatting or parsing based on the expert engine of Time4J, it is sufficient to
 * specify a historic era (pattern symbol G) using the history of calendar reforms in a locale, and Time4J
 * will automatically apply different rules of calendar history. It is also possible to explicitly model
 * a suitable history by creating an instance of {@code net.time4j.history.ChronoHistory} and to feed the
 * format engine with this information. Furthermore, this history object yields specialized elements for
 * querying and manipulating an ISO-8601 calendar date in a historic context. </p>
 *
 * <p>Following elements which are declared as constants are registered by
 * this class: </p>
 *
 * <ul>
 *  <li>{@link #COMPONENT}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_QUARTER}</li>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_NUMBER}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #QUARTER_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #YEAR}</li>
 *  <li>{@link #YEAR_OF_WEEKDATE}</li>
 * </ul>
 *
 * <p>Furthermore, all elements of classes {@link Weekmodel}, {@link EpochDays} and
 * {@code ChronoHistory} are supported. </p>
 *
 * @author      <NAME>
 * @doctags.concurrency {immutable}
 */
/*[deutsch]
 * <p>Repr&auml;sentiert ein reines Kalenderdatum im ISO-8601-Standard. </p>
 *
 * <p>Der Wertebereich fasst auch negative Jahre bis zu {@code -999999999}.
 * Diese Jahre sind nicht historisch zu interpretieren, sondern vielmehr
 * als eine andere Z&auml;hlweise &auml;hnlich zur Z&auml;hlung von
 * Epochentagen. Die Schaltjahrregeln des gregorianischen Kalenders werden
 * proleptisch, also r&uuml;ckwirkend auch in die ferne Vergangenheit
 * angewandt (eine ahistorische mathematische Abstraktion). </p>
 *
 * <p>Allerdings bietet diese Klasse <strong>volle Historisierung mittels eines historischen
 * Erweiterungsmechanismus</strong> an (i18n-Modul). Beim Formatieren oder Parsen basierend auf der
 * Expert-Maschine von Time4J gen&uuml;gt es, eine spezifische historische &Auml;ra (Mustersymbol G) mitsamt
 * einer Region anzugeben, und Time4J wird automatisch verschiedene Regeln der Kalendergeschichte anwenden.
 * Es ist auch m&ouml;glich, eine geeignete Kalendergeschichte zu modellieren, indem ein Objekt des Typs
 * {@code net.time4j.history.ChronoHistory} erzeugt wird, und die Formatmaschine mit dieser Information
 * zu f&uuml;ttern. Au&szlig;erdem bietet dieses Objekt spezielle Elemente an, die historische Abfragen
 * und Manipulationen eines ISO-Kalenderdatums erlauben. </p>
 *
 * <p>Registriert sind folgende als Konstanten deklarierte Elemente: </p>
 *
 * <ul>
 *  <li>{@link #COMPONENT}</li>
 *  <li>{@link #DAY_OF_MONTH}</li>
 *  <li>{@link #DAY_OF_QUARTER}</li>
 *  <li>{@link #DAY_OF_WEEK}</li>
 *  <li>{@link #DAY_OF_YEAR}</li>
 *  <li>{@link #MONTH_AS_NUMBER}</li>
 *  <li>{@link #MONTH_OF_YEAR}</li>
 *  <li>{@link #QUARTER_OF_YEAR}</li>
 *  <li>{@link #WEEKDAY_IN_MONTH}</li>
 *  <li>{@link #YEAR}</li>
 *  <li>{@link #YEAR_OF_WEEKDATE}</li>
 * </ul>
 *
 * <p>Dar&uuml;berhinaus sind alle Elemente der Klassen {@link Weekmodel}, {@link EpochDays}
 * und {@code ChronoHistory} nutzbar. </p>
 *
 * @author      <NAME>
 * @doctags.concurrency {immutable}
 */
@CalendarType("iso8601")
public final class PlainDate
    extends Calendrical<IsoDateUnit, PlainDate>
    implements GregorianDate, Normalizer<CalendarUnit>, ThreetenAdapter, LocalizedPatternSupport {

    //~ Statische Felder/Initialisierungen --------------------------------

    /** Fr&uuml;hestm&ouml;gliches Datum [-999999999-01-01]. */
    static final PlainDate MIN =
        new PlainDate(GregorianMath.MIN_YEAR, 1, 1);

    /** Sp&auml;testm&ouml;gliches Datum [+999999999-12-31]. */
    static final PlainDate MAX =
        new PlainDate(GregorianMath.MAX_YEAR, 12, 31);

    /** Entspricht dem Jahr {@code -999999999}. */
    static final Integer MIN_YEAR =
        Integer.valueOf(GregorianMath.MIN_YEAR);

    /** Entspricht dem Jahr {@code +999999999}. */
{'fraction_non_alphanumeric': 0.14834427734237096, 'fraction_numerical': 0.019911035797500528, 'mean_word_length': 3.8959557552713444, 'pattern_counts': {'":': 0, '<': 153, '<?xml version=': 0, '>': 153, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 12, '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': '6805552', 'n_tokens_mistral': 4817, 'n_tokens_neox': 4642, 'n_words': 1251}