0

I have a model

models.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

from django.utils import timezone

class Article(models.Model):
     sort = models.IntegerField(blank=True)
     pub_date = models.DateTimeField(default=timezone.now)
     title = models.CharField(max_length=30, blank=True)

common.py

 TIME_ZONE = 'America/New_York'
 USE_TZ = True

local.py

 from .common import *

 CELERY_BROKER_URL = env('REDIS_URL')
 CELERY_RESULT_BACKEND = env('REDIS_URL')

 CELERY_ACCEPT_CONTENT = ['application/json']
 CELERY_TASK_SERIALIZER = 'json'
 CELERY_RESULT_SERIALIZER = 'json'
 CELERY_TIMEZONE = TIME_ZONE

production.py

 from .common import *

 CELERY_BROKER_URL = env('REDIS_URL')
 CELERY_RESULT_BACKEND = env('REDIS_URL')

 CELERY_ACCEPT_CONTENT = ['application/json']
 CELERY_TASK_SERIALIZER = 'json'
 CELERY_RESULT_SERIALIZER = 'json'
 CELERY_TIMEZONE = TIME_ZONE

tasks.py

 from __future__ import absolute_import, unicode_literals
 from celery.decorators import task

 from .models import Article

 import urllib2
 import json
 import datetime

 @task(name="articles")
 def update_article():

 # .... more code
 article = Article.objects.get(id=1)
       if article != None:
            article.pub_date = datetime.datetime.now()
            article.title = "Hello"
            article.save()

When I run in the django shell

 import datetime
 pub_date = datetime.datetime.now()
 print pub_date

The pub_date is EST / 'America/New_York' timezone - correct.

I have a celery to update the Article, I wrote a simple code

article.pub_date = datetime.datetime.now()

When the pub_date is updated, in the DB the date is in UTC not America/New_York / EST timezone, even the shell is showing me correct ETC, but running it with the task, in the postgres DB it is UTC

11
  • What's your celery timezone set to? Commented May 2, 2017 at 22:33
  • I found it, so my CELERY_TIMEZONE = TIME_ZONE and my TIME_ZONE = 'America/New_York' in settings Commented May 2, 2017 at 22:34
  • stackoverflow.com/questions/22786748/… docs.celeryproject.org/en/latest/userguide/periodic-tasks.html Maybe you need to reset your database scheduler? Commented May 2, 2017 at 22:39
  • I have restarted all services and I set it to be CELERY_ACCEPT_CONTENT = ['application/json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_TIMEZONE = 'America/New_York' Commented May 2, 2017 at 22:44
  • I have updated settings.py with more settings, still not working, still UTC Commented May 2, 2017 at 22:46

1 Answer 1

2

Following the comments =)

Always use django.utils.timezone.now() instead of datetime.datetime.now().

Please note that directly in Postgres you will see these datetime columns in UTC + TZ offset format, and Django will translate the datetime to the desired timezone (either server TZ or the client TZ if the time is rendered in a view).

Now, if in your local Django shell you see the correct datetime but not in Heroku, it may be that Heroku the column does not hold TZ information (althought I find this hard to belive). I haven't had used Heroku but the Django migrations will take care of a timestamp with time zone column. In postgres you can check the type of a column via psql (or dbshell):

\d <your table>

                   Table article
    Column     |           Type            |        Modifiers
---------------+---------------------------+---------------------
 id            | integer                   | ...
 pub_date      | timestamp with time zone  | ...
 ....          | ...                       | ...

Hope this helps.

Sign up to request clarification or add additional context in comments.

11 Comments

Yes in heroku it shows me pub_date | timestamp with time zone | not null, example 2017-05-03 14:53:00.361049+00 - but this time is 4 hours ahead that I needed to be, local shows 10:53 and heroku 14:53, that is what is strange to me, postgres on local should have same features like heroku postgres so not sure why it works on local and not heroku.
It is OK if you see 14:53:00.361049+00, since NY is UTC-4. Where are you seeing 14:53? in Heroku? In postgres? in shell? dbshell? in a model? Somewhere the datetime is show naive instead of tz aware.
I am connected to Postgres to local via CLI and doing a simple select * on the table to see all the data, on the local I see 10:53:00.... and on heroku I see with heroku pg:psql select * - 14:53:00.361049+00 - same environment, same DB why different times?
a naive datetime of 10:53:00 is the same that a tz aware 14:53:00.361049+00. Note that the rows you saved with article.pub_date = datetime.datetime.now() will hold a different time zone that the ones you saved with article.pub_date = timezone.now()
No I am not doing datetime.datetime.now() on any of them I have local and heroku article.pub_date = timezone.now() both, local shows 2017-05-03 10:45:00.836694-04 and heroku 14:55:00.361049+00 - same code, different result
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.