I have a model with a DateTimeField:
deadline = models.DateTimeField(verbose_name="Valid unitl", null=True, blank=True)
Users should be allowed to input date, time and timezone info in the field. This is my desired format:
2012-12-31 23:30 +0430
I expect the time will get converted to UTC before storing to db. So I tried using a model form for that, but it throws Enter a valid date/time. validation error on that DateTimeField if I enter the value above.
This is in settings.py:
DATE_INPUT_FORMATS = ('%Y-%m-%d %H:%M %Z', )
What am I missing?
Edit:
As per Видул Петров's suggestion, tried to use a form field:
deadline2 = forms.DateTimeField(input_formats=['%Y-%m-%d %H:%M %Z',],
Got the same effect: Enter a valid date/time.
Edit 2
It appears that datetime can't handle the "%z" parameter. This throws a ValueError:
datetime.datetime.strptime(value, format)
So I tested it in console:
>>> import datetime
>>> datetime.datetime.strptime('2012-12-30 19:00 +0100', "%Y-%m-%d %H:%M %z")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 317, in _strptime
(bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M %z'
Also tried pytz:
>>> import pytz
>>> pytz.datetime.datetime.strptime('2012-12-30 19:00 +0100', "%Y-%m-%d %H:%M %z")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 317, in _strptime
(bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M %z'
I really feel this should work. Did I miss some part of the docs that says otherwise?
When you set USE_TZ = True in your settings, Django stores date and time information in UTC in the database otherwise it will store naive date time (date time without timezone).
In most cases using Django's time zones support is very convenient because input and output datetime will be automatically translate by Django.
But if you really need timezone input from your user, you will need to set USE_TZ = False then use DateTimeField which is naive datetime along with CharField to store timezone information in your models.py.
ref: https://docs.djangoproject.com/en/2.1/topics/i18n/timezones/
Related
I use django simple-history to get history on my models
I then search the history results by date but I get the error below. How can I format the date?
RuntimeWarning: DateTimeField HistoricalIssue.history_date received a naive datetime (2022-04-13 10:34:32) while time zone support is active.
warnings.warn("DateTimeField %s received a naive datetime (%s)"
def SearchByDate(request):
date_search = request.POST['date-search']
if date_search:
admin_hist_search_results = Issue.history.filter(history_date=date_search)
First, keep in mind that this is not an error, but "only" a warning. It mentions that the incoming timestamp (which you store in variable date_search) does not have timezone information, while you compare it with a timestamp field (history_date on model Issue) that does have timezone information. This could potentially lead to issues.
If you know the timezone coming in from the request, you can add that information to the timestamp, for example:
import pytz
date_as_string = request.POST['date-search']
parsed_date = datetime.strptime(date_as_string, '%Y-%m-%d')
amsterdam_timezone = pytz.timezone('Europe/Amsterdam')
date_search = amsterdam_timezone.localize(parsed_date)
I went through datetime python page, and other related pages, but unable to get this thing to work.
I have the following string that I want to convert to python date object.
May 29, 2018 10:40:06 CDT AM:
I use the following to match, but python2.7 is giving me doesnt match error.
datetime_object = datetime.strptime(line, '%B %d, %Y %I:%M:%S %Z %p:')
It seems as though CDT is not a valid timezone name as it works with GMT.
>>> str(datetime.strptime('May 29, 2018 10:40:06 GMT AM:', '%B %d, %Y %I:%M:%S %Z %p:'))
'2018-05-29 10:40:06'
from dateutil import parser
print (parser.parse("May 29 13:40:06 CDT 2018"))
Output
2018-05-29 13:40:06
Reference: python-dateutil
Building a Twitter scraper I'm stuck at converting tweet creation datetime (I get it as local timezone) into UTC.
Creation date from data-original-title -attribute's format is 12:17 AM - 8 Apr 2018. How can I convert it to UTC?
First of all you need to convert your string into a python datetime format then i recommend you using pytz module to change the timezone used into UTC timezone like this example:
import datetime
import pytz
a = '12:17 AM - 8 Apr 2018'
final = datetime.datetime.strptime(a, '%I:%M %p - %d %b %Y').replace(tzinfo=pytz.UTC)
print(final)
# 2018-04-08 00:17:00+00:00
Also, if you want to check the converted time into a string representation, you can do :
str_time = final.strftime('%d/%m/%Y %H:%M:%S')
print(str_time)
# '08/04/2018 00:17:00'
Ps: If you don't have pytz module installed in your PC, you can install it by :
sudo pip install pytz
Try Below:
import pandas as pd
datestr = '12:17 AM - 8 Apr 2018'
utcDate = pd.to_datetime(datestr, format='%H:%M %p - %d %b %Y', utc=True)
I came across an interesting situation when using this class:
class Company(models.Model):
date = models.DateField()
time = models.TimeField()
c = Company(date=datetime.datetime.now(), time=datetime.datetime.now())
Django decides to use DATETIME_INPUT_FORMATS defined within the formats.py file.
Which makes sense, because I am passing in a datetime.now() to both fields.
I think I could make Django to use DATE_INPUT_FORMATS and TIME_INPUT_FORMATS respectively, if I passed in only the current date and current time in.
Something like this:
c = Company(date=datetime.date.now(), time=datetime.time.now())
But this obviously throws an exception as now doesn't exist like that. Is there a different way to achieve this?
For the date, you can use datetime.date.today() or datetime.datetime.now().date().
For the time, you can use datetime.datetime.now().time().
However, why have separate fields for these in the first place? Why not use a single DateTimeField?
You can always define helper functions on the model that return the .date() or .time() later if you only want one or the other.
import datetime
datetime.datetime.now().strftime ("%Y%m%d")
20151015
For the time
from time import gmtime, strftime
showtime = strftime("%Y-%m-%d %H:%M:%S", gmtime())
print showtime
2015-10-15 07:49:18
import datetime
datetime.date.today() # Returns 2018-01-15
datetime.datetime.now() # Returns 2018-01-15 09:00
import datetime
Current Date and time
print(datetime.datetime.now())
#2019-09-08 09:12:12.473393
Current date only
print(datetime.date.today())
#2019-09-08
Current year only
print(datetime.date.today().year)
#2019
Current month only
print(datetime.date.today().month)
#9
Current day only
print(datetime.date.today().day)
#8
A related info, to the question...
In django, use timezone.now() for the datetime field, as django supports timezone, it just returns datetime based on the USE TZ settings, or simply timezone 'aware' datetime objects
For a reference, I've got TIME_ZONE = 'Asia/Kolkata' and USE_TZ = True,
from django.utils import timezone
import datetime
print(timezone.now()) # The UTC time
print(timezone.localtime()) # timezone specified time,
print(datetime.datetime.now()) # default local time
# output
2020-12-11 09:13:32.430605+00:00
2020-12-11 14:43:32.430605+05:30 # IST is UTC+5:30
2020-12-11 14:43:32.510659
refer timezone settings and Internationalization and localization in django docs for more details.
Another way to get datetime UTC with milliseconds.
from datetime import datetime
datetime.utcnow().isoformat(sep='T', timespec='milliseconds') + 'Z'
2020-10-29T14:46:37.655Z
I'm trying to get a date for an event from a user.
The input is just a simple html text input.
My main problem is that I don't know how to parse the date.
If I try to pass the raw string, I get a TypeError, as expected.
Does Django have any date-parsing modules?
If you are using django.forms look at DateField.input_formats. This argument allows to define several date formats. DateField tries to parse raw data according to those formats in order.
Django doesn't, so to speak, by Python does. It seems I'm wrong here, as uptimebox's answer shows.
Say you're parsing this string: 'Wed Apr 21 19:29:07 +0000 2010' (This is from Twitter's JSON API)
You'd parse it into a datetime object like this:
import datetime
JSON_time = 'Wed Apr 21 19:29:07 +0000 2010'
my_time = datetime.datetime.strptime(JSON_time, '%a %b %d %H:%M:%S +0000 %Y')
print type(my_time)
You'd get this, confirming it is a datetime object:
<type 'datetime.datetime'>
More information on strptime() can be found here.
(In 2017), you could now use django.utils.dateparse
The DateField can be used outside of Django forms.
Example, when used {{ value|date:"SHORT_DATE_FORMAT" }} in template:
from django.forms import DateField
from django.utils import formats
# need '%d.%m.%Y' instead of 'd.m.Y' from get_format()
dformat = ('.' + formats.get_format("SHORT_DATE_FORMAT", lang=request.LANGUAGE_CODE)).replace('.', '.%').replace('-', '-%').replace('/', '/%')[1:]
dfield = DateField(input_formats=(dformat,))
<date> = dfield.to_python(<string>)