Skip to content

Commit 88b3617

Browse files
committed
add limited support for timezone-sensitive functions using pytz
1 parent 66ae29e commit 88b3617

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

sql_server/pyodbc/operations.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
from django.utils import timezone
77
from django.utils.six import string_types
88

9+
try:
10+
import pytz
11+
except ImportError:
12+
pytz = None
13+
914

1015
class DatabaseOperations(BaseDatabaseOperations):
1116
_aggregate_functions = (
@@ -24,6 +29,22 @@ class DatabaseOperations(BaseDatabaseOperations):
2429
def __init__(self, connection):
2530
super(DatabaseOperations, self).__init__(connection)
2631

32+
def _get_utcoffset(self, tzname):
33+
"""
34+
Returns UTC offset for given time zone in seconds
35+
"""
36+
# SQL Server has no built-in support for tz database
37+
# see http://blogs.msdn.com/b/sqlprogrammability/archive/2008/03/18/using-time-zone-data-in-sql-server-2008.aspx
38+
if pytz is None:
39+
from django.core.exceptions import ImproperlyConfigured
40+
raise ImproperlyConfigured("This query requires pytz, "
41+
"but it isn't installed.")
42+
zone = pytz.timezone(tzname)
43+
# no way to take DST into account at this point
44+
now = datetime.datetime.now()
45+
delta = zone.localize(now, is_dst=False).utcoffset()
46+
return delta.days * 86400 + delta.seconds
47+
2748
def bulk_batch_size(self, fields, objs):
2849
"""
2950
Returns the maximum allowed batch size for the backend. The fields
@@ -97,17 +118,17 @@ def date_trunc_sql(self, lookup_type, field_name):
97118
return "CONVERT(datetime, CONVERT(varchar(12), %s, 112))" % field_name
98119

99120
def datetime_extract_sql(self, lookup_type, field_name, tzname):
100-
if settings.USE_TZ:
101-
# see http://blogs.msdn.com/b/sqlprogrammability/archive/2008/03/18/using-time-zone-data-in-sql-server-2008.aspx
102-
raise NotImplementedError('SQL Server has no built-in support for tz database.')
121+
if settings.USE_TZ and not tzname == 'UTC':
122+
offset = self._get_utcoffset(tzname)
123+
field_name = 'DATEADD(second, %d, %s)' % (offset, field_name)
103124
params = []
104125
sql = self.date_extract_sql(lookup_type, field_name)
105126
return sql, params
106127

107128
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
108-
if settings.USE_TZ:
109-
# see http://blogs.msdn.com/b/sqlprogrammability/archive/2008/03/18/using-time-zone-data-in-sql-server-2008.aspx
110-
raise NotImplementedError('SQL Server has no built-in support for tz database.')
129+
if settings.USE_TZ and not tzname == 'UTC':
130+
offset = self._get_utcoffset(tzname)
131+
field_name = 'DATEADD(second, %d, %s)' % (offset, field_name)
111132
params = []
112133
sql = ''
113134
if lookup_type in ('year', 'month', 'day'):

0 commit comments

Comments
 (0)