# `Calendrical.Reform.Japan`

A composite calendar that tracks the historical calendar in use in Japan.

Unlike the European reforms, Japan did not move from the Julian calendar to
the Gregorian calendar. Before 1873 Japan used the Tenpō *lunisolar* calendar
(`Calendrical.LunarJapanese`); it adopted the Gregorian calendar as part of the
Meiji reforms. This makes `Calendrical.Reform.Japan` a good example of a
composite that splices a lunisolar calendar with a solar one.

The Gregorian side uses `Calendrical.Japanese` rather than
`Calendrical.Gregorian`, so post-reform dates carry Japanese era years
(Meiji, Taishō, Shōwa, Heisei, Reiwa) when localized — 1 January 1873 is
Meiji 6.

## Transitions

* **(base)** — the Japanese lunisolar calendar (`Calendrical.LunarJapanese`).

* **1873-01-01** — Japan adopts the Gregorian calendar (as
  `Calendrical.Japanese`). The last lunisolar day, Meiji 5, month 12, day 2
  (31 December 1872 in the Gregorian calendar), is followed directly by
  1 January 1873. No physical days are skipped — only the remainder of the
  lunisolar month is dropped.

Because `Calendrical.LunarJapanese` numbers years continuously from the Taika
era (645 CE), pre-reform dates carry that year number rather than an era-based
year such as "Meiji 5".

## Examples

    # The physical day before the reform, in the lunisolar calendar
    iex> Date.convert!(~D[1873-01-01 Calendrical.Reform.Japan], Calendrical.Gregorian)
    ~D[1873-01-01 Calendrical.Gregorian]

    iex> Date.convert!(~D[1873-01-01 Calendrical.Gregorian], Calendrical.Reform.Japan)
    ~D[1873-01-01 Calendrical.Reform.Japan]

## Reference

See `Calendrical.Reform` for the reform dates of other territories and the
sources they are drawn from.

# `day`

```elixir
@type day() :: 1..31
```

# `month`

```elixir
@type month() :: 1..12
```

# `year`

```elixir
@type year() :: -9999..9999
```

# `calendar_base`

Identifies that the calendar is month based.

This may not always be true for all dates in a composite
calendar but only a single value per calendar is supported.

# `calendar_for_date`

# `calendar_for_date`

Identify the base calendar for a given date.

This function derives the calendar we delegate to for a given
date based upon the configuration.

# `calendar_for_iso_days`

Identify the base calendar for a given iso_days.

# `calendar_year`

```elixir
@spec calendar_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the calendar year as displayed on rendered calendars.

# `cldr_calendar_type`

Defines the CLDR calendar type for this calendar.

This type is used in support of `Calendrical.localize/3`.

# `cyclic_year`

```elixir
@spec cyclic_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the cyclic year.

# `date_from_iso_days`

Returns `{year, month, day}` calculated from the number of
`iso_days`.

# `date_to_iso_days`

# `date_to_iso_days`

Returns the number of days since the calendar epoch for the
given `year-month-day`.

# `day_of_era`

Calculates the day and era for the given date.

# `day_of_week`

Calculates the day of the week for the given date.

# `day_of_year`

Calculates the day of the year for the given date.

# `days_in_month`

Returns the number of days in the given month.

Composite calendars cannot answer this without a year so the
default implementation returns `{:error, :undefined}`.

# `days_in_month`

Returns the number of days in the given year/month.

# `days_in_week`

Returns the number of days in a week.

# `days_in_year`

Returns the number of days in the given year.

# `extended_year`

```elixir
@spec extended_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the extended year.

# `iso_week_of_year`

Calculates the ISO week of the year for the given date.

# `leap_year?`

Returns whether the given year is a leap year, in the context
of the calendar in effect on the first day of that year.

# `month`

Returns a `Date.Range` representing a given month of a year.

# `month_of_year`

Calculates the month of the year for the given date.

# `naive_datetime_from_iso_days`

Converts a `t:Calendar.iso_days/0` to the datetime form for
this calendar.

# `naive_datetime_to_iso_days`

```elixir
@spec naive_datetime_to_iso_days(
  Calendar.year(),
  Calendar.month(),
  Calendar.day(),
  Calendar.hour(),
  Calendar.minute(),
  Calendar.second(),
  Calendar.microsecond()
) :: Calendar.iso_days()
```

Returns the `t:Calendar.iso_days/0` form of the specified
datetime.

# `periods_in_year`

Returns the number of periods in the given year.

# `plus`

Adds an `increment` number of `:months` or `:quarters` to the
given `year-month-day`. Delegates to whichever base calendar is
in effect on the input date.

# `quarter`

Returns a `Date.Range` representing a given quarter of a year.

# `quarter_of_year`

Calculates the quarter of the year (1..4) for the given date.

# `related_gregorian_year`

```elixir
@spec related_gregorian_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the related Gregorian year.

# `shift_date`

```elixir
@spec shift_date(year(), month(), day(), Duration.t()) :: {year(), month(), day()}
```

Shifts a date by the given duration.

# `valid_date?`

Determines if the date given is valid according to this calendar.

# `week`

Returns a `Date.Range` representing a given week of a year.

Not all base calendars define weeks; the result depends on the
calendar in effect on 1 January of the given year.

# `week_of_month`

Composite calendars do not define week-of-month.

# `week_of_year`

Calculates the week of the year for the given date.

# `weeks_in_year`

Returns the number of weeks in the given year (in the context
of the calendar that starts the year).

# `year`

Returns a `Date.Range` representing a given year.

# `year_of_era`

```elixir
@spec year_of_era(year(), month(), day()) :: {year(), era :: non_neg_integer()}
```

Calculates the year and era from the given `year`, `month`,
and `day`. The result is in the context of the calendar in
effect on that date.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
