Django: Store gmt time in database table instead of local time - python

In my customer model I have two datetime fields for storing created and updated time.
datetime_created = models.DateTimeField(auto_now_add=True)
datetime_updated = models.DateTimeField(auto_now=True)
When I create a customer, Now it is storing the local time in the database, When I get this customer data through API, It is returning the datetime in gmt time. This is fine. But I want to save the gmt time in the database. I think storing local time in database is not a good practice.
Date settings in settings.py file is
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
I have already installed "pip install pytz" module and my database is postgresql.

Best practice is to save it in UTC format.
USE_TZ = True in your settings, Django stores date and time information in UTC in the database otherwise it will store naive date time

You're rigth, the best practice is to save in UTC your datetime fields, and to convert it to your convenience in your views using pytz or in your templates using tz tag.
IE, you can use pytz to convert your datetime in an specific datetime in your views
import pytz
datetime_with_new_tz = object.created_at.astimezone(pytz.timezone(YOUR_LOCAL_TIMEZONE))`
if you want to convert the timezone in your template, you can use tz
{% load tz %}
{{object.created_at|timezone:YOUR_LOCAL_TIMEZONE}}

Related

Django-models Change format of dateField as "DD-MM-YYY"

I am using django-model's-dateField in my django-project and wanna change my dateFields format in admin view.
Currently (default) django gives format in YYYY-MM-DD but i want to modify that and in need of DD-MM-YYYY
I've been struggled too much in this and till no solution.
Also providing my code, may help..
my settings.py have:
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='User_Profile')
mobile = models.BigIntegerField()
alternative_number = models.BigIntegerField()
DOB = models.DateField()
and then i register it in admin
output on admin
as you can see in my admin page there is a dateField with format 2019-11-04 but i want in form of DD-MM-YYYY as 04-11-2019.
I tried LANGUAGE_CODE = 'de-at' that would work for me but the problem is, it changes the local language also.
refering a similer post:
Django - change default presentation format of model date field
You need just to override Django’s defaults locale settings. Add this to your settings.py file
from django.conf.locale.es import formats as es_formats
es_formats.DATETIME_FORMAT = "d M Y H:i:s"
fahim kazi was right: to define a models.DateField format, you need DATE_FORMAT, not DATETIME_FORMAT.
Yet Naveen Varshney was also right: not DATE_FORMAT nor DATETIME_FORMAT work without specifying the language, with es_formats for instance.
Therefore, from the combination of both answers, put the following in settings:
es_formats.DATE_FORMAT = 'd-m-y'
(Also '%d-%m-%y' printed %01-%08-%20 thus the % is not needed).
Thanks both.
add this to your settings.py
DATE_FORMAT = '%d-%m-%y'
for more check this date format

datetime display and timezone converting in django

in settings.py file:
TIME_ZONE = 'UTC'
USE_TZ = True
in models.py:
from django.utils import timezone
date = models.DateTimeField(default = timezone.now())
before pip install pytz,date field in mysql db stored as UTC time, and date in front end webpage display as localtime. but after pip install pytz,date field in mysql db stored as UTC time, at the same time date in front end webpage display as UTC time too.
What is the reason for this?
How to do make sure that after pip install pytz,date field in mysql db stored as UTC time, and date in front end webpage display as localtime?
BTW, which library is more easily done than pytz?
Just change your TIME_ZONE setting to your local time's pytz.
e.g.
TIME_ZONE = 'Asia/Dubai'

Django - query (month/day) filter only works when USE_TZ = False

How can I get the "latest_events_list" query below to work with day/month?
The below query only works if USE_TZ = False in settings.py. When I set USE_TZ = True, it doesn't query any objects.
Query for "year" works regardless of USE_TZ settings.
begin_datetime is a DateTime field in Event model.
views.py
today = datetime.datetime.now()
# list of events ordered and filter
latest_events_list = Event.objects.filter(begin_datetime__day = today.day)
My guess has to do with UTC and localtime - but I'm not sure. Thanks!
As Gocht helped mention in his comment above:
My MySQL server timezone needed to be in UTC time zone.
In addition, for those looking to change server time zone - be sure to restart the server or else changes may not take place.
Cheers

Django DateTimeField from form to UTC

I have a small Django app with a form, wich saves some data to the DB.
Here's the form:
class SomeForm(forms.Form):
time = forms.DateTimeField()
...
And the view, where I save it:
class AccountAddIncome(View):
def save(self, form):
model = Model(
time=form.cleaned_data['time']
)
model.save()
def post(self, request, *args, **kwargs):
form = SomeForm(request.POST)
if form.is_valid():
self.save(form)
return redirect(self.success_url)
else:
...
My problem is, that the Django admin says: "Note: You are 1 hour ahead of server time."
The date command on my Ubuntu (the server) says exactly the same date as my computer has.
But, when I save this object in the DB, and make the following query:
Model.objects.filter(time__lt=timezone.now())
django do not list the previously saved model for an hour. If I go to the admin, and set the time back one hour, django'll show that object.
So, my question is, what's the best practice, to manage datetime objects in django?
I want to save everything in UTC, but I cannot convert that datetime from the form to UTC.
go to settings.py of your Django project
comment timezone settings and use TIME_ZONE = timezone.now()
from django.utils import timezone
TIME_ZONE = timezone.now()
# TIME_ZONE = 'UTC'
# USE_I18N = True
# USE_L10N = True
# USE_TZ = True
Than you will never see this - Note: You are 1 hour ahead of server time.

How do I get the visitor's current timezone then convert timezone.now() to string of the local time in Django 1.4?

I understand that the best practice now with Django 1.4 is to store all datetime in UTC and I agree with that. I also understand that all timezone conversation should be done in the template level like this:
{% load tz %}
{% timezone "Europe/Paris" %}
Paris time: {{ value }}
{% endtimezone %}
However, I need to convert the UTC time to the request's local time all in Python. I can't use the template tags since I am returning the string in JSON using Ajax (more specifically Dajaxice).
Currently this is my code ajax.py:
# checked is from the checkbox's this.value (Javascript).
datetime = timezone.now() if checked else None
$ order_pk is sent to the Ajax function.
order = Order.objects.get(pk=order_pk)
order.time = datetime
order.save()
return simplejson.dumps({
'error': False,
'datetime': dateformat.format(datetime, 'F j, Y, P') if checked else 'None'
})
So even if the current time is April 14, 2012, 5:52 p.m. in EST time (my local timezone), the JSON response will return April 14, 2012, 9:52 p.m, because that is the UTC time.
Also I noticed that Django stores a template variable called TIME_ZONE for each request (not actually part of the request variable), so since my is America/New_York, I'm assuming that Django can figure out each visitor's own local timezone (based on HTTP header)?
Anyway, so my question is two-fold:
How do I get the visitor's local timezone in my ajax.py? (Probably pass it as a string argument like {{ TIME_ZONE }})
With the visitor's local timezone, how to convert the UTC timezone.now() to the local timezone and output as a string using Django's dateformat?
EDIT: for #agf
timezone.now() gives the UTC time when USE_TZ = True:
# From django.utils.timezone
def now():
"""
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
"""
if settings.USE_TZ:
# timeit shows that datetime.now(tz=utc) is 24% slower
return datetime.utcnow().replace(tzinfo=utc)
else:
return datetime.now()
Is there anyway to convert a datetime to something other than UTC? For example, can I do something like current_time = timezone.now(), then current_time.replace(tzinfo=est) (EST = Eastern Standard Time)?
You need to read the Django Timezones docs carefully.
One important point:
there's no equivalent of the Accept-Language HTTP header that Django could use to determine the user's time zone automatically.
You have to ask the user what their timezone is or just use a default.
You also need to make sure:
USE_TZ = True
in your settings.py.
Once you have a timezone tz, you can:
from django.utils import timezone
timezone.activate(tz)
datetime = timezone.now() if checked else None
to get a timezone-aware datetime object in timezone tz.
While the browser does not send any headers to the server that would indicate a timezone, the JavaScript environment does know its current timezone.
This has two important effects: While the server can't find out your current timezone on the initial request, you can send down some javascript code which will determine the TZ offset and send that information back to the server so that the zone info can be associated with the current session from that point forward.
But more importantly, if you're sending your time value inside JSON data which will be interpreted by the browser client-side, the browser's timezone doesn't need to be known. Instead, you only have to ensure the timezone offset is present in your JSON output so that the browser can do its own timezone math after-the-fact.
var now = new Date()
var offset_minutes = now.getTimezoneOffset() # e.g. 240 for GMT-0400
Since you want the users' timezones, it makes sense to me that this should be done on the browser with Javascript.
I pass something like this into the template:
{"t": str(obj.timestamp))
Where obj is an instance of a django model where the timestamp field is of type DateTimeField.
The template:
<div class="timestring">{{ t }}</div>
...
<script>
$('.timestring').each(function(){
var d = new Date($(this).text());
$(this).text(d.toLocaleDateString() + ", " + d.toLocaleFormat("%r (%Z)"));
})
</script>
For me, this outputs something like: 2/15/2017, 05:22:24 PM (PST)
The relevant documentation:
Javascript Date class (see especially the constructor which accepts datestrings, and the toLocaleFormat() method)
strftime (comes with lots of date formatting shortcuts)

Categories