Django: DateTimeField received a naive datetime - python

I am working on creating a view that will only display posts whose deadlines dates have not passed. accomplish this I've added the following my views.py file:
current_posts = Posts.objects.filter(post_name=post, deadline__range=[date.today(), "2999-12-31"]).order_by('deadline')
This way I am able to only show posts whose deadline range fall between today and December 31, 2999. However I get the following error, and no posts show at all:
RuntimeWarning: DateTimeField OfferedFunds.deadline received a naive datetime (2999-12-31 00:00:00) while time zone support is active.
RuntimeWarning)
Past solutions posted left me trying the following which also does not work:
timezone.now()
current_posts = Posts.objects.filter(post_name=post, deadline__range=[timezone.now(), "2999-12-31"]).order_by('deadline')
What does work is if instead of entering: timezone.now(), I enter an actual date like "2015-10-10" however this defeats the purpose. Any ideas on how I can solve this?

Instead of checking a range, you can do deadline__gte=timezone.now()
This page has more info: https://docs.djangoproject.com/en/stable/ref/models/querysets/#gte

I actually ran into this problem today at work! Basically the deadline__range=[date.today(), '2999-10-10'] line has a UTC aware time in the first slot and a UTC unaware time in the second slot. Let me guide you to the post that helped me How to make an unaware datetime timezone aware in python. There are some pure python solutions and some django solutions but I think you'll find what you need there!

In your settings.py set USE_TZ = False, so that should fix the warning. In my case I wanted to work with native datetime globally so that's what I ended up doing. Cheers!

Related

How to calculate how many minutes ago a post was created?

Question is asked in title. The problem is that i want my website to be used globally and because there are different timezones i would like to say how many minutes/hours/days/years ago something was posted.
Just convert everything to one time zone when you save the date.
If you're creating a site that contains user-generated content, then this is important.
So I do know that Django that there is a timesince filter, timesince.
This can be done through the following code.
{{ post.timestamp | timesince }}
You can make use of pytz module for accurate and cross platform timezone calculations. Take a look at this.
https://pypi.org/project/pytz/
Here is what you can do is, at the time of the creation of user's post, use the above module and retrieve the localtime with the timezone details and convert it to UTC and store the same, to retrieve it all you need to do is "depending on the region add or sub the respective number as mentioned in the timezone map.
https://upload.wikimedia.org/wikipedia/commons/8/88/World_Time_Zones_Map.png

Django Timezone Awareness - Data to be stored in UTC

This is my first time developing a timezone aware web app. I'm using Django 1.11.7. I have looked through many posts regarding timezones and honestly, I'm starting to feel like I just don't understand the concept of timezones... 0_o
I'm making a booking app with start_time and end_time for each reservation.
I expect the user to be able to enter dates and times as he experiences them in his timezone. On the other hand, I want these dates and times stored in a postgresql database in UTC format.
If I was choosing to reserve, for example, between 12am and 2am (today), the result in the database should show between 5pm and 7pm (today).
Right?
Django Internationalization settings:
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_TZ = True
USE_L10N = True
USE_I18N = True
During database creation:
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
end_time TIMESTAMP WITH TIME ZONE NOT NULL
Using Django's built in admin page feature, I enter the following information:
But when I look up the results in the database, here's what I get:
2017-12-05 19:00:00-05 | 2017-12-05 20:59:59-05
The stored result changed in the opposite direction of what I was expecting. I was expecting:
2017-12-06 05:00:00+05 | 2017-12-06 07:00:00+05
If my expectations are wrong and everything is working fine, I would be grateful if you could explain to me how I should interpret the timezone when I read it.
Otherwise, if my expectations where right, I would appreciate any advice.
Thank you.
The basic issue here is that you've misunderstood what the admin is doing for you ("I expect the user to be able to enter dates and times as he experiences them in his timezone"). In fact, the admin interprets all datetimes in the server time zone (UTC in your case).
Note: You are 5 hours behind server time
actually means:
Warning: The values you enter here will be interpreted in the server timezone, which is 5 hours ahead of you.
(I agree with you that this wording is ambiguous. You might want to file a ticket about improving it.)
For background on this issue, see this ticket. The root of the problem is that there's no way to get the user's timezone in the browser. What you can do is compare the current time in the browser to the current time on the server and post the warning above if they are different.
If you want to interpret datetimes in the user's timezone, there's no alternative but to ask the user to indicate their timezone explicitly, record it somewhere, and then activate() it to make it the current timezone. This is the technique described in the documentation. I believe that there are third-party packages that provide timezone selection widgets based on the list of timezones in pytz.
You're also misreading the time display. I think what you were expecting is 2017-12-06 05:00:00+00. Instead the result is 2017-12-06 00:00:00+00 in UTC or, equivalently, 2017-12-05 19:00:00-05 in Ottawa time, which is what you reported.
https://www.google.co.jp/search?dcr=0&q=ottawa+timezone&spell=1&sa=X&ved=0ahUKEwjX0LnA5_bXAhVFjJQKHXCdBDYQvwUIJigA&biw=1394&bih=803
Ottawa timezone is -5.
You can manually test in a template that's the timezones are properly registered by showing the time you've registered in different timezones with this filter:
https://docs.djangoproject.com/en/1.11/topics/i18n/timezones/#std:templatefilter-timezone
I had a very similar issue with Hotel bookings. This answer put me on the right track.
https://stackoverflow.com/a/18307581/4660189
The key here is in what you said:
I expect the user to be able to enter dates and times as he experiences them in his timezone.
"his timezone" would need to be handled via a middleware. So that each user can be assigned a timezone, and thus the system would handle all times/dates for this user accordingly.
This should get you going. Happy coding and welcome to the mind bending reality of timezones.

