#30128: Using timezone created with datetime.timedelta causes incorrect 
timezone in
SQL query.
-------------------------------------+-------------------------------------
               Reporter:  mvarnar    |          Owner:  nobody
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  2.1
  layer (models, ORM)                |       Keywords:  orm, postgresql,
               Severity:  Normal     |  timezone, datetime
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 I haven’t checked this bug with other databases, but it definitely works
 improperly with postgres.
 Django ORM create incorrect query when I use timezone determined like
 "timezone(timedelta(hours=some_hours))".
 "timezone(timedelta(hours=5))" in query will look like "UTC+05:00", but
 postgres doesn't know this timezone name and handle it as POSIX style.
 "UTC" part will be interpreted as some zone abbreviation and timezone will
 be shifted by 5 hours to the west (positive shift is shift to the west in
 accordance with POSIX standart), i.e. actually timezone will be equal to
 UTC-5.

 From https://www.postgresql.org/docs/10/datatype-datetime.html :
 "In addition to the timezone names and abbreviations, PostgreSQL will
 accept POSIX-style time zone specifications of the form STDoffset or
 STDoffsetDST, where STD is a zone abbreviation, offset is a numeric offset
 in hours west from UTC"

 Checked with:
 django==2.1.5
 psycopg2==2.7.6.1
 postgreSQL==10.6

 Using the following example model:
 {{{
 class test(models.Model):
     class Meta:
         db_table = 'test_timezones'

     datetime = models.DateTimeField()
 }}}

 Sample of bug is bellow:

 {{{
 >>> from datetime import timezone, timedelta
 >>> from django.db.models.functions import ExtractWeekDay
 >>> from django_issues.models import test
 >>> from django.db.models.functions import ExtractHour
 >>> from pytz import timezone as pytz_timezone
 >>>
 print(test.objects.annotate(hour=ExtractHour('datetime')).values('datetime',
 'hour').get())
 {'datetime': datetime.datetime(2018, 1, 1, 7, 0, tzinfo=<UTC>), 'hour': 7}
 >>> tz = timezone(timedelta(hours=5))
 >>> print(tz)
 UTC+05:00
 >>> print(test.objects.annotate(hour=ExtractHour('datetime',
 tzinfo=tz)).values('datetime', 'hour').get())
 {'datetime': datetime.datetime(2018, 1, 1, 7, 0, tzinfo=<UTC>), 'hour': 2}
 >>> print(test.objects.annotate(hour=ExtractHour('datetime',
 tzinfo=tz)).values('datetime', 'hour').query)
 SELECT "test_timezones"."datetime", EXTRACT('hour' FROM
 "test_timezones"."datetime" AT TIME ZONE 'UTC+05:00') AS "hour" FROM
 "test_timezones"
 >>> tz2 = pytz_timezone('Asia/Yekaterinburg')
 >>> print(tz2)
 Asia/Yekaterinburg
 >>> print(test.objects.annotate(hour=ExtractHour('datetime',
 tzinfo=tz2)).values('datetime', 'hour').get())
 {'datetime': datetime.datetime(2018, 1, 1, 7, 0, tzinfo=<UTC>), 'hour':
 12}
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30128>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.da304c19b5d1651765c2d3ff2bbfac5d%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to