from .oids import builtins
# Register default adapters
-from . import array, json, composite, numeric, text # noqa
+from . import array, composite, date, json, numeric, text # noqa
# Register associations with array oids
array.register_all_arrays()
--- /dev/null
+"""
+Adapters for date/time types.
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+import codecs
+from datetime import date
+
+from ..adapt import Dumper
+from .oids import builtins
+
+
+@Dumper.text(date)
+class DateDumper(Dumper):
+
+ _encode = codecs.lookup("ascii").encode
+ DATE_OID = builtins["date"].oid
+
+ def dump(self, obj: date) -> bytes:
+ # NOTE: whatever the PostgreSQL DateStyle input format (DMY, MDY, YMD)
+ # the YYYY-MM-DD is always understood correctly.
+ return self._encode(str(obj))[0]
+
+ @property
+ def oid(self) -> int:
+ return self.DATE_OID
--- /dev/null
+import datetime as dt
+import pytest
+
+
+@pytest.mark.parametrize(
+ "val, expr",
+ [
+ (dt.date(1, 1, 1), "'0001-01-01'::date"),
+ (dt.date(1000, 1, 1), "'1000-01-01'::date"),
+ (dt.date(2000, 1, 1), "'2000-01-01'::date"),
+ (dt.date(2000, 12, 31), "'2000-12-31'::date"),
+ (dt.date(3000, 1, 1), "'3000-01-01'::date"),
+ ],
+)
+def test_dump_date(conn, val, expr):
+ cur = conn.cursor()
+ cur.execute("select %s = %%s" % expr, (val,))
+ assert cur.fetchone()[0] is True
+
+
+@pytest.mark.xfail # TODO: binary dump
+@pytest.mark.parametrize(
+ "val, expr", [(dt.date(2000, 1, 1), "'2000-01-01'::date")]
+)
+def test_dump_date_binary(conn, val, expr):
+ cur = conn.cursor()
+ cur.execute("select %s = %%b" % expr, (val,))
+ assert cur.fetchone()[0] is True
+
+
+@pytest.mark.parametrize("datestyle_in", ["DMY", "MDY", "YMD"])
+def test_dump_date_datestyle(conn, datestyle_in):
+ cur = conn.cursor()
+ cur.execute(f"set datestyle = ISO, {datestyle_in}")
+ cur.execute("select '2000-01-02'::date = %s", (dt.date(2000, 1, 2),))
+ assert cur.fetchone()[0]