-Code.require_file "test_helper.exs", __DIR__
-Code.require_file "fixtures/calendar/holocene.exs", __DIR__
+Code.require_file("test_helper.exs", __DIR__)
+Code.require_file("fixtures/calendar/holocene.exs", __DIR__)
 
 defmodule FakeCalendar do
   def date_to_string(_, _, _), do: "boom"
   def time_to_string(_, _, _, _), do: "boom"
   def naive_datetime_to_string(_, _, _, _, _, _, _), do: "boom"
   def datetime_to_string(_, _, _, _, _, _, _, _, _, _), do: "boom"
-  def day_rollover_relative_to_midnight_utc, do: {123456, 123457}
+  def day_rollover_relative_to_midnight_utc, do: {123_456, 123_457}
 end
 
 defmodule DateTest do

    assert inspect(~N[2000-01-01 23:00:07.005]) == "~N[2000-01-01 23:00:07.005]"

    ndt = %{~N[2000-01-01 23:00:07.005] | calendar: FakeCalendar}
    assert inspect(ndt) == "%NaiveDateTime{calendar: FakeCalendar, day: 1, hour: 23, " <>
                           "microsecond: {5000, 3}, minute: 0, month: 1, second: 7, year: 2000}"
  end

  test "compare/2" do


  test "to_string/1" do
    datetime = %DateTime{
      year: 2000,
      month: 2,
      day: 29,
      zone_abbr: "BRM",
      hour: 23,
      minute: 0,
      second: 7,
      microsecond: {0, 0},
      utc_offset: -12600,
      std_offset: 3600,
      time_zone: "Brazil/Manaus"
    }

    assert to_string(datetime) == "2000-02-29 23:00:07-02:30 BRM Brazil/Manaus"
  end

  test "from_iso8601/1 handles positive and negative offsets" do
    assert DateTime.from_iso8601("2015-01-24T09:50:07-10:00")
           |> elem(1) ==
             %DateTime{
               microsecond: {0, 0},
               month: 1,
               std_offset: 0,
               time_zone: "Etc/UTC",
               utc_offset: 0,
               year: 2015,
               zone_abbr: "UTC",
               day: 24,
               hour: 19,
               minute: 50,
               second: 7
             }

    assert DateTime.from_iso8601("2015-01-24T09:50:07+10:00")
           |> elem(1) ==
             %DateTime{
               microsecond: {0, 0},
               month: 1,
               std_offset: 0,
               time_zone: "Etc/UTC",
               utc_offset: 0,
               year: 2015,
               zone_abbr: "UTC",
               day: 23,
               hour: 23,
               minute: 50,
               second: 7
             }
  end

  test "from_unix/2" do
    # with Unix times back to 0 Gregorian seconds
    min_datetime = %DateTime{
      calendar: Calendar.ISO,
      day: 1,
      hour: 0,
      microsecond: {0, 0},
      minute: 0,
      month: 1,
      second: 0,
      std_offset: 0,
      time_zone: "Etc/UTC",
      utc_offset: 0,
      year: 0,
      zone_abbr: "UTC"
    }

    assert DateTime.from_unix(-62_167_219_200) == {:ok, min_datetime}
    assert DateTime.from_unix(-62_167_219_201) == {:error, :invalid_unix_time}

    max_datetime = %DateTime{
      calendar: Calendar.ISO,
      day: 31,
      hour: 23,
      microsecond: {0, 0},
      minute: 59,
      month: 12,
      second: 59,
      std_offset: 0,
      time_zone: "Etc/UTC",
      utc_offset: 0,
      year: 9999,
      zone_abbr: "UTC"
    }

    assert DateTime.from_unix(253_402_300_799) == {:ok, max_datetime}
    assert DateTime.from_unix(253_402_300_800) == {:error, :invalid_unix_time}

    minus_datetime = %DateTime{
      calendar: Calendar.ISO,
      day: 31,
      hour: 23,
      microsecond: {999_999, 6},
      minute: 59,
      month: 12,
      second: 59,
      std_offset: 0,
      time_zone: "Etc/UTC",
      utc_offset: 0,
      year: 1969,
      zone_abbr: "UTC"
    }

    assert DateTime.from_unix(-1, :microsecond) == {:ok, minus_datetime}
  end

  test "from_unix!/2" do
    # with Unix times back to 0 Gregorian seconds
    datetime = %DateTime{
      calendar: Calendar.ISO,
      day: 1,
      hour: 0,
      microsecond: {0, 0},
      minute: 0,
      month: 1,
      second: 0,
      std_offset: 0,
      time_zone: "Etc/UTC",
      utc_offset: 0,
      year: 0,
      zone_abbr: "UTC"
    }

    assert DateTime.from_unix!(-62_167_219_200) == datetime

    assert_raise ArgumentError, fn ->
      DateTime.from_unix!(-62_167_219_201)
    end
  end

  test "to_unix/2 works with Unix times back to 0 Gregorian seconds" do
    # with Unix times back to 0 Gregorian seconds
    gregorian_0 = %DateTime{
      calendar: Calendar.ISO,
      day: 1,
      hour: 0,
      microsecond: {0, 0},
      minute: 0,
      month: 1,
      second: 0,
      std_offset: 0,
      time_zone: "Etc/UTC",
      utc_offset: 0,
      year: 0,
      zone_abbr: "UTC"
    }

    assert DateTime.to_unix(gregorian_0) == -62_167_219_200

    before_gregorian_0 = %DateTime{gregorian_0 | year: -1}

    assert_raise FunctionClauseError, fn ->
      DateTime.to_unix(before_gregorian_0)
    end
  end

  test "compare/2" do
    datetime1 = %DateTime{
      year: 2000,
      month: 2,
      day: 29,
      zone_abbr: "CET",
      hour: 23,
      minute: 0,
      second: 7,
      microsecond: {0, 0},
      utc_offset: 3600,
      std_offset: 0,
      time_zone: "Europe/Warsaw"
    }

    datetime2 = %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"
    }

    assert DateTime.compare(datetime1, datetime1) == :eq
    assert DateTime.compare(datetime1, datetime2) == :lt
