Django: time zone issue - django

NOTE: I deleted the question as it existed previously and providing only the relevant info here.
Our database server (RH) has TIME_ZONE = "Europe/London" specified. And, within the Django settings.py, we specify TIME_ZONE = "America/New_York".
And, in my Model class I have specified:
created = models.DateTimeField(editable=False,auto_now=False, auto_now_add=True)
modified = models.DateTimeField(editable=False,auto_now=True, auto_now_add=True)
When I then go look at the data in the admin site, I get UTC/GMT time instead of Eastern.
I thought that all time is adjusted automagically by Django since I specified "America/New_York" as Django's Time Zone.
Any help/clarification is appreciated.
Thanks
Eric

Relying on date/time 'automagic' is dangerous and these auto_add model parameters are a trap. Always understand the timezone(s) you are dealing with. Python makes this easier by attaching a tzinfo member to its datetime objects. While these objects are 'naive' by default, I encourage you to always attach tzinfo detail. Still Python needs some extra help with either python-dateutil or pytz (what I use). Here's a universal rule though - always store your datetimes in a database as UTC.
Why? Your users may be in different locals, mobile phones and laptops travel, servers are misconfigured or mirrored in different timezones. So many headaches. Datetimes should never be naive and if they are (as in a database) and you need the context, also include a timezone field in the table.
So in your case.
Don't use the auto_now fields, use a custom save() instead.
Store UTC in the database
If you need to know the timezone - for say a user event - store the timezone in the database as well.
Convert to the necessary/requested timezone
If you are using pytz, the localize() method is great. Python's datetime object has the useful replace() and astimezone().
One more note, if your database is timezone naive (like MySQL) make sure your datetimes are in UTC and then use replace(tzinfo=None) because the database connector can't handle tz-aware objects.
Here is a thread with detail on Django's auto_now fields.

The simplest/fastest fix [said above by Ajay Yadav] is this ,
Just add TIME_ZONE attribute to the Database's section in settings.py,
settings.py
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'TIME_ZONE': 'Asia/Tokyo',
}
}
For the available Timezone choices , See the Official documentation linked below ,
DJANGO TIMEZONE CHOICES

First off, I would want to store my data as UTC cause its a good starting point.
So let me ask this, Why do you need the time in EST, is this for the end-user, or do you need to do logic on the server and need it in EST?
If its for the enduser, an easy fix is to let the users browser handle converting to the correct time. On the server convert the datetime object to a timestamp:
timestamp = time.mktime(datetime_obj.timetuple()) * 1000
And then on the web page instantiate a Date object:
var date_obj = new Date({{ timestamp }});
var datetime_string = date_obj.toString();
// the datetime_string will be in the users local timezone
Now, on the other hand, if you want to have the time in the correct zone on the server so you can perform logic on it. I recommend using the help of python-dateutil. It will allow you to easily swap to a different timezone:
from datetime import datetime
from dateutil import zoneinfo
from_zone = zoneinfo.gettz('UTC')
to_zone = zoneinfo.gettz('America/New_York')
utc = created # your datetime object from the db
# Tell the datetime object that it's in UTC time zone since
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)
# Convert time zone
eastern_time = utc.aztimezone(to_zone)
Now if you really wanna store the datetime in EST, you need change the time on the DB server (like Ajay Yadav and gorus said). I don't know why you want to store them as EST, but then again I don't know what your application is.

When you say auto_now_add=True, the value will be added by your database server and not your django server. So you need to set time zone on your database server.

Since you edited the question, I'll edit my answer :) Django cannot control the time zone of your db, so the way to fix this is to update the time zone for your db. For MySql, run this query:
SELECT ##global.time_zone, ##session.time_zone;
This should return SYSTEM, SYSTEM by default, which in your case means "Europe/London", and the cause of your problem. Now that you've verified this, follow the instructions in the first comment on this page:
http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
Remember to restart MySql server after you've updated the time zone for the changes to take effect.

Related

Dynamic setting the timestamp fields in superset dashboards

