# `Calendrical.Gregorian`

Implements the proleptic Gregorian calendar.

Intended to be plug-compatible with `Calendar.ISO`
with additional functions to support localisation,
date ranges for `year`, `quarter`, `month` and `week`.

When calling `Calendrical.localize/3` on a
`Calendar.ISO`-based date, those dates are first
moved to this calendar acting as a localisation
proxy.

# `add`

Adds `:year`, `:quarter`, `:month`, `:week` increments

These functions support `CalendarInterval`

# `calendar_base`

Identifies that the calendar is month based.

# `calendar_year`

```elixir
@spec calendar_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  year :: Calendar.year() | {:error, Exception.t()}
```

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`.
Currently only `:gregorian` or `:japanese` are supported.

# `cyclic_year`

```elixir
@spec cyclic_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  year :: Calendar.year() | {:error, Exception.t()}
```

Returns the cyclic year as displayed
on rendered calendars.

# `date_from_iso_days`

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

# `date_to_iso_days`

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

# `day_of_era`

```elixir
@spec day_of_era(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  {day :: Calendrical.day(), era :: Calendrical.era()} | {:error, Exception.t()}
```

Calculates the day and era from the given `year`, `month`, and `day`.

# `day_of_week`

```elixir
@spec day_of_week(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day(),
  starting_on :: :default | atom()
) ::
  {day_of_week :: Calendar.day_of_week(),
   first_day_of_week :: Calendar.day_of_week(),
   last_day_of_week :: Calendar.day_of_week()}
  | {:error, Exception.t()}
```

Calculates the day of the week from the given `year`, `month`, and `day`.
It is an integer from 1 to 7, where 1 means "first day of the week"
and 7 means "last day of the week".

This means the value is an ordinal day of week and is relative to
the week as defined by a given calendar. It specifically does not
mean that a return value of `{1, 1, 7}` means that `1` is "Monday".

# `day_of_year`

```elixir
@spec day_of_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  day :: Calendar.day() | {:error, Exception.t()}
```

Calculates the day of the year from the given `year`, `month`, and `day`.

# `days_in_month`

```elixir
@spec days_in_month(month :: Calendrical.month()) ::
  days :: Calendar.day() | {:error, Exception.t()} | {:ambiguous, Range.t()}
```

Returns how many days there are in the given month.

If the days in month cannot be determined without
knowning the year and error tuple is returned.

# `days_in_month`

```elixir
@spec days_in_month(year :: Calendrical.year(), month :: Calendrical.month()) ::
  days :: Calendar.day() | {:error, Exception.t()} | {:ambiguous, Range.t()}
```

Returns how many days there are in the given year-month.

# `days_in_week`

Returns the number days in a week.

# `days_in_year`

```elixir
@spec days_in_year(year :: Calendrical.year()) ::
  days :: Calendar.day() | {:error, Exception.t()}
```

Returns the number days in a given year.

# `extended_year`

```elixir
@spec extended_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  year :: Calendar.year() | {:error, Exception.t()}
```

Returns the extended year as displayed
on rendered calendars.

# `first_gregorian_day_of_year`

Returns the number of `iso_days` that is
the first day of the given
year for this calendar.

# `iso_week_of_year`

```elixir
@spec iso_week_of_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  {year :: Calendar.year(), week :: Calendrical.week()}
  | {:error, Exception.t()}
```

Calculates the ISO week of the year from the given `year`, `month`, and `day`.
It is an integer from 1 to 53.

# `last_gregorian_day_of_year`

Returns the number of `iso_days` that is
the last day of the given
year for this calendar.

# `leap_year?`

```elixir
@spec leap_year?(year :: Calendrical.year()) :: boolean()
```

Returns if the given year is a leap year.

# `month`

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

# `month_of_year`

```elixir
@spec month_of_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  month :: Calendar.month() | {:error, Exception.t()}
```

Calculates the month of the year from the given `year`, `month`, and `day`.
It is an integer from 1 to 12.

# `naive_datetime_from_iso_days`

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

Converts the `t:Calendar.iso_days` format to the datetime format specified by 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` format of the specified date.

# `periods_in_year`

```elixir
@spec periods_in_year(year :: Calendrical.year()) :: Calendar.month()
```

Calculates the number of period in a given `year`. A period
corresponds to a month in month-based calendars and
a week in week-based calendars.

# `plus`

Adds an `increment` number of `date_part`s
to a `year-month-day`.

`date_part` can be `:years`, `:quarters`
`:months` or `:days`.

# `quarter`

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

# `quarter_of_year`

```elixir
@spec quarter_of_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) :: quarter :: Calendrical.quarter() | {:error, Exception.t()}
```

Calculates the quarter of the year from the given `year`, `month`, and `day`.
It is an integer from 1 to 4.

# `related_gregorian_year`

```elixir
@spec related_gregorian_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) :: year :: Calendar.year() | {:error, Exception.t()}
```

Returns the related gregorain year as displayed
on rendered calendars.

# `shift_date`

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

Shifts a date by given duration.

# `shift_naive_datetime`

```elixir
@spec shift_naive_datetime(
  Calendar.year(),
  Calendar.month(),
  Calendar.day(),
  Calendar.hour(),
  Calendar.minute(),
  Calendar.second(),
  Calendar.microsecond(),
  Duration.t()
) ::
  {Calendar.year(), Calendar.month(), Calendar.day(), Calendar.hour(),
   Calendar.minute(), Calendar.second(), Calendar.microsecond()}
```

Shifts a naive date time by given duration.

# `shift_time`

```elixir
@spec shift_time(
  Calendar.hour(),
  Calendar.minute(),
  Calendar.second(),
  Calendar.microsecond(),
  Duration.t()
) ::
  {Calendar.hour(), Calendar.minute(), Calendar.second(),
   Calendar.microsecond()}
```

Shifts a time by given duration.

# `valid_date?`

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

# `week`

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

# `week_of_month`

```elixir
@spec week_of_month(
  year :: Calendrical.year(),
  month :: Calendrical.week(),
  day :: Calendar.day()
) ::
  {month :: Calendar.month(), week :: Calendrical.week()}
  | {:error, Exception.t()}
```

Calculates the week of the month from the given `year`, `month`, and `day`.
It is an integer from 1 to 5.

# `week_of_year`

```elixir
@spec week_of_year(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  {year :: Calendar.year(), week :: Calendrical.week()}
  | {:error, Exception.t()}
```

Calculates the week of the year from the given `year`, `month`, and `day`.
It is an integer from 1 to 53.

# `weeks_in_year`

```elixir
@spec weeks_in_year(year :: Calendrical.year()) ::
  {weeks :: Calendar.week(), days_in_last_week :: Calendar.day()}
  | {:error, Exception.t()}
```

Returns the number weeks in a given year.

Note that for Gregorian month-based calendars the
number of weeks returned will be 53 (not the sometimes
expected 52) since there is always a week 53 with
1 or 2 (in a leap year) additional days in the
last week.

### Arguments

* `year` is any `t:Calendar.year/0`

### Returns

* `{weeks_in_year, days_in_last_week}`

### Example

    iex> Calendrical.Gregorian.weeks_in_year(2019)
    {53, 1}

    iex> Calendrical.Gregorian.weeks_in_year(2020)
    {53, 2}

# `year`

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

# `year_of_era`

```elixir
@spec year_of_era(Calendrical.year()) ::
  {year :: Calendar.year(), era :: Calendrical.era()}
```

Calculates the year and era from the given `year`.

The ISO calendar has two eras: the current era which
starts in year 1 and is defined as era "1". And a
second era for those years less than 1 defined as
era "0".

# `year_of_era`

```elixir
@spec year_of_era(
  year :: Calendrical.year(),
  month :: Calendrical.month(),
  day :: Calendrical.day()
) ::
  {year :: Calendar.year(), era :: Calendrical.era()} | {:error, Exception.t()}
```

Calculates the year and era from the given `year`,
`month` and `day`.

The ISO calendar has two eras: the current era which
starts in year 1 and is defined as era "1". And a
second era for those years less than 1 defined as
era "0".

---

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