I am facing problem in my django app while working with DateTimeField
.Its mainly because of DST time changes.
I have created an event on 30-oct-2015(DST last week). I created a copy of first event which will be on 06-Nov-2015(Non DST day)
I applied timedelta
of 7 days , So it chaned days to 7+. But I did not aplly timedelta for hours.
Due to Day Light saving , its reduced by one hour. I dont need this. I just want to have same hours. How Can I do that.?
I tried with this , but did not help me.
DST timezone issue in django app
Please see this screenshot
my models.py
from django.db import models
from datetime import timedelta
class Event(models.Model):
name = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
start_date = models.DateTimeField()
def __unicode__(self):
return self.name
def copy_event(self, add_days=timedelta(days=7)):
start_date = self.start_date + add_days
name = self.name +' (copy)'
new_event = Event(name = name,created = self.created,start_date=start_date,)
new_event.save()
return new_event
The solution to this problem is to use UTC in the code and use local time only when interacting with end users. Time zone support is disabled by default. To enable it, set USE_TZ = True in your settings file. In Django 5.0, time zone support will be enabled by default.
You can use time. localtime and look at the tm_isdst flag in the return value. Using time. localtime() , you can ask the same question for any arbitrary time to see whether DST would be (or was) in effect for your current time zone.
Introduction to Django DateTimeField As per Django is concerned there are several field types through which the date and time values can be injected for storage on the models. The difference between these fields arises on the format of the data being stored. There are options to store only date value, even time value alone can be capture.
This article revolves around Date and time Fields in Serializers in Django REST Framework. There are four major fields – DateTimeField, DateField, TimeField and DurationField. DateTimeField is a serializer field used for date and time representation.
There are four major fields – DateTimeField, DateField, TimeField and DurationField. DateTimeField is a serializer field used for date and time representation. It is same as – DateTimeField – Django Models
The difference between these fields arises on the format of the data being stored. There are options to store only date value, even time value alone can be capture. As per datetime field both date and time values will be captured.
Since USE_TZ=True
you are always dealing with aware datetimes, which represent a precise moment in time. That moment in time will, in general, be displayed differently depending on the current time zone. Some time zones have DST and some don't, so in general there's no way you can store the datetime such that all users in all timezones will see the clock time you want (i.e. the same clock time as the event being copied).
I can think of a couple workarounds:
If it's the case that you're only serving one time zone (that is, the current time zone is always going to be the same), you can just do your arithmetic in that time zone.
from django.utils.timezone import localtime
new_start_date = localtime(self.start_date) + add_days
The addition of add_days
will always keep the clock time the same (that is, it doesn't take DST into account). The new_start_date
will be converted to and stored in UTC, and then converted back to the desired local time for display.
What you're really trying to represent is a particular clock time on a particular day, not an exact moment in time. So perhaps you don't want to be using aware datetimes at all. One option is to set USE_TZ=False
, but that's a global, far-reaching change that you may not want to make. Another option is to use a different representation for this field. For example, you could use a DateField
and a TimeField
instead of a DateTimeField
.
I was having this same problem creating repeated events in Django, and here's the solution I found that's pretty clean and - thus far - works. Using your code, where you have:
start_date = self.start_date + add_days
Try:
start_date = self.start_date.replace(tzinfo=None) + add_days
That converts the self.start_date parameter to a naive datetime, and allows the addition of days without accounting for the timezone. I've tested this extensively on my own, and it works both springing forward and falling back.
Reference: Converting timezone-aware datetime to local time in Python
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With