       zone_to_string(utc_offset, std_offset, zone_abbr, time_zone)
   end
 
-  @impl true
-  @since "1.5.0"
+  @doc """
+  Determines if the date given is valid according to the proleptic Gregorian calendar.
+
+  ## Examples
+
+    iex(1)> Calendar.ISO.valid_date?(2015, 2, 28)
+    true
+    iex(2)> Calendar.ISO.valid_date?(2015, 2, 30)
+    false
+  """
+  @impl true
+  @since "1.5.0"
+  @spec valid_date?(year, month, day) :: boolean
   def valid_date?(year, month, day) do
     month in 1..12 and year in 0..9999 and day in 1..days_in_month(year, month)
   end
 
-  @impl true
-  @since "1.5.0"
+  @doc """
+  Determines if the date given is valid according to the proleptic Gregorian calendar.
+  Note that leap seconds are considered valid, but the use of 24:00:00 as the
+  zero hour of the day is considered invalid.
+
+  ## Examples
+
+    iex> Calendar.ISO.valid_time?(10, 50, 25, {3006, 6})
+    true
+    iex> Calendar.ISO.valid_time?(23, 59, 60, {0, 0})
+    true
+    iex> Calendar.ISO.valid_time?(24, 0, 0, {0, 0})
+    false
+  """
+  @impl true
+  @since "1.5.0"
+  @spec valid_time?(Calendar.hour(), Calendar.minute(), Calendar.secon(), Calendar.microsecond()) ::
+          boolean
   def valid_time?(hour, minute, second, {microsecond, precision}) do
     hour in 0..23 and minute in 0..59 and second in 0..60 and microsecond in 0..999_999 and
       precision in 0..6
   end
 
-  @impl true
-  @since "1.5.0"
+  @doc """
+  See `c:Calendar.day_rollover_relative_to_midlight_utc/0` for documentation.
+  """
+  @impl true
+  @since "1.5.0"
+  @spec day_rollover_relative_to_midnight_utc() :: {0, 1}
   def day_rollover_relative_to_midnight_utc() do
     {0, 1}
   end


  @doc """
  Converts the given time into a string.
  """
  @impl true
  def time_to_string(hour, minute, second, microsecond) do
    time_to_string(hour, minute, second, microsecond, :extended)


  @doc """
  Converts the given date into a string.

  ## Examples

    iex> Calendar.ISO.date_to_string(2015, 2, 28)
    "2015-02-28"
    iex> Calendar.ISO.date_to_string(2017, 8, 1)
    "2017-08-01"
  """
  @spec date_to_string(year, month, day) :: String.t()
  @impl true
  def date_to_string(year, month, day) do
    date_to_string(year, month, day, :extended)
