Monday, August 31, 2015

Re: TIME ZONE DJANGO SAVE DATETIMEFIELD

On Mon, Aug 31, 2015 at 5:37 PM, Serena <serenity.luna@gmail.com> wrote:
> I understand what you say, when I started working with Django I thought
> exactly the same, it is more convenient that the date is saved with a time
> zone and then the conversions are made, and also knew that the gap was
> precisely because those 4:30 in my timezone, but the problem is not to show
> the data to the user, but as I make my queries so that the filtered data is
> correct, since my dates are obvious questions, I'll put my concern examples:
>
> The date does not place the customer, we do not control them. Each time an
> invoice is added, the date placed in my controller using:
> >> factura = Factura()
> >> factura.fecha = timezone.now ()
> >> factura.save ()
>
> For example I consult my templates from sales day, and was shown to the
> customer in my template:
> 1. Add invoice number 6 on August 31, 2015 at 18:48
> 2. Add Invoice Number 7 on August 31, 2015 at 18:48
> 3. Add Invoice Number 8 on August 31, 2015 at 19:32
>
> But Database I remain as follows:
> 1. Invoice number 6 Date: 08/31/2015 23:18:07
> 2. Invoice number 6 Date: 08/31/2015 23:31:25
> 3. Invoice number 6 Date: 01/09/2015 00:02:17
>

This helped my understanding immensely. Thank you.

You know what is odd though, the DB entries for 2 and 3 seem to be
using a different format (MM/DD/YYYY and DD/MM/YYYY respectively). It
may be right if the data for 3 is really from January, though.

>
> So if I want to consult the invoices (today August 31, 2015):
>
> >> Factura.objects.filter (fecha__startswith = timezone.now (). Date ())
>
> only leave me the invoice number 6 and number 7 because the number 8
> corresponds to another day.


Ahh, there's the problem. You are performing a string match against
the beginning of the date string, not an actual comparison of dates
and times (ie is 04:00 later than 05:00, etc.). This is both slow, and
inaccurate, as you've experienced. Django will perform a numerical
comparison of the datetime's behind the scenes within the database,
which should yield faster and accurate results.

>
> Is there any way of making the request and that django conversion made
> directly (with some function)? or I have to do the conversion?
>
> I hope I was more explicit. And much I appreciate your time.

Django will do the hard stuff, but you need to feed it the right
information in order to do so. My understanding is that you want to
see all of the bills (class Factura) that have a date falling in
between 00:00 and 23:59 (a 24 hour period for 1 day) in your local
timezone (or more specifically, the default timezone of the server).

I'm no timezone expert, but here is how I came up with performing the query:

import datetime
from django.utils import timezone

# date today, default (server) timezone
d = timezone.localtime(timezone.now(),
timezone=timezone.get_default_timezone()).date()

# grab the date, stripping away the current time
naive_start_date = datetime.datetime(d.year, d.month, d.day)

# create a timezone aware datetime object with a time of 00:00
(beginning of the day) by only providing the date
local_start_datetime = timezone.make_aware(naive_start_date,
timezone=timezone.get_default_timezone())

# create a timedelta object of 1 day
one_day = datetime.timedelta(days=1)

# calculate 1 day in the future from the start datetime
local_end_datetime = local_start_datetime + one_day

# query, use >= for start time since we start at 00:00 and < since
we use 00:00 of next day
bills = Factura.objects.filter(fecha__gte=local_start_datetime,
fecha__lt=local_end_datetime)


Most of this is just generating a date for the right
calendar/numerical day (based on the local timezone) and creating a
datetime for midnight (morning) of that day. The rest is pretty
simple. Hopefully this also accounts for DST and other timezone
anomalies beyond my comprehension.

I would also highly recommend that you install the pytz module. Django
will use it if it is available, and will make your timezone handling
even more accurate. (See #3
https://docs.djangoproject.com/en/1.8/topics/i18n/timezones/#faq )

Hopefully you can just copy/paste that into your shell and it'll come
up with the right results. Seems to work on my local machine.
Obviously if you want a different day you'll just need to come up with
a different naive_start_date.

Well, I learned a lot answering your question, hope you do too, lol.

-James

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CA%2Be%2BciX3g_9HCBcOj2adfcszdAALQdVp72%2Bqg_ct6p0RCueeLQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment