diff -r 727107721f4f Doc/library/sqlite3.rst --- a/Doc/library/sqlite3.rst Sun Oct 20 12:49:04 2013 +0300 +++ b/Doc/library/sqlite3.rst Sun Oct 20 22:09:27 2013 +0800 @@ -783,6 +783,8 @@ .. literalinclude:: ../includes/sqlite3/adapter_datetime.py + .. versionchanged:: 3.4 + Added timezone support in adapter for :class:`datetime.datetime`. Converting SQLite values to custom Python types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff -r 727107721f4f Lib/sqlite3/dbapi2.py --- a/Lib/sqlite3/dbapi2.py Sun Oct 20 12:49:04 2013 +0300 +++ b/Lib/sqlite3/dbapi2.py Sun Oct 20 22:09:27 2013 +0800 @@ -64,14 +64,34 @@ def convert_timestamp(val): datepart, timepart = val.split(b" ") year, month, day = map(int, datepart.split(b"-")) - timepart_full = timepart.split(b".") + + if b"+" in timepart: + naive_timepart, tz_offset = timepart.split(b"+") + tz_offset = b"+" + tz_offset + elif b"-" in timepart: + naive_timepart, tz_offset = timepart.split(b"-") + tz_offset = b"-" + tz_offset + else: + naive_timepart = timepart + tz_offset = None + + if tz_offset is not None: + offset_hours, offset_minutes = map(int, tz_offset.split(b':')) + tz_delta = datetime.timedelta(hours=offset_hours, + minutes=offset_minutes) + tzinfo = datetime.timezone(tz_delta) + else: + tzinfo = None + + timepart_full = naive_timepart.split(b".") hours, minutes, seconds = map(int, timepart_full[0].split(b":")) if len(timepart_full) == 2: microseconds = int('{:0<6.6}'.format(timepart_full[1].decode())) else: microseconds = 0 - val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds) + val = datetime.datetime(year, month, day, hours, minutes, seconds, + microseconds, tzinfo) return val diff -r 727107721f4f Lib/sqlite3/test/types.py --- a/Lib/sqlite3/test/types.py Sun Oct 20 12:49:04 2013 +0300 +++ b/Lib/sqlite3/test/types.py Sun Oct 20 22:09:27 2013 +0800 @@ -386,6 +386,30 @@ ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) + def CheckSqlTimestampWithTimezone(self): + class GMT1(datetime.tzinfo): + def utcoffset(self, dt): + return datetime.timedelta(hours=1) + gmt1 = GMT1() + + ts = sqlite.Timestamp(2006, 11, 21, 16, 30, tzinfo=gmt1) + self.cur.execute("insert into test(ts) values (?)", (ts,)) + self.cur.execute("select ts from test") + ts2 = self.cur.fetchone()[0] + self.assertEqual(ts, ts2) + + def CheckSqlTimestampWithNegativeTimezone(self): + class GMT_MINUS_5(datetime.tzinfo): + def utcoffset(self, dt): + return datetime.timedelta(hours=-5) + gmt_minus_5 = GMT_MINUS_5() + + ts = sqlite.Timestamp(2006, 11, 21, 16, 30, tzinfo=gmt_minus_5) + self.cur.execute("insert into test(ts) values (?)", (ts,)) + self.cur.execute("select ts from test") + ts2 = self.cur.fetchone()[0] + self.assertEqual(ts, ts2) + def suite(): sqlite_type_suite = unittest.makeSuite(SqliteTypeTests, "Check") decltypes_type_suite = unittest.makeSuite(DeclTypesTests, "Check") diff -r 727107721f4f Misc/NEWS --- a/Misc/NEWS Sun Oct 20 12:49:04 2013 +0300 +++ b/Misc/NEWS Sun Oct 20 22:09:27 2013 +0800 @@ -62,6 +62,9 @@ Library ------- +- Issue #19065: Added timezone support in sqlite3 adapter for + datetime.datetime. + - Issue #18235: Fix the sysconfig variables LDSHARED and BLDSHARED under AIX. Patch by David Edelsohn.