summaryrefslogtreecommitdiffstats
path: root/tests/date
diff options
context:
space:
mode:
Diffstat (limited to 'tests/date')
-rw-r--r--tests/date/__init__.py0
-rw-r--r--tests/date/test_add.py88
-rw-r--r--tests/date/test_behavior.py73
-rw-r--r--tests/date/test_comparison.py247
-rw-r--r--tests/date/test_construct.py16
-rw-r--r--tests/date/test_day_of_week_modifiers.py298
-rw-r--r--tests/date/test_diff.py365
-rw-r--r--tests/date/test_fluent_setters.py29
-rw-r--r--tests/date/test_getters.py87
-rw-r--r--tests/date/test_start_end_of.py252
-rw-r--r--tests/date/test_strings.py48
-rw-r--r--tests/date/test_sub.py90
12 files changed, 1593 insertions, 0 deletions
diff --git a/tests/date/__init__.py b/tests/date/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/date/__init__.py
diff --git a/tests/date/test_add.py b/tests/date/test_add.py
new file mode 100644
index 0000000..a435f46
--- /dev/null
+++ b/tests/date/test_add.py
@@ -0,0 +1,88 @@
+from __future__ import annotations
+
+from datetime import timedelta
+
+import pytest
+
+import pendulum
+
+from tests.conftest import assert_date
+
+
+def test_add_years_positive():
+ assert pendulum.date(1975, 1, 1).add(years=1).year == 1976
+
+
+def test_add_years_zero():
+ assert pendulum.date(1975, 1, 1).add(years=0).year == 1975
+
+
+def test_add_years_negative():
+ assert pendulum.date(1975, 1, 1).add(years=-1).year == 1974
+
+
+def test_add_months_positive():
+ assert pendulum.date(1975, 12, 1).add(months=1).month == 1
+
+
+def test_add_months_zero():
+ assert pendulum.date(1975, 12, 1).add(months=0).month == 12
+
+
+def test_add_months_negative():
+ assert pendulum.date(1975, 12, 1).add(months=-1).month == 11
+
+
+def test_add_month_with_overflow():
+ assert pendulum.Date(2012, 1, 31).add(months=1).month == 2
+
+
+def test_add_days_positive():
+ assert pendulum.Date(1975, 5, 31).add(days=1).day == 1
+
+
+def test_add_days_zero():
+ assert pendulum.Date(1975, 5, 31).add(days=0).day == 31
+
+
+def test_add_days_negative():
+ assert pendulum.Date(1975, 5, 31).add(days=-1).day == 30
+
+
+def test_add_weeks_positive():
+ assert pendulum.Date(1975, 5, 21).add(weeks=1).day == 28
+
+
+def test_add_weeks_zero():
+ assert pendulum.Date(1975, 5, 21).add(weeks=0).day == 21
+
+
+def test_add_weeks_negative():
+ assert pendulum.Date(1975, 5, 21).add(weeks=-1).day == 14
+
+
+def test_add_timedelta():
+ delta = timedelta(days=18)
+ d = pendulum.date(2015, 3, 14)
+
+ new = d + delta
+ assert isinstance(new, pendulum.Date)
+ assert_date(new, 2015, 4, 1)
+
+
+def test_add_duration():
+ duration = pendulum.duration(years=2, months=3, days=18)
+ d = pendulum.Date(2015, 3, 14)
+
+ new = d + duration
+ assert_date(new, 2017, 7, 2)
+
+
+def test_addition_invalid_type():
+ d = pendulum.date(2015, 3, 14)
+
+ with pytest.raises(TypeError):
+ d + 3
+
+ with pytest.raises(TypeError):
+ 3 + d
diff --git a/tests/date/test_behavior.py b/tests/date/test_behavior.py
new file mode 100644
index 0000000..98dd175
--- /dev/null
+++ b/tests/date/test_behavior.py
@@ -0,0 +1,73 @@
+from __future__ import annotations
+
+import pickle
+
+from datetime import date
+
+import pytest
+
+import pendulum
+
+
+@pytest.fixture()
+def p():
+ return pendulum.Date(2016, 8, 27)
+
+
+@pytest.fixture()
+def d():
+ return date(2016, 8, 27)
+
+
+def test_timetuple(p, d):
+ assert p.timetuple() == d.timetuple()
+
+
+def test_ctime(p, d):
+ assert p.ctime() == d.ctime()
+
+
+def test_isoformat(p, d):
+ assert p.isoformat() == d.isoformat()
+
+
+def test_toordinal(p, d):
+ assert p.toordinal() == d.toordinal()
+
+
+def test_weekday(p, d):
+ assert p.weekday() == d.weekday()
+
+
+def test_isoweekday(p, d):
+ assert p.isoweekday() == d.isoweekday()
+
+
+def test_isocalendar(p, d):
+ assert p.isocalendar() == d.isocalendar()
+
+
+def test_fromtimestamp():
+ assert pendulum.Date.fromtimestamp(0) == date.fromtimestamp(0)
+
+
+def test_fromordinal():
+ assert pendulum.Date.fromordinal(730120) == date.fromordinal(730120)
+
+
+def test_hash():
+ d1 = pendulum.Date(2016, 8, 27)
+ d2 = pendulum.Date(2016, 8, 27)
+ d3 = pendulum.Date(2016, 8, 28)
+
+ assert hash(d2) == hash(d1)
+ assert hash(d1) != hash(d3)
+
+
+def test_pickle():
+ d1 = pendulum.Date(2016, 8, 27)
+ s = pickle.dumps(d1)
+ d2 = pickle.loads(s)
+
+ assert isinstance(d2, pendulum.Date)
+ assert d2 == d1
diff --git a/tests/date/test_comparison.py b/tests/date/test_comparison.py
new file mode 100644
index 0000000..94bf224
--- /dev/null
+++ b/tests/date/test_comparison.py
@@ -0,0 +1,247 @@
+from __future__ import annotations
+
+from datetime import date
+
+import pendulum
+
+from tests.conftest import assert_date
+
+
+def test_equal_to_true():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 1)
+ d3 = date(2000, 1, 1)
+
+ assert d2 == d1
+ assert d3 == d1
+
+
+def test_equal_to_false():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 2)
+ d3 = date(2000, 1, 2)
+
+ assert d1 != d2
+ assert d1 != d3
+
+
+def test_not_equal_to_true():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 2)
+ d3 = date(2000, 1, 2)
+
+ assert d1 != d2
+ assert d1 != d3
+
+
+def test_not_equal_to_false():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 1)
+ d3 = date(2000, 1, 1)
+
+ assert d2 == d1
+ assert d3 == d1
+
+
+def test_not_equal_to_none():
+ d1 = pendulum.Date(2000, 1, 1)
+
+ assert d1 != None # noqa
+
+
+def test_greater_than_true():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(1999, 12, 31)
+ d3 = date(1999, 12, 31)
+
+ assert d1 > d2
+ assert d1 > d3
+
+
+def test_greater_than_false():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 2)
+ d3 = date(2000, 1, 2)
+
+ assert not d1 > d2
+ assert not d1 > d3
+
+
+def test_greater_than_or_equal_true():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(1999, 12, 31)
+ d3 = date(1999, 12, 31)
+
+ assert d1 >= d2
+ assert d1 >= d3
+
+
+def test_greater_than_or_equal_true_equal():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 1)
+ d3 = date(2000, 1, 1)
+
+ assert d1 >= d2
+ assert d1 >= d3
+
+
+def test_greater_than_or_equal_false():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 2)
+ d3 = date(2000, 1, 2)
+
+ assert not d1 >= d2
+ assert not d1 >= d3
+
+
+def test_less_than_true():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 2)
+ d3 = date(2000, 1, 2)
+
+ assert d1 < d2
+ assert d1 < d3
+
+
+def test_less_than_false():
+ d1 = pendulum.Date(2000, 1, 2)
+ d2 = pendulum.Date(2000, 1, 1)
+ d3 = date(2000, 1, 1)
+
+ assert not d1 < d2
+ assert not d1 < d3
+
+
+def test_less_than_or_equal_true():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 2)
+ d3 = date(2000, 1, 2)
+
+ assert d1 <= d2
+ assert d1 <= d3
+
+
+def test_less_than_or_equal_true_equal():
+ d1 = pendulum.Date(2000, 1, 1)
+ d2 = pendulum.Date(2000, 1, 1)
+ d3 = date(2000, 1, 1)
+
+ assert d1 <= d2
+ assert d1 <= d3
+
+
+def test_less_than_or_equal_false():
+ d1 = pendulum.Date(2000, 1, 2)
+ d2 = pendulum.Date(2000, 1, 1)
+ d3 = date(2000, 1, 1)
+
+ assert not d1 <= d2
+ assert not d1 <= d3
+
+
+def test_is_anniversary():
+ d = pendulum.Date.today()
+ an_anniversary = d.subtract(years=1)
+ assert an_anniversary.is_anniversary()
+ not_an_anniversary = d.subtract(days=1)
+ assert not not_an_anniversary.is_anniversary()
+ also_not_an_anniversary = d.add(days=2)
+ assert not also_not_an_anniversary.is_anniversary()
+
+ d1 = pendulum.Date(1987, 4, 23)
+ d2 = pendulum.Date(2014, 9, 26)
+ d3 = pendulum.Date(2014, 4, 23)
+ assert not d2.is_anniversary(d1)
+ assert d3.is_anniversary(d1)
+
+
+def test_is_birthday(): # backward compatibility
+ d = pendulum.Date.today()
+ an_anniversary = d.subtract(years=1)
+ assert an_anniversary.is_birthday()
+ not_an_anniversary = d.subtract(days=1)
+ assert not not_an_anniversary.is_birthday()
+ also_not_an_anniversary = d.add(days=2)
+ assert not also_not_an_anniversary.is_birthday()
+
+ d1 = pendulum.Date(1987, 4, 23)
+ d2 = pendulum.Date(2014, 9, 26)
+ d3 = pendulum.Date(2014, 4, 23)
+ assert not d2.is_birthday(d1)
+ assert d3.is_birthday(d1)
+
+
+def test_closest():
+ instance = pendulum.Date(2015, 5, 28)
+ dt1 = pendulum.Date(2015, 5, 27)
+ dt2 = pendulum.Date(2015, 5, 30)
+ closest = instance.closest(dt1, dt2)
+ assert closest == dt1
+
+ closest = instance.closest(dt2, dt1)
+ assert closest == dt1
+
+
+def test_closest_with_date():
+ instance = pendulum.Date(2015, 5, 28)
+ dt1 = date(2015, 5, 27)
+ dt2 = date(2015, 5, 30)
+ closest = instance.closest(dt1, dt2)
+ assert isinstance(closest, pendulum.Date)
+ assert_date(closest, 2015, 5, 27)
+
+
+def test_closest_with_equals():
+ instance = pendulum.Date(2015, 5, 28)
+ dt1 = pendulum.Date(2015, 5, 28)
+ dt2 = pendulum.Date(2015, 5, 30)
+ closest = instance.closest(dt1, dt2)
+ assert closest == dt1
+
+
+def test_farthest():
+ instance = pendulum.Date(2015, 5, 28)
+ dt1 = pendulum.Date(2015, 5, 27)
+ dt2 = pendulum.Date(2015, 5, 30)
+ closest = instance.farthest(dt1, dt2)
+ assert closest == dt2
+
+ closest = instance.farthest(dt2, dt1)
+ assert closest == dt2
+
+
+def test_farthest_with_date():
+ instance = pendulum.Date(2015, 5, 28)
+ dt1 = date(2015, 5, 27)
+ dt2 = date(2015, 5, 30)
+ closest = instance.farthest(dt1, dt2)
+ assert isinstance(closest, pendulum.Date)
+ assert_date(closest, 2015, 5, 30)
+
+
+def test_farthest_with_equals():
+ instance = pendulum.Date(2015, 5, 28)
+ dt1 = pendulum.Date(2015, 5, 28)
+ dt2 = pendulum.Date(2015, 5, 30)
+ closest = instance.farthest(dt1, dt2)
+ assert closest == dt2
+
+
+def test_is_same_day():
+ dt1 = pendulum.Date(2015, 5, 28)
+ dt2 = pendulum.Date(2015, 5, 29)
+ dt3 = pendulum.Date(2015, 5, 28)
+ dt4 = date(2015, 5, 28)
+ dt5 = date(2015, 5, 29)
+
+ assert not dt1.is_same_day(dt2)
+ assert dt1.is_same_day(dt3)
+ assert dt1.is_same_day(dt4)
+ assert not dt1.is_same_day(dt5)
+
+
+def test_comparison_to_unsupported():
+ dt1 = pendulum.Date.today()
+
+ assert dt1 != "test"
+ assert dt1 not in ["test"]
diff --git a/tests/date/test_construct.py b/tests/date/test_construct.py
new file mode 100644
index 0000000..5b6eb78
--- /dev/null
+++ b/tests/date/test_construct.py
@@ -0,0 +1,16 @@
+from __future__ import annotations
+
+from pendulum import Date
+from tests.conftest import assert_date
+
+
+def test_construct():
+ d = Date(2016, 10, 20)
+
+ assert_date(d, 2016, 10, 20)
+
+
+def test_today():
+ d = Date.today()
+
+ assert isinstance(d, Date)
diff --git a/tests/date/test_day_of_week_modifiers.py b/tests/date/test_day_of_week_modifiers.py
new file mode 100644
index 0000000..55aba55
--- /dev/null
+++ b/tests/date/test_day_of_week_modifiers.py
@@ -0,0 +1,298 @@
+from __future__ import annotations
+
+import pytest
+
+import pendulum
+
+from pendulum.exceptions import PendulumException
+from tests.conftest import assert_date
+
+
+def test_start_of_week():
+ d = pendulum.date(1980, 8, 7).start_of("week")
+ assert_date(d, 1980, 8, 4)
+
+
+def test_start_of_week_from_week_start():
+ d = pendulum.date(1980, 8, 4).start_of("week")
+ assert_date(d, 1980, 8, 4)
+
+
+def test_start_of_week_crossing_year_boundary():
+ d = pendulum.date(2014, 1, 1).start_of("week")
+ assert_date(d, 2013, 12, 30)
+
+
+def test_end_of_week():
+ d = pendulum.date(1980, 8, 7).end_of("week")
+ assert_date(d, 1980, 8, 10)
+
+
+def test_end_of_week_from_week_end():
+ d = pendulum.date(1980, 8, 10).end_of("week")
+ assert_date(d, 1980, 8, 10)
+
+
+def test_end_of_week_crossing_year_boundary():
+ d = pendulum.date(2013, 12, 31).end_of("week")
+ assert_date(d, 2014, 1, 5)
+
+
+def test_next():
+ d = pendulum.date(1975, 5, 21).next()
+ assert_date(d, 1975, 5, 28)
+
+
+def test_next_monday():
+ d = pendulum.date(1975, 5, 21).next(pendulum.MONDAY)
+ assert_date(d, 1975, 5, 26)
+
+
+def test_next_saturday():
+ d = pendulum.date(1975, 5, 21).next(6)
+ assert_date(d, 1975, 5, 24)
+
+
+def test_next_invalid():
+ dt = pendulum.date(1975, 5, 21)
+
+ with pytest.raises(ValueError):
+ dt.next(7)
+
+
+def test_previous():
+ d = pendulum.date(1975, 5, 21).previous()
+ assert_date(d, 1975, 5, 14)
+
+
+def test_previous_monday():
+ d = pendulum.date(1975, 5, 21).previous(pendulum.MONDAY)
+ assert_date(d, 1975, 5, 19)
+
+
+def test_previous_saturday():
+ d = pendulum.date(1975, 5, 21).previous(6)
+ assert_date(d, 1975, 5, 17)
+
+
+def test_previous_invalid():
+ dt = pendulum.date(1975, 5, 21)
+
+ with pytest.raises(ValueError):
+ dt.previous(7)
+
+
+def test_first_day_of_month():
+ d = pendulum.date(1975, 11, 21).first_of("month")
+ assert_date(d, 1975, 11, 1)
+
+
+def test_first_wednesday_of_month():
+ d = pendulum.date(1975, 11, 21).first_of("month", pendulum.WEDNESDAY)
+ assert_date(d, 1975, 11, 5)
+
+
+def test_first_friday_of_month():
+ d = pendulum.date(1975, 11, 21).first_of("month", 5)
+ assert_date(d, 1975, 11, 7)
+
+
+def test_last_day_of_month():
+ d = pendulum.date(1975, 12, 5).last_of("month")
+ assert_date(d, 1975, 12, 31)
+
+
+def test_last_tuesday_of_month():
+ d = pendulum.date(1975, 12, 1).last_of("month", pendulum.TUESDAY)
+ assert_date(d, 1975, 12, 30)
+
+
+def test_last_friday_of_month():
+ d = pendulum.date(1975, 12, 5).last_of("month", 5)
+ assert_date(d, 1975, 12, 26)
+
+
+def test_nth_of_month_outside_scope():
+ d = pendulum.date(1975, 6, 5)
+
+ with pytest.raises(PendulumException):
+ d.nth_of("month", 6, pendulum.MONDAY)
+
+
+def test_nth_of_month_outside_year():
+ d = pendulum.date(1975, 12, 5)
+
+ with pytest.raises(PendulumException):
+ d.nth_of("month", 55, pendulum.MONDAY)
+
+
+def test_nth_of_month_first():
+ d = pendulum.date(1975, 12, 5).nth_of("month", 1, pendulum.MONDAY)
+
+ assert_date(d, 1975, 12, 1)
+
+
+def test_2nd_monday_of_month():
+ d = pendulum.date(1975, 12, 5).nth_of("month", 2, pendulum.MONDAY)
+
+ assert_date(d, 1975, 12, 8)
+
+
+def test_3rd_wednesday_of_month():
+ d = pendulum.date(1975, 12, 5).nth_of("month", 3, 3)
+
+ assert_date(d, 1975, 12, 17)
+
+
+def test_first_day_of_quarter():
+ d = pendulum.date(1975, 11, 21).first_of("quarter")
+ assert_date(d, 1975, 10, 1)
+
+
+def test_first_wednesday_of_quarter():
+ d = pendulum.date(1975, 11, 21).first_of("quarter", pendulum.WEDNESDAY)
+ assert_date(d, 1975, 10, 1)
+
+
+def test_first_friday_of_quarter():
+ d = pendulum.date(1975, 11, 21).first_of("quarter", 5)
+ assert_date(d, 1975, 10, 3)
+
+
+def test_first_of_quarter_from_a_day_that_will_not_exist_in_the_first_month():
+ d = pendulum.date(2014, 5, 31).first_of("quarter")
+ assert_date(d, 2014, 4, 1)
+
+
+def test_last_day_of_quarter():
+ d = pendulum.date(1975, 8, 5).last_of("quarter")
+ assert_date(d, 1975, 9, 30)
+
+
+def test_last_tuesday_of_quarter():
+ d = pendulum.date(1975, 8, 5).last_of("quarter", pendulum.TUESDAY)
+ assert_date(d, 1975, 9, 30)
+
+
+def test_last_friday_of_quarter():
+ d = pendulum.date(1975, 8, 5).last_of("quarter", pendulum.FRIDAY)
+ assert_date(d, 1975, 9, 26)
+
+
+def test_last_day_of_quarter_that_will_not_exist_in_the_last_month():
+ d = pendulum.date(2014, 5, 31).last_of("quarter")
+ assert_date(d, 2014, 6, 30)
+
+
+def test_nth_of_quarter_outside_scope():
+ d = pendulum.date(1975, 1, 5)
+
+ with pytest.raises(PendulumException):
+ d.nth_of("quarter", 20, pendulum.MONDAY)
+
+
+def test_nth_of_quarter_outside_year():
+ d = pendulum.date(1975, 1, 5)
+
+ with pytest.raises(PendulumException):
+ d.nth_of("quarter", 55, pendulum.MONDAY)
+
+
+def test_nth_of_quarter_first():
+ d = pendulum.date(1975, 12, 5).nth_of("quarter", 1, pendulum.MONDAY)
+
+ assert_date(d, 1975, 10, 6)
+
+
+def test_nth_of_quarter_from_a_day_that_will_not_exist_in_the_first_month():
+ d = pendulum.date(2014, 5, 31).nth_of("quarter", 2, pendulum.MONDAY)
+ assert_date(d, 2014, 4, 14)
+
+
+def test_2nd_monday_of_quarter():
+ d = pendulum.date(1975, 8, 5).nth_of("quarter", 2, pendulum.MONDAY)
+ assert_date(d, 1975, 7, 14)
+
+
+def test_3rd_wednesday_of_quarter():
+ d = pendulum.date(1975, 8, 5).nth_of("quarter", 3, 3)
+ assert_date(d, 1975, 7, 16)
+
+
+def test_first_day_of_year():
+ d = pendulum.date(1975, 11, 21).first_of("year")
+ assert_date(d, 1975, 1, 1)
+
+
+def test_first_wednesday_of_year():
+ d = pendulum.date(1975, 11, 21).first_of("year", pendulum.WEDNESDAY)
+ assert_date(d, 1975, 1, 1)
+
+
+def test_first_friday_of_year():
+ d = pendulum.date(1975, 11, 21).first_of("year", 5)
+ assert_date(d, 1975, 1, 3)
+
+
+def test_last_day_of_year():
+ d = pendulum.date(1975, 8, 5).last_of("year")
+ assert_date(d, 1975, 12, 31)
+
+
+def test_last_tuesday_of_year():
+ d = pendulum.date(1975, 8, 5).last_of("year", pendulum.TUESDAY)
+ assert_date(d, 1975, 12, 30)
+
+
+def test_last_friday_of_year():
+ d = pendulum.date(1975, 8, 5).last_of("year", 5)
+ assert_date(d, 1975, 12, 26)
+
+
+def test_nth_of_year_outside_scope():
+ d = pendulum.date(1975, 1, 5)
+
+ with pytest.raises(PendulumException):
+ d.nth_of("year", 55, pendulum.MONDAY)
+
+
+def test_nth_of_year_first():
+ d = pendulum.date(1975, 12, 5).nth_of("year", 1, pendulum.MONDAY)
+
+ assert_date(d, 1975, 1, 6)
+
+
+def test_2nd_monday_of_year():
+ d = pendulum.date(1975, 8, 5).nth_of("year", 2, pendulum.MONDAY)
+ assert_date(d, 1975, 1, 13)
+
+
+def test_2rd_wednesday_of_year():
+ d = pendulum.date(1975, 8, 5).nth_of("year", 3, pendulum.WEDNESDAY)
+ assert_date(d, 1975, 1, 15)
+
+
+def test_7th_thursday_of_year():
+ d = pendulum.date(1975, 8, 31).nth_of("year", 7, pendulum.THURSDAY)
+ assert_date(d, 1975, 2, 13)
+
+
+def test_first_of_invalid_unit():
+ d = pendulum.date(1975, 8, 5)
+
+ with pytest.raises(ValueError):
+ d.first_of("invalid", 3)
+
+
+def test_last_of_invalid_unit():
+ d = pendulum.date(1975, 8, 5)
+
+ with pytest.raises(ValueError):
+ d.last_of("invalid", 3)
+
+
+def test_nth_of_invalid_unit():
+ d = pendulum.date(1975, 8, 5)
+
+ with pytest.raises(ValueError):
+ d.nth_of("invalid", 3, pendulum.MONDAY)
diff --git a/tests/date/test_diff.py b/tests/date/test_diff.py
new file mode 100644
index 0000000..56358cc
--- /dev/null
+++ b/tests/date/test_diff.py
@@ -0,0 +1,365 @@
+from __future__ import annotations
+
+from datetime import date
+
+import pytest
+
+import pendulum
+
+
+@pytest.fixture
+def today():
+ return pendulum.today().date()
+
+
+def test_diff_in_years_positive():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.add(years=1)).in_years() == 1
+
+
+def test_diff_in_years_negative_with_sign():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.subtract(years=1), False).in_years() == -1
+
+
+def test_diff_in_years_negative_no_sign():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.subtract(years=1)).in_years() == 1
+
+
+def test_diff_in_years_vs_default_now(today):
+ assert today.subtract(years=1).diff().in_years() == 1
+
+
+def test_diff_in_years_ensure_is_truncated():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.add(years=1).add(months=7)).in_years() == 1
+
+
+def test_diff_in_months_positive():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.add(years=1).add(months=1)).in_months() == 13
+
+
+def test_diff_in_months_negative_with_sign():
+ dt = pendulum.date(2000, 1, 1)
+
+ assert dt.diff(dt.subtract(years=1).add(months=1), False).in_months() == -11
+
+
+def test_diff_in_months_negative_no_sign():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.subtract(years=1).add(months=1)).in_months() == 11
+
+
+def test_diff_in_months_vs_default_now(today):
+ assert today.subtract(years=1).diff().in_months() == 12
+
+
+def test_diff_in_months_ensure_is_truncated():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.add(months=1).add(days=16)).in_months() == 1
+
+
+def test_diff_in_days_positive():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.add(years=1)).in_days() == 366
+
+
+def test_diff_in_days_negative_with_sign():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.subtract(years=1), False).in_days() == -365
+
+
+def test_diff_in_days_negative_no_sign():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.subtract(years=1)).in_days() == 365
+
+
+def test_diff_in_days_vs_default_now(today):
+ assert today.subtract(weeks=1).diff().in_days() == 7
+
+
+def test_diff_in_weeks_positive():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.add(years=1)).in_weeks() == 52
+
+
+def test_diff_in_weeks_negative_with_sign():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.subtract(years=1), False).in_weeks() == -52
+
+
+def test_diff_in_weeks_negative_no_sign():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.subtract(years=1)).in_weeks() == 52
+
+
+def test_diff_in_weeks_vs_default_now(today):
+ assert today.subtract(weeks=1).diff().in_weeks() == 1
+
+
+def test_diff_in_weeks_ensure_is_truncated():
+ dt = pendulum.date(2000, 1, 1)
+ assert dt.diff(dt.add(weeks=1).subtract(days=1)).in_weeks() == 0
+
+
+def test_diff_for_humans_now_and_day(today):
+ assert today.subtract(days=1).diff_for_humans() == "1 day ago"
+
+
+def test_diff_for_humans_now_and_days(today):
+ assert today.subtract(days=2).diff_for_humans() == "2 days ago"
+
+
+def test_diff_for_humans_now_and_nearly_week(today):
+ assert today.subtract(days=6).diff_for_humans() == "6 days ago"
+
+
+def test_diff_for_humans_now_and_week(today):
+ assert today.subtract(weeks=1).diff_for_humans() == "1 week ago"
+
+
+def test_diff_for_humans_now_and_weeks(today):
+ assert today.subtract(weeks=2).diff_for_humans() == "2 weeks ago"
+
+
+def test_diff_for_humans_now_and_nearly_month(today):
+ assert today.subtract(weeks=3).diff_for_humans() == "3 weeks ago"
+
+
+def test_diff_for_humans_now_and_month():
+ with pendulum.travel_to(pendulum.datetime(2016, 4, 1)):
+ today = pendulum.today().date()
+
+ assert today.subtract(weeks=4).diff_for_humans() == "4 weeks ago"
+ assert today.subtract(months=1).diff_for_humans() == "1 month ago"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 3, 1)):
+ today = pendulum.today().date()
+
+ assert today.subtract(weeks=4).diff_for_humans() == "1 month ago"
+
+
+def test_diff_for_humans_now_and_months(today):
+ assert today.subtract(months=2).diff_for_humans() == "2 months ago"
+
+
+def test_diff_for_humans_now_and_nearly_year(today):
+ assert today.subtract(months=11).diff_for_humans() == "11 months ago"
+
+
+def test_diff_for_humans_now_and_year(today):
+ assert today.subtract(years=1).diff_for_humans() == "1 year ago"
+
+
+def test_diff_for_humans_now_and_years(today):
+ assert today.subtract(years=2).diff_for_humans() == "2 years ago"
+
+
+def test_diff_for_humans_now_and_future_day(today):
+ assert today.add(days=1).diff_for_humans() == "in 1 day"
+
+
+def test_diff_for_humans_now_and_future_days(today):
+ assert today.add(days=2).diff_for_humans() == "in 2 days"
+
+
+def test_diff_for_humans_now_and_nearly_future_week(today):
+ assert today.add(days=6).diff_for_humans() == "in 6 days"
+
+
+def test_diff_for_humans_now_and_future_week(today):
+ assert today.add(weeks=1).diff_for_humans() == "in 1 week"
+
+
+def test_diff_for_humans_now_and_future_weeks(today):
+ assert today.add(weeks=2).diff_for_humans() == "in 2 weeks"
+
+
+def test_diff_for_humans_now_and_nearly_future_month(today):
+ assert today.add(weeks=3).diff_for_humans() == "in 3 weeks"
+
+
+def test_diff_for_humans_now_and_future_month():
+ with pendulum.travel_to(pendulum.datetime(2016, 3, 1)):
+ today = pendulum.today("UTC").date()
+
+ assert today.add(weeks=4).diff_for_humans() == "in 4 weeks"
+ assert today.add(months=1).diff_for_humans() == "in 1 month"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 3, 31)):
+ today = pendulum.today("UTC").date()
+
+ assert today.add(months=1).diff_for_humans() == "in 1 month"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 4, 30)):
+ today = pendulum.today("UTC").date()
+
+ assert today.add(months=1).diff_for_humans() == "in 1 month"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 1, 31)):
+ today = pendulum.today("UTC").date()
+
+ assert today.add(weeks=4).diff_for_humans() == "in 1 month"
+
+
+def test_diff_for_humans_now_and_future_months(today):
+ assert today.add(months=2).diff_for_humans() == "in 2 months"
+
+
+def test_diff_for_humans_now_and_nearly_future_year(today):
+ assert today.add(months=11).diff_for_humans() == "in 11 months"
+
+
+def test_diff_for_humans_now_and_future_year(today):
+ assert today.add(years=1).diff_for_humans() == "in 1 year"
+
+
+def test_diff_for_humans_now_and_future_years(today):
+ assert today.add(years=2).diff_for_humans() == "in 2 years"
+
+
+def test_diff_for_humans_other_and_day(today):
+ assert today.diff_for_humans(today.add(days=1)) == "1 day before"
+
+
+def test_diff_for_humans_other_and_days(today):
+ assert today.diff_for_humans(today.add(days=2)) == "2 days before"
+
+
+def test_diff_for_humans_other_and_nearly_week(today):
+ assert today.diff_for_humans(today.add(days=6)) == "6 days before"
+
+
+def test_diff_for_humans_other_and_week(today):
+ assert today.diff_for_humans(today.add(weeks=1)) == "1 week before"
+
+
+def test_diff_for_humans_other_and_weeks(today):
+ assert today.diff_for_humans(today.add(weeks=2)) == "2 weeks before"
+
+
+def test_diff_for_humans_other_and_nearly_month(today):
+ assert today.diff_for_humans(today.add(weeks=3)) == "3 weeks before"
+
+
+def test_diff_for_humans_other_and_month():
+ with pendulum.travel_to(pendulum.datetime(2016, 3, 1)):
+ today = pendulum.today().date()
+
+ assert today.diff_for_humans(today.add(weeks=4)) == "4 weeks before"
+ assert today.diff_for_humans(today.add(months=1)) == "1 month before"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 3, 31)):
+ today = pendulum.today().date()
+
+ assert today.diff_for_humans(today.add(months=1)) == "1 month before"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 4, 30)):
+ today = pendulum.today().date()
+
+ assert today.diff_for_humans(today.add(months=1)) == "1 month before"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 1, 31)):
+ today = pendulum.today().date()
+
+ assert today.diff_for_humans(today.add(weeks=4)) == "1 month before"
+
+
+def test_diff_for_humans_other_and_months(today):
+ assert today.diff_for_humans(today.add(months=2)) == "2 months before"
+
+
+def test_diff_for_humans_other_and_nearly_year(today):
+ assert today.diff_for_humans(today.add(months=11)) == "11 months before"
+
+
+def test_diff_for_humans_other_and_year(today):
+ assert today.diff_for_humans(today.add(years=1)) == "1 year before"
+
+
+def test_diff_for_humans_other_and_years(today):
+ assert today.diff_for_humans(today.add(years=2)) == "2 years before"
+
+
+def test_diff_for_humans_other_and_future_day(today):
+ assert today.diff_for_humans(today.subtract(days=1)) == "1 day after"
+
+
+def test_diff_for_humans_other_and_future_days(today):
+ assert today.diff_for_humans(today.subtract(days=2)) == "2 days after"
+
+
+def test_diff_for_humans_other_and_nearly_future_week(today):
+ assert today.diff_for_humans(today.subtract(days=6)) == "6 days after"
+
+
+def test_diff_for_humans_other_and_future_week(today):
+ assert today.diff_for_humans(today.subtract(weeks=1)) == "1 week after"
+
+
+def test_diff_for_humans_other_and_future_weeks(today):
+ assert today.diff_for_humans(today.subtract(weeks=2)) == "2 weeks after"
+
+
+def test_diff_for_humans_other_and_nearly_future_month(today):
+ assert today.diff_for_humans(today.subtract(weeks=3)) == "3 weeks after"
+
+
+def test_diff_for_humans_other_and_future_month():
+ with pendulum.travel_to(pendulum.datetime(2016, 3, 1)):
+ today = pendulum.today().date()
+
+ assert today.diff_for_humans(today.subtract(weeks=4)) == "4 weeks after"
+ assert today.diff_for_humans(today.subtract(months=1)) == "1 month after"
+
+ with pendulum.travel_to(pendulum.datetime(2017, 2, 28)):
+ today = pendulum.today().date()
+
+ assert today.diff_for_humans(today.subtract(weeks=4)) == "1 month after"
+
+
+def test_diff_for_humans_other_and_future_months(today):
+ assert today.diff_for_humans(today.subtract(months=2)) == "2 months after"
+
+
+def test_diff_for_humans_other_and_nearly_future_year(today):
+ assert today.diff_for_humans(today.subtract(months=11)) == "11 months after"
+
+
+def test_diff_for_humans_other_and_future_year(today):
+ assert today.diff_for_humans(today.subtract(years=1)) == "1 year after"
+
+
+def test_diff_for_humans_other_and_future_years(today):
+ assert today.diff_for_humans(today.subtract(years=2)) == "2 years after"
+
+
+def test_diff_for_humans_absolute_days(today):
+ assert today.diff_for_humans(today.subtract(days=2), True) == "2 days"
+ assert today.diff_for_humans(today.add(days=2), True) == "2 days"
+
+
+def test_diff_for_humans_absolute_weeks(today):
+ assert today.diff_for_humans(today.subtract(weeks=2), True) == "2 weeks"
+ assert today.diff_for_humans(today.add(weeks=2), True) == "2 weeks"
+
+
+def test_diff_for_humans_absolute_months(today):
+ assert today.diff_for_humans(today.subtract(months=2), True) == "2 months"
+ assert today.diff_for_humans(today.add(months=2), True) == "2 months"
+
+
+def test_diff_for_humans_absolute_years(today):
+ assert today.diff_for_humans(today.subtract(years=1), True) == "1 year"
+ assert today.diff_for_humans(today.add(years=1), True) == "1 year"
+
+
+def test_subtraction():
+ d = pendulum.date(2016, 7, 5)
+ future_dt = date(2016, 7, 6)
+ future = d.add(days=1)
+
+ assert (future - d).total_seconds() == 86400
+ assert (future_dt - d).total_seconds() == 86400
diff --git a/tests/date/test_fluent_setters.py b/tests/date/test_fluent_setters.py
new file mode 100644
index 0000000..c76cc2f
--- /dev/null
+++ b/tests/date/test_fluent_setters.py
@@ -0,0 +1,29 @@
+from __future__ import annotations
+
+import pendulum
+
+from tests.conftest import assert_date
+
+
+def test_fluid_year_setter():
+ d = pendulum.Date(2016, 10, 20)
+ new = d.set(year=1995)
+
+ assert_date(new, 1995, 10, 20)
+ assert new.year == 1995
+
+
+def test_fluid_month_setter():
+ d = pendulum.Date(2016, 7, 2)
+ new = d.set(month=11)
+
+ assert new.month == 11
+ assert d.month == 7
+
+
+def test_fluid_day_setter():
+ d = pendulum.Date(2016, 7, 2)
+ new = d.set(day=9)
+
+ assert new.day == 9
+ assert d.day == 2
diff --git a/tests/date/test_getters.py b/tests/date/test_getters.py
new file mode 100644
index 0000000..a492794
--- /dev/null
+++ b/tests/date/test_getters.py
@@ -0,0 +1,87 @@
+from __future__ import annotations
+
+import pendulum
+
+
+def test_year():
+ d = pendulum.Date(1234, 5, 6)
+ assert d.year == 1234
+
+
+def test_month():
+ d = pendulum.Date(1234, 5, 6)
+ assert d.month == 5
+
+
+def test_day():
+ d = pendulum.Date(1234, 5, 6)
+ assert d.day == 6
+
+
+def test_day_of_week():
+ d = pendulum.Date(2012, 5, 7)
+ assert d.day_of_week == pendulum.MONDAY
+
+
+def test_day_of_year():
+ d = pendulum.Date(2015, 12, 31)
+ assert d.day_of_year == 365
+ d = pendulum.Date(2016, 12, 31)
+ assert d.day_of_year == 366
+
+
+def test_days_in_month():
+ d = pendulum.Date(2012, 5, 7)
+ assert d.days_in_month == 31
+
+
+def test_age():
+ d = pendulum.Date.today()
+ assert d.age == 0
+ assert d.add(years=1).age == -1
+ assert d.subtract(years=1).age == 1
+
+
+def test_is_leap_year():
+ assert pendulum.Date(2012, 1, 1).is_leap_year()
+ assert not pendulum.Date(2011, 1, 1).is_leap_year()
+
+
+def test_is_long_year():
+ assert pendulum.Date(2015, 1, 1).is_long_year()
+ assert not pendulum.Date(2016, 1, 1).is_long_year()
+
+
+def test_week_of_month():
+ assert pendulum.Date(2012, 9, 30).week_of_month == 5
+ assert pendulum.Date(2012, 9, 28).week_of_month == 5
+ assert pendulum.Date(2012, 9, 20).week_of_month == 4
+ assert pendulum.Date(2012, 9, 8).week_of_month == 2
+ assert pendulum.Date(2012, 9, 1).week_of_month == 1
+ assert pendulum.date(2020, 1, 1).week_of_month == 1
+ assert pendulum.date(2020, 1, 7).week_of_month == 2
+ assert pendulum.date(2020, 1, 14).week_of_month == 3
+
+
+def test_week_of_year_first_week():
+ assert pendulum.Date(2012, 1, 1).week_of_year == 52
+ assert pendulum.Date(2012, 1, 2).week_of_year == 1
+
+
+def test_week_of_year_last_week():
+ assert pendulum.Date(2012, 12, 30).week_of_year == 52
+ assert pendulum.Date(2012, 12, 31).week_of_year == 1
+
+
+def test_is_future():
+ d = pendulum.Date.today()
+ assert not d.is_future()
+ d = d.add(days=1)
+ assert d.is_future()
+
+
+def test_is_past():
+ d = pendulum.Date.today()
+ assert not d.is_past()
+ d = d.subtract(days=1)
+ assert d.is_past()
diff --git a/tests/date/test_start_end_of.py b/tests/date/test_start_end_of.py
new file mode 100644
index 0000000..f1b4412
--- /dev/null
+++ b/tests/date/test_start_end_of.py
@@ -0,0 +1,252 @@
+from __future__ import annotations
+
+import pytest
+
+import pendulum
+
+from pendulum import Date
+from tests.conftest import assert_date
+
+
+def test_start_of_day():
+ d = Date.today()
+ new = d.start_of("day")
+ assert isinstance(new, Date)
+ assert_date(new, d.year, d.month, d.day)
+
+
+def test_end_of_day():
+ d = Date.today()
+ new = d.end_of("day")
+ assert isinstance(new, Date)
+ assert_date(new, d.year, d.month, d.day)
+
+
+def test_start_of_week():
+ d = Date(2016, 10, 20)
+ new = d.start_of("week")
+ assert isinstance(new, Date)
+ assert_date(new, d.year, d.month, 17)
+
+
+def test_end_of_week():
+ d = Date(2016, 10, 20)
+ new = d.end_of("week")
+ assert isinstance(new, Date)
+ assert_date(new, d.year, d.month, 23)
+
+
+def test_start_of_month_is_fluid():
+ d = Date.today()
+ assert isinstance(d.start_of("month"), Date)
+
+
+def test_start_of_month_from_now():
+ d = Date.today()
+ new = d.start_of("month")
+ assert_date(new, d.year, d.month, 1)
+
+
+def test_start_of_month_from_last_day():
+ d = Date(2000, 1, 31)
+ new = d.start_of("month")
+ assert_date(new, 2000, 1, 1)
+
+
+def test_start_of_year_is_fluid():
+ d = Date.today()
+ new = d.start_of("year")
+ assert isinstance(new, Date)
+
+
+def test_start_of_year_from_now():
+ d = Date.today()
+ new = d.start_of("year")
+ assert_date(new, d.year, 1, 1)
+
+
+def test_start_of_year_from_first_day():
+ d = Date(2000, 1, 1)
+ new = d.start_of("year")
+ assert_date(new, 2000, 1, 1)
+
+
+def test_start_of_year_from_last_day():
+ d = Date(2000, 12, 31)
+ new = d.start_of("year")
+ assert_date(new, 2000, 1, 1)
+
+
+def test_end_of_month_is_fluid():
+ d = Date.today()
+ assert isinstance(d.end_of("month"), Date)
+
+
+def test_end_of_month_from_now():
+ d = Date.today().start_of("month")
+ new = d.start_of("month")
+ assert_date(new, d.year, d.month, 1)
+
+
+def test_end_of_month():
+ d = Date(2000, 1, 1).end_of("month")
+ new = d.end_of("month")
+ assert_date(new, 2000, 1, 31)
+
+
+def test_end_of_month_from_last_day():
+ d = Date(2000, 1, 31)
+ new = d.end_of("month")
+ assert_date(new, 2000, 1, 31)
+
+
+def test_end_of_year_is_fluid():
+ d = Date.today()
+ assert isinstance(d.end_of("year"), Date)
+
+
+def test_end_of_year_from_now():
+ d = Date.today().end_of("year")
+ new = d.end_of("year")
+ assert_date(new, d.year, 12, 31)
+
+
+def test_end_of_year_from_first_day():
+ d = Date(2000, 1, 1)
+ new = d.end_of("year")
+ assert_date(new, 2000, 12, 31)
+
+
+def test_end_of_year_from_last_day():
+ d = Date(2000, 12, 31)
+ new = d.end_of("year")
+ assert_date(new, 2000, 12, 31)
+
+
+def test_start_of_decade_is_fluid():
+ d = Date.today()
+ assert isinstance(d.start_of("decade"), Date)
+
+
+def test_start_of_decade_from_now():
+ d = Date.today()
+ new = d.start_of("decade")
+ assert_date(new, d.year - d.year % 10, 1, 1)
+
+
+def test_start_of_decade_from_first_day():
+ d = Date(2000, 1, 1)
+ new = d.start_of("decade")
+ assert_date(new, 2000, 1, 1)
+
+
+def test_start_of_decade_from_last_day():
+ d = Date(2009, 12, 31)
+ new = d.start_of("decade")
+ assert_date(new, 2000, 1, 1)
+
+
+def test_end_of_decade_is_fluid():
+ d = Date.today()
+ assert isinstance(d.end_of("decade"), Date)
+
+
+def test_end_of_decade_from_now():
+ d = Date.today()
+ new = d.end_of("decade")
+ assert_date(new, d.year - d.year % 10 + 9, 12, 31)
+
+
+def test_end_of_decade_from_first_day():
+ d = Date(2000, 1, 1)
+ new = d.end_of("decade")
+ assert_date(new, 2009, 12, 31)
+
+
+def test_end_of_decade_from_last_day():
+ d = Date(2009, 12, 31)
+ new = d.end_of("decade")
+ assert_date(new, 2009, 12, 31)
+
+
+def test_start_of_century_is_fluid():
+ d = Date.today()
+ assert isinstance(d.start_of("century"), Date)
+
+
+def test_start_of_century_from_now():
+ d = Date.today()
+ new = d.start_of("century")
+ assert_date(new, d.year - d.year % 100 + 1, 1, 1)
+
+
+def test_start_of_century_from_first_day():
+ d = Date(2001, 1, 1)
+ new = d.start_of("century")
+ assert_date(new, 2001, 1, 1)
+
+
+def test_start_of_century_from_last_day():
+ d = Date(2100, 12, 31)
+ new = d.start_of("century")
+ assert_date(new, 2001, 1, 1)
+
+
+def test_end_of_century_is_fluid():
+ d = Date.today()
+ assert isinstance(d.end_of("century"), Date)
+
+
+def test_end_of_century_from_now():
+ now = Date.today()
+ d = now.end_of("century")
+ assert_date(d, now.year - now.year % 100 + 100, 12, 31)
+
+
+def test_end_of_century_from_first_day():
+ d = Date(2001, 1, 1)
+ new = d.end_of("century")
+ assert_date(new, 2100, 12, 31)
+
+
+def test_end_of_century_from_last_day():
+ d = Date(2100, 12, 31)
+ new = d.end_of("century")
+ assert_date(new, 2100, 12, 31)
+
+
+def test_average_is_fluid():
+ d = Date.today().average()
+ assert isinstance(d, Date)
+
+
+def test_average_from_same():
+ d1 = pendulum.date(2000, 1, 31)
+ d2 = pendulum.date(2000, 1, 31).average(d1)
+ assert_date(d2, 2000, 1, 31)
+
+
+def test_average_from_greater():
+ d1 = pendulum.date(2000, 1, 1)
+ d2 = pendulum.date(2009, 12, 31).average(d1)
+ assert_date(d2, 2004, 12, 31)
+
+
+def test_average_from_lower():
+ d1 = pendulum.date(2009, 12, 31)
+ d2 = pendulum.date(2000, 1, 1).average(d1)
+ assert_date(d2, 2004, 12, 31)
+
+
+def test_start_of():
+ d = pendulum.date(2013, 3, 31)
+
+ with pytest.raises(ValueError):
+ d.start_of("invalid")
+
+
+def test_end_of_invalid_unit():
+ d = pendulum.date(2013, 3, 31)
+
+ with pytest.raises(ValueError):
+ d.end_of("invalid")
diff --git a/tests/date/test_strings.py b/tests/date/test_strings.py
new file mode 100644
index 0000000..f373581
--- /dev/null
+++ b/tests/date/test_strings.py
@@ -0,0 +1,48 @@
+from __future__ import annotations
+
+import pendulum
+
+
+def test_to_string():
+ d = pendulum.Date(2016, 10, 16)
+ assert str(d) == "2016-10-16"
+
+
+def test_to_date_string():
+ d = pendulum.Date(1975, 12, 25)
+ assert d.to_date_string() == "1975-12-25"
+
+
+def test_to_formatted_date_string():
+ d = pendulum.Date(1975, 12, 25)
+ assert d.to_formatted_date_string() == "Dec 25, 1975"
+
+
+def test_repr():
+ d = pendulum.Date(1975, 12, 25)
+
+ assert repr(d) == "Date(1975, 12, 25)"
+ assert d.__repr__() == "Date(1975, 12, 25)"
+
+
+def test_format_with_locale():
+ d = pendulum.Date(1975, 12, 25)
+ expected = "jeudi 25e jour de décembre 1975"
+ assert d.format("dddd Do [jour de] MMMM YYYY", locale="fr") == expected
+
+
+def test_strftime():
+ d = pendulum.Date(1975, 12, 25)
+ assert d.strftime("%d") == "25"
+
+
+def test_for_json():
+ d = pendulum.Date(1975, 12, 25)
+ assert d.for_json() == "1975-12-25"
+
+
+def test_format():
+ d = pendulum.Date(1975, 12, 25)
+ assert f"{d}" == "1975-12-25"
+ assert f"{d:YYYY}" == "1975"
+ assert f"{d:%Y}" == "1975"
diff --git a/tests/date/test_sub.py b/tests/date/test_sub.py
new file mode 100644
index 0000000..33855a4
--- /dev/null
+++ b/tests/date/test_sub.py
@@ -0,0 +1,90 @@
+from __future__ import annotations
+
+from datetime import datetime
+from datetime import timedelta
+
+import pytest
+
+import pendulum
+
+from tests.conftest import assert_date
+
+
+def test_subtract_years_positive():
+ assert pendulum.date(1975, 1, 1).subtract(years=1).year == 1974
+
+
+def test_subtract_years_zero():
+ assert pendulum.date(1975, 1, 1).subtract(years=0).year == 1975
+
+
+def test_subtract_years_negative():
+ assert pendulum.date(1975, 1, 1).subtract(years=-1).year == 1976
+
+
+def test_subtract_months_positive():
+ assert pendulum.date(1975, 1, 1).subtract(months=1).month == 12
+
+
+def test_subtract_months_zero():
+ assert pendulum.date(1975, 12, 1).subtract(months=0).month == 12
+
+
+def test_subtract_months_negative():
+ assert pendulum.date(1975, 11, 1).subtract(months=-1).month == 12
+
+
+def test_subtract_days_positive():
+ assert pendulum.Date(1975, 6, 1).subtract(days=1).day == 31
+
+
+def test_subtract_days_zero():
+ assert pendulum.Date(1975, 5, 31).subtract(days=0).day == 31
+
+
+def test_subtract_days_negative():
+ assert pendulum.Date(1975, 5, 30).subtract(days=-1).day == 31
+
+
+def test_subtract_days_max():
+ delta = pendulum.now() - pendulum.instance(datetime.min)
+ assert pendulum.now().subtract(days=delta.days - 1).year == 1
+
+
+def test_subtract_weeks_positive():
+ assert pendulum.Date(1975, 5, 28).subtract(weeks=1).day == 21
+
+
+def test_subtract_weeks_zero():
+ assert pendulum.Date(1975, 5, 21).subtract(weeks=0).day == 21
+
+
+def test_subtract_weeks_negative():
+ assert pendulum.Date(1975, 5, 14).subtract(weeks=-1).day == 21
+
+
+def test_subtract_timedelta():
+ delta = timedelta(days=18)
+ d = pendulum.date(2015, 3, 14)
+
+ new = d - delta
+ assert isinstance(new, pendulum.Date)
+ assert_date(new, 2015, 2, 24)
+
+
+def test_subtract_duration():
+ delta = pendulum.duration(years=2, months=3, days=18)
+ d = pendulum.date(2015, 3, 14)
+
+ new = d - delta
+ assert_date(new, 2012, 11, 26)
+
+
+def test_addition_invalid_type():
+ d = pendulum.date(2015, 3, 14)
+
+ with pytest.raises(TypeError):
+ d - "ab"
+
+ with pytest.raises(TypeError):
+ "ab" - d