In my project I have object with datetime field
startdate = models.DateTimeField(default="1999-01-01 00:00:00")
I need create new object and send datetime = "2015-12-9"
calen = models.calendar()
calen.startdate = datetime.strptime(request.POST["date"], "%Y-%m-%d")
calen.save()
In this object I see
calen.startdate => datetime.datetime(2015, 12, 9, 0, 0)
all right.
in pqAdmin3, postgres DB this field = "2015-12-09 08:00:00+02"
wrong 8 hours!!!! ->6+2
When I select this object calen.startdate
datetime.datetime(2015, 12, 9, 6, 0, tzinfo=<UTC>)
extra 6:00!!!!
I tried to make a complete date, now(),but all the same is extra 6 hours
Do not use django.utils.datetime for database fields. Use timezone instead.
from django.utils import timezone
now = timezone.now()
Related
My django project is correctly enable the timezone in settings.
However, the datetime field of Django ORM object is a naive datetime object as shown in Block 3.
The expected result should be same as the output of Block 4 without any manually conversion.
In [1]: from django.conf import settings
...: settings.USE_TZ, settings.TIME_ZONE
Out[1]: (True, 'Asia/Hong_Kong')
In [2]: from qms.models import Quota
In [3]: q = Quota.objects.get(pk=1)
...: q.create_date, q.write_date
Out[3]:
(datetime.datetime(2021, 3, 10, 17, 37, 42, 489818),
datetime.datetime(2021, 3, 10, 17, 37, 42, 489818))
In [4]: from django.utils import timezone
...: timezone.make_aware(q.create_date,timezone.utc), \
...: timezone.make_aware(q.write_date, timezone.utc)
Out[4]:
(datetime.datetime(2021, 3, 10, 17, 37, 42, 489818, tzinfo=<UTC>),
datetime.datetime(2021, 3, 10, 17, 37, 42, 489818, tzinfo=<UTC>))
Record in SQL
Column
value
id
1
create_date
2021-03-10 17:37:42.489818+00
write_date
2021-03-10 17:37:42.489818+00
name
email
Django Model Definition
class Quota(models.models):
name = models.CharField(max_length=255)
create_date = models.DateTimeField(auto_now_add=True)
write_date = models.DateTimeField(auto_now=True)
The PostgreSQL database schema and settings, Table "public.qms_quota"
Column
Type
Modifiers
id
integer
not null default nextval('qms_quota_id_seq'::regclass)
create_date
timestamp with time zone
not null
write_date
timestamp with time zone
not null
name
character varying(255)
not null
SHOW TIMEZONE;
TimeZone
----------
UTC
Questions
How can I get the timezone-aware datetime object directly without any conversion?
Or the manual conversion is expected ?
The root-cause is a bug from a connection pool library django_postgrespool2==2.0.1.
When you use the your connection engine with "django_postgrespool2", it will NOT correctly handle the timezone settings. Releated Issue
TLDR: use engine django.db.backends.postgresql
You can use django.utils.timezone.localtime to convert the datetime received from the DB to localtime:
from django.utils.timezone import localtime
q = Quota.objects.get(pk=1)
print(localtime(q.create_date), localtime(q.write_date))
I have an endpoint that accepts POST method. The POST body contains a DateTime field of format - "%Y-%m-%d %H:%MZ". I need to validate if that datetime is less than current Datetime in UTC. I'm using Marshmallow to validate the request body.
run_datetime = fields.DateTime(format="%Y-%m-%d %H:%MZ")
Are there any inbuilt validators for this case to validate DateTime field. Or should I be writing a custom function for this to compare the run_datetime with today's UTC's datetime.
There is no built-in validator that can solve your particular issue at hand, take a look at the available validators here.
Although, defining your own validator is trivially easy, for your particular case: fields.Datetime will accept an argument named validate which can take a function that returns a bool. For example, I quickly defined a lambda here to validate if the datetime is more recent than "now":
from datetime import datetime
from marshmallow import Schema, fields
NOW = datetime(2020, 11, 23, 14, 23, 0, 579974)
class User(Schema):
id = fields.Integer(required=True)
name = fields.String(required=True)
# Define an arbitrary datetime here like NOW or just use datetime.now()
date_created = fields.DateTime(required=True, validate=lambda x: x > NOW)
# This will succeed
User().load(dict(
id=10,
name="Test",
# Note that this date is more recent than previously defined NOW
date_created="2020-11-23T14:24:40.224965",
))
#{'date_created': datetime.datetime(2020, 11, 23, 14, 24, 40, 224965),
# 'id': 10,
# 'name': 'Test'}
# While this will fail
User().load(dict(
id=10,
name="Test",
# Here the date is one month behind than NOW
date_created="2020-10-23T14:24:40.224965",
))
# ValidationError: {'date_created': ['Invalid value.']}
In Django models, How to increment the date field using timezone.now?
working:
end_date = models.DateTimeField(default=timezone.now() + timezone.timedelta(days=365))
Not Working
end_date = models.DateTimeField(default=timezone.now + timezone.timedelta(days=365))
I think timezone.now is a function which runs every time when the object is created. so that error occurs.
You could use a function:
def f():
return timezone.now() + timezone.timedelta(days=365)
...
end_date = models.DateTimeField(default=f)
The current time in that timezone is the added with the timedelta anytime a new end_date is created by default:
>>> from django.utils import timezone
>>> from datetime import timedelta
>>> def f():
... return timezone.now() + timezone.timedelta(days=365)
...
>>> f()
datetime.datetime(2018, 6, 25, 19, 42, 49, 761389, tzinfo=<UTC>)
>>> f()
datetime.datetime(2018, 6, 25, 19, 43, 2, 953158, tzinfo=<UTC>)
Sample run with Django:
In [1]: from testapp import models
In [2]: models.Test.objects.create().date_added
Out[2]: datetime.datetime(2018, 6, 25, 20, 5, 28, 316214, tzinfo=<UTC>)
In [3]: models.Test.objects.create().date_added
Out[3]: datetime.datetime(2018, 6, 25, 20, 5, 33, 114624, tzinfo=<UTC>)
A good approach would be to use the post_save signal. Import it with
from django.db.models.signals import post_save and then create a handler function like this:
def handler_function(sender, instance, created, **kwargs):
if sender == YourModel and created:
instance.end_date = timezone.now() + timezone.timedelta(days=365)
instance.save()
post_save.connect(handler_function, sender=YourModel)
This will work for sure, I hope this also applies to your case. Let me know if you need further help!
Trying to pass a datetime object via pymongo, as I can't use a hardcoded "datetime" as shown in all the pymongo documentation (eg: "2015-12-24T11:59:00Z").
Simply want to delete collections over 7 days old. Why is it erroring on "an integer is required" when I'm passing it a UTC date via 'newDate'?
from datetime import datetime, timedelta
from pymongo import MongoClient
newDate = datetime.utcnow() - timedelta(days=7)
result = db.collection.remove({"receivedDateUtc" : { '$lte' : datetime(newDate) }} )
The reason is that newDate is already a datetime object.
result = db.collection.remove({'receivedDateUtc' : { '$lte' : newDate }} )
Demo:
In [67]: newDate = datetime.utcnow() - timedelta(days=7)
In [68]: newDate
Out[68]: datetime.datetime(2015, 12, 29, 22, 2, 41, 391369)
i create a website using django .and now i want show the number of users registered today,
so i write this code
from django.utils import timezone
from django.contrib.auth import get_user_model
um=get_user_model()
now=timezone.now()
todayusers=um.objects.filter(date_joined__day=now.day,date_joined__month=now.month,date_joined__year=now.year).count()
today it is 4th july 2014 ,and i find today mywebsite get two users registered
but it show todayusers =0
i do not knwo why ?
so i change the code to make it simple
todayusers=um.objects.filter(date_joined__day=4).count()
it show todayusers=0
and i change it to
todayusers=um.objects.filter(date_joined__day=3).count()
ok ,this time ,it show todayusers=2
i find one of the user ,its user id is 13,so i get that user
u13=um.objects.get(ud=13)
now i check its date_joined ,this datetime filed
u13.date_joined.day=4
that means ,it should be 4th july ,why when i query it in django ,it can not find
my django TIME_ZONE = 'Asia/Shanghai'
any one can help me
See if this works
todayusers=um.objects.filter(date__year='2014',
date__month='07', date__day='04').count()
OR
start_date = datetime.date(2014, 7, 4)
end_date = datetime.date(2014, 7, 4)
todayusers = um.objects.filter(date__range=(start_date, end_date)).count()
OR
todayusers = um.objects.filter(date__gte=datetime.datetime.today()).count()
OR
from pytz import timezone
from datetime import datetime
asia_sh = timezone("Asia/Shanghai")
startdate = datetime(2014, 07, 04, 0, 0, 0, tzinfo=asia_sh)
enddate = datetime(2014, 07, 04, 23, 59, 59, tzinfo=aisa_sh)
todayusers = um.objects.filter(date__range=(start_date, end_date)).count()