Why python datetime replace timezone is returning different timezone?

I am working on Python/Django project. I am trying to let user select date and time using jQuery plugin datetimepicker add-on. So when I select now option and post data django is saving the time in UTC offset. This is what is saved in database, 2017-03-30 13:38:00+00:00. I need to convert this time from user's timezone and save it in system as utc. Because later I will have script running which will look for data in database which is less than the utc time.
Actually the script is to let user post information on website and let them chose the publish date and time. So for example, If use posted an article which will be published on April 2nd 1pm Chicago time, I don't want other users to read the article before this time. So people around the world can read article as soon as it is April 2nd and 1PM in Chicago. So how can I make this functionality work?
My solution was to get the time and remove it's timezone information using replace(tzinfo=pytz.timezone('America/Chicago')) and when I print the time, I am getting 2017-03-30 13:38:00-05:51. The actual offset right now is -05:00. Can anyone help me to and tell me what I am doing wrong?
What I am doing for form is that I have publish_date object in my model and I am using django forms to create form. I have added class as an attribute in it and using jquery plugin,
$('.datepicker').datetimepicker({
timeFormat: 'HH:mm',
stepHour: 1,
stepMinute: 1,
});
So when User submits the form, on post method this my code,
form = PublishForm(request.POST)
if form.is_valid():
f = form.save(commit=False)
f.created_by_user_id = request.user.id
f.save()
and than to get the date all I am doing is f.publish_date and the other options I have used lice replace and localize are pretty standard.
Thanks
As noted in the comments, you appear to have two problems. First is that the datetimepicker is saving a date and time with a UTC timezone offset, when it should be applying a different timezone or leaving off the timezone offset entirely. Second is that pytz is using the wrong offset.
I don't know how to fix the first problem, but I can help you with the second. You need to use pytz's localize function. This only works when the datetime doesn't have a timezone attached, but since you know the timezone is incorrect anyway you can delete it first.
tz = pytz.timezone('America/Chicago')
dt = tz.localize(dt.replace(tzinfo=None))
The naming of the datetime replace(tzinfo = ...) function is unfortunate. In fact, its behaviour is random. Do not use this!
Mark's answer is the way to go. Use localize.

Django model TimeField views.py cannot select hour or minute

When using a TimeField in a Django model I wish to be able to perform a query in a view, using the hour and minute elements of the TimeField separately.
However, when I do so, if I run the view I receive an error message that the __hour (or __minute) does not exist (see code below):
scheduleItems = DEVICESCHEDULE.objects.filter(time__hour = nowHour)
If I change the model to use a DateTimeField rather than a TimeField, I am able to use the __hour and __minute options.
I would prefer to keep the field type as a TimeField, as I only need a time to be input and inputting a date (even if it is ignored) is confusing to the user.
Thanks in advance!
Seem like the date/time related lookups only works with dates and datetimes, not the time fields, although seems like it would be a nice feature to have as well.
Have you thought about raising a ticket maybe?
Maybe you can consider this as a replacement:
DEVICESCHEDULE.objects.extra(where=['SUBSTR(time, 1, 2)=%0.2d'], params=[nowHour])
DEVICESCHEDULE.objects.extra(where=['SUBSTR(time, 4, 2)=%0.2d'], params=[nowMinute])

django, datetime and timezones

I am using: datetime.now() to get the current time in an Event app that lets you create an event that has an end date, then all of the events are displayed in a calendar and if an event is passed due it is displayed in red.
My issue is that I have some users in different timezones than me saying that the events are ending at the wrong time. They should end at midnight on the day they are due.
I have the timezone setup in my django settings.py. When I use: datetime.now() is that going off of the users local timezone or is it going off of what timezone I have setup in django?
What I want is to find midnight for the users current timezone, so if my method above is wrong, how do I go about doing that?
Thanks
You will need your users to specify their timezone in their user profile. This can then be used to calculate local times correctly.
Check out Relativity of time – shortcomings in Python datetime, and workaround for some good information (and concrete examples).
UPDATE: From Django 1.4 it comes up with timezone support. Check it out.
I worked on a library to work with user timezones transparently. You should just use a Field and some timezone utils and you should get everything converted to the user timezone everytime you do a request or a query.
The library is named django-timezones, and is a modification of the one that Brosner first made.
Give it a try to see if it works for you.
Try storing the UTC Datetime instead then make the necessary adjustments based on the user's timezone:
import datetime
def getUtcNow():
return datetime.datetime(*time.gmtime()[:6])

Categories