44import datetime
55import uuid
66import warnings
7+ import sys
78
89from django .conf import settings
910from django .db .backends .base .operations import BaseDatabaseOperations
@@ -26,7 +27,7 @@ def max_in_list_size(self):
2627 return 2048
2728
2829 def _convert_field_to_tz (self , field_name , tzname ):
29- if settings .USE_TZ and not tzname == 'UTC' :
30+ if tzname and settings .USE_TZ and self . connection . timezone_name != tzname :
3031 offset = self ._get_utcoffset (tzname )
3132 field_name = 'DATEADD(second, %d, %s)' % (offset , field_name )
3233 return field_name
@@ -107,7 +108,7 @@ def combine_expression(self, connector, sub_expressions):
107108
108109 def convert_datetimefield_value (self , value , expression , connection ):
109110 if value is not None :
110- if settings .USE_TZ :
111+ if settings .USE_TZ and not timezone . is_aware ( value ) :
111112 value = timezone .make_aware (value , self .connection .timezone )
112113 return value
113114
@@ -129,6 +130,8 @@ def date_extract_sql(self, lookup_type, field_name):
129130 return "DATEPART(weekday, %s)" % field_name
130131 elif lookup_type == 'week' :
131132 return "DATEPART(iso_week, %s)" % field_name
133+ elif lookup_type == 'iso_week_day' :
134+ return "DATEPART(weekday, DATEADD(day, -1, %s))" % field_name
132135 elif lookup_type == 'iso_year' :
133136 return "YEAR(DATEADD(day, 26 - DATEPART(isoww, %s), %s))" % (field_name , field_name )
134137 else :
@@ -144,7 +147,8 @@ def date_interval_sql(self, timedelta):
144147 sql = 'DATEADD(microsecond, %d%%s, CAST(%s AS datetime2))' % (timedelta .microseconds , sql )
145148 return sql
146149
147- def date_trunc_sql (self , lookup_type , field_name , tzname = '' ):
150+ def date_trunc_sql (self , lookup_type , field_name , tzname = None ):
151+ field_name = self ._convert_field_to_tz (field_name , tzname )
148152 CONVERT_YEAR = 'CONVERT(varchar, DATEPART(year, %s))' % field_name
149153 CONVERT_QUARTER = 'CONVERT(varchar, 1+((DATEPART(quarter, %s)-1)*3))' % field_name
150154 CONVERT_MONTH = 'CONVERT(varchar, DATEPART(month, %s))' % field_name
@@ -480,9 +484,22 @@ def adapt_datetimefield_value(self, value):
480484 """
481485 if value is None :
482486 return None
483- if settings .USE_TZ and timezone .is_aware (value ):
484- # pyodbc donesn't support datetimeoffset
485- value = value .astimezone (self .connection .timezone ).replace (tzinfo = None )
487+
488+ # Expression values are adapted by the database.
489+ if hasattr (value , 'resolve_expression' ):
490+ return value
491+
492+ if timezone .is_aware (value ):
493+ if settings .USE_TZ :
494+ # When support for time zones is enabled, Django stores datetime information
495+ # in UTC in the database and uses time-zone-aware objects internally
496+ # source: https://docs.djangoproject.com/en/dev/topics/i18n/timezones/#overview
497+ value = value .astimezone (timezone .utc )
498+ else :
499+ # When USE_TZ is False, settings.TIME_ZONE is the time zone in
500+ # which Django will store all datetimes
501+ # source: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TIME_ZONE
502+ value = timezone .make_naive (value , self .connection .timezone )
486503 return value
487504
488505 def time_trunc_sql (self , lookup_type , field_name , tzname = '' ):
0 commit comments