I'm building few dashboards in Apache superset. All my available timestamp fields are in UTC timezone. (for example fields are, class_start_time & class_end_time).
I want that in the timezone the dashboard is opened all the timestamp fields will be automatically converted.
For example, I'm opening dashboard in Norway , so the UTC data should be converted to CET timezone of Norway.
I have tried to add some value here in Hours offset but its not working.
Can you please guide how we can achieve this.?
Just for reference :
In Kibana dashboards (ELK stack) have feature to automatically convert the timezone into which it is being opened. So I need same thing in Superset.
Normally you would be able to set this with environment variables when you start the program or container. In Apache Superset, this is not possible. There is an ongoing discussion on Github about this issue. One GitHub user posts the problem and workaround, which is far from workable:
Daylight savings causes issues where users have to update datasource
timezone offset for each datasource twice per year.
So the only thing you can do is update the hours offset twice a year. To make matters even worse, if you use Postgresql, this may not even be possible due to a bug as described here.

How to stop django postgresql timestramp conversion

When I Insert timestamp into Postgres table in EST (2019-02-21 05:37:46) and in Postgresql table is stores in IST (2019-02-21 16:07:46). I want time to be stored only in EST. Can anyone help me to fix this issue?
In postgres, you can change the default format mask for datetimes using the set n postgres, you can change the default format mask for datetimes using the set datestyle
for more details follow this link
also refer this link
To my knowledge, there is no setting in PostgreSQL that would trim seconds from timestamp literals by default
In general you should handle all datetimes in UTC, because these are absolute timestamps that are always correct. Even if you are only going to have users in the EST time zone use your website, the EST time zone has daylight saving time (DST) in the summer, so you could get buggy behaviour when the time jumps (especially since there is an overlap of one hour when the clock goes back). This means:
Your code should use UTC timestamps to make calculations and pass around
Your database should store UTC datetime (which PostgreSQL does anyway).
You should only transform to a local time zone when presenting the data to the user. This is default behaviour in Django:
USE_TZ = True by default
TIME_ZONE = "America/New_York" to set default time zone, which will take into account DST
So when you're saving a time-aware datetime to the database (in EST say), the database stores it as UTC. When you fetch and display it, Django will show it in the current time zone of the user (EST in your case). When you query the database directly using a tool, PostgreSQL gives back the UTC, correct datetime, but your shell or tool might display it in the local time zone. You can format your query to use a different time zone using the links posted by #c.grey in the other answer.
Read up on the details here

Django - can I save DateTime objects that have different timezones in the same column?

If I have a DateTimeField() in a model in my app, can I sometimes store a date time with one timezone and sometimes a different timezone?
Short answer: Yes, you can.
When Django saves the timezone, it saves it as the UTC time in the database. When it goes to display it again in your app, it will look for the settings.TIME_ZONE and apply that time zone. If you need to convert it back to a particular time zone, you will also need to store the string of which time zone it is.
More about: Django Time Zones.

Django international site with UTC

I am writing a site to be served internationally across multiple timezones.
In the settings.py:
TIME_ZONE = 'UTC'
USE_TZ = True
I am wondering if someone from NZ puts in a datetime via models.DateTimeField, does it automatically picks up the current timezone and convert to UTC without any extra code?
I am a bit confused on this paragraph:
The current time zone is the equivalent of the current locale for
translations. However, there’s no equivalent of the Accept-Language
HTTP header that Django could use to determine the user’s time zone
automatically. Instead, Django provides time zone selection functions.
Use them to build the time zone selection logic that makes sense for
you.
So do I have to override the save method to add the get_current_timezone()?
The key sentence there is: "However, there’s no equivalent of the Accept-Language HTTP header that Django could use to determine the user’s time zone automatically."
So there's no way for Django to reliably figure out your NZ user's time zone. It's not going to give you the user's time zone - you have to tell it! Specifically, until you explicitly activate() a time zone, the current time zone is just UTC as you defined in your TIME_ZONE setting.
When it comes to user input, the documentation says: "Django interprets datetimes entered in forms in the current time zone and returns aware datetime objects." So, if you've activated the appropriate NZ time zone then the conversion will happen as you expect. But if not, the datetime will be interpreted as being in your default UTC timezone.
How do you figure out the user's timezone? The documentation gives an example of how you can set it based on a value explicitly chosen by the user. I'm sure there are also services out there that try to guess the time zone based on the IP address. Either way, though, Django won't do it for you.

Using custom sql in Django

Is there a way to run a custum SQL statement in Django? I have some timestamp fields in my database that have timezone information. Normally you could just enter the time in a format like: 2010-7-30 15:11:22 EDT and in my case postgresql will figure it out. But in Django it treats timestamps as Datetimes which don't store timezone information so I can't just update the model object with this string and save it. Any ideas?
I somehow must have missed the link in the documentation that covers this: http://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly.