 
   Only supports converting datetimes which are in the ISO calendar,
   attempting to convert datetimes from other calendars will raise.
+  You can also optionally specify an offset for the formatted string.
 
   WARNING: the ISO 8601 datetime format does not contain the time zone nor
   its abbreviation, which means information is lost when converting to such

      std_offset: std_offset
    } = datetime

    Calendar.ISO.date_to_string(year, month, day, format) <>
      "T" <>
      Calendar.ISO.time_to_string(hour, minute, second, microsecond, format) <>
      Calendar.ISO.offset_to_string(utc_offset, std_offset, time_zone, format)
  end

  def to_iso8601(%{calendar: _} = datetime, format) when format in [:extended, :basic] do
    datetime
    |> convert!(Calendar.ISO)
    |> to_iso8601(format)
  end

  @doc """

      iex> DateTime.to_iso8601(dt, :basic)
      "20000229T230007-0400"

      iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
      ...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
      ...>                utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
      iex> DateTime.to_iso8601(dt, :extended, 3600)
      "2000-03-01T04:00:07+01:00"

      iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
      ...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
      ...>                utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
      iex> DateTime.to_iso8601(dt, :extended, 0)
      "2000-03-01T03:00:07+00:00"

      iex> dt = %DateTime{year: 2000, month: 3, day: 01, zone_abbr: "UTC",
      ...>                hour: 03, minute: 0, second: 7, microsecond: {0, 0},
      ...>                utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
      iex> DateTime.to_iso8601(dt, :extended, 0)
      "2000-03-01T03:00:07Z"

      iex> {:ok, dt, offset} = DateTime.from_iso8601("2000-03-01T03:00:07Z")
      iex> "2000-03-01T03:00:07Z" = DateTime.to_iso8601(dt, :extended, offset)
  """
  @spec to_iso8601(Calendar.datetime(), :basic | :extended, nil | integer()) :: String.t()
  def to_iso8601(datetime, format \\ :extended, offset \\ nil)

  def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, nil)
      when format in [:extended, :basic] do
    %{
      year: year,
