Python3 date and time formatting - python

I'm using an API that sends a date in a wierd format "YYYY-MM-DDTHH:MM:SSZ".
So the date comes out as 2018-04-27T23:59:18Z, I have never seen a date and time formatted like this. Its a string and I would like to format it as MM-DD-YYYY HH:MM:SS. I can't even wrap my head around removing the T and Z. Any help would be appreciated! Thanks in advance!

Create datetime.datetime object from your string via datetime.strptime, then turn it back into a string with its strftime method.
>>> from datetime import datetime
>>> s = "2018-04-27T23:59:18Z"
>>> datetime.strptime(s, '%Y-%m-%dT%XZ').strftime('%m-%d-%Y %X')
>>> '04-27-2018 23:59:18'
strptime and strftime behavior
(Depending on you locale you might have to use %H, %M and %S instead of %X.)

That looks like the ISO 8601 time format.
For reasons that I really don't understand, there's no standard library function that parses ISO 8601 correctly. The dateutil package that you can find on PyPI will parse it for you though.

Use this pattern:
import datetime
d = '2018-04-27T23:59:18Z'
myDate = datetime.datetime.strptime(d, '%Y-%m-%dT%H:%M:%SZ')
# datetime.datetime(2018, 4, 27, 23, 59, 18)
Then to get a datetime string use strftime:
myDate_str = myDate.strftime('%Y-%m-%d %H:%M:%S')
# '2018-04-27 23:59:18'

Related

Python - convert string type to datetime type

I have a two variables that i want to compare. When printed, this is what they look like:
2020-05-20 13:01:30
2020-05-20 14:49:03
However, one is a string type, and the other a datetime type.
If I want to convert the string one into date type so I can compare them, is the only way to use strptime? Because this seems a little redundant to me, since the string already has the exact format I want it to have. Basically, is there a function that does the same as strptime, but without re-formating it? As you can imagine, googling this problem is impossible, as all I'm getting is people trying to format any kind of string into datetime, so all the answers are just pointing at strptime.
If you work with Python 3.7+, for ISO 8601 compatible strings, use datetime.fromisoformat() as this is considerably more efficient than strptime or dateutil's parser. Ex:
from datetime import datetime
dtobj = datetime.fromisoformat('2020-05-20 13:01:30')
print(repr(dtobj))
# datetime.datetime(2020, 5, 20, 13, 1, 30)
You can find a benchmark vs. strptime etc. here or here.
You can use parser provided by dateutil
from dateutil import parser
date_object = parser.parse("2020-05-20 13:01:30")
print(repr(date_object))
# datetime.datetime(2020, 5, 20, 13, 1, 30)
print(type(date_object))
# <class 'datetime.datetime'>
print(date_object)
# 2020-05-20 13:01:30
From the docs:
This module offers a generic date/time string parser which is able to parse most known formats to represent a date and/or time.
Documentation: https://dateutil.readthedocs.io/en/stable/parser.html

Serializing and deserializing datetimefield type object (Django app)

In a Django app of mine, I have a datetime object that I need to serialize and then deserialize. When I try it, I get the error:
ValueError: time data '2016-05-31T18:57:17.280939+00:00' does not
match format '%Y-%m-%d %H:%M:%S.%f'
My code to serialize and deserialize is:
timestring = time.isoformat() #where timestring is DateTimeField type object, instantiated in Django
timeobj = datetime.strptime(timestring, "%Y-%m-%d %H:%M:%S.%f")
What am I doing wrong and how do I get over the hump? Your guidance is greatly appreciated.
timeobj = datetime.strptime(timestring, "%Y-%m-%dT%H:%M:%S.%f+00:00")
(adds a T as the date/time separator, and hard codes the utc offset string part)
will resolve your problem ... and I guess its reasonably safe ... personally I always go with
from dateutil.parser import parse as date_parse
dt_obj = date_parse(timestring)
that pretty much always works and does not require me to hardcode the datestring you may need pip install python-dateutil
So there are two things going on here:
Your format string has a space between %d and %H but the test string has a T.
Python's datetime.datetime.strptime does not work with timezone names/offsets. From the relevant docs:
classmethod datetime.strptime(date_string, format)
Return a datetime corresponding to date_string, parsed according to
format. This is equivalent to datetime(*(time.strptime(date_string,
format)[0:6])).
So you can extract year, month, day, hour, minute, second and microsecond but the %z directive is for strftime only, not strptime.
So, in summary:
In [18]: datetime.strptime(datetime.today().isoformat(), '%Y-%m-%dT%H:%M:%S.%f')
Out[18]: datetime.datetime(2016, 5, 31, 15, 20, 20, 581261)
but
In [22]: datetime.strptime(datetime.today().isoformat()+'+00:00', '%Y-%m-%dT%H:%M:%S.%f%z')
---------------------------------------------------------------------------
ValueError: 'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S.%f%z'

Converting ISO 8601 date format with timezone in python

I am attempting to convert the following date (2012-12-25T08:52:00-05:00) to a datetime object in python. However, I cannot figure out what the -05:00 part of the date is referencing. I am simply trying to perform the following:
datetime.datetime.strptime('2012-12-25T08:52:00-05:00','%Y-%m-%dT%H:%M:%S')
But this comes up with an expected 'ValueError: unconverted data remains'. I'm just trying to figure out what the last part of the date is used for so that I can convert that string to a proper datetime object in python.
Happy Holidays!
Your date seems to be in the ISO 8601 format, I don't think datetime handles the timezone information at the end of the string format.
You can use pip install python-dateutil, its parser can return a datetime object :
import dateutil.parser
datestr = '2012-12-25T08:52:00-05:00'
dateutil.parser.parse(datestr)
>>> datetime.datetime(2012, 12, 25, 8, 52, tzinfo=tzoffset(None, -18000))
The -05:00 indicates the timezone offset from UTC, i.e. %z would be the correct strptime argument to parse it.
If the time is UTC the offset might be indicated using Z, e.g. 2012-12-25T08:52:00Z. Not sure if %z would actually accept this...

python: how to handle timestamps (ISO8601)

I have to deal in python with strings representing iso8601 timestamps.
My timestamps string are therefore in the following form:
timestamp = "2011-08-18T10:29:47+03:00"
Currently I'm converting them in python using:
timestamp = timestamp[:-6]
timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S")
But in this way I lose all the information about the time zone.
I have seen many examples here on s-o about timestamps and python, unfortunately no one was preserving the timezone as well, or just recover the time zone delay using:
delay = timestamp[-6:]
I have also tried:
timestamp = "2011-08-18T10:29:47+03:00"
timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S%z")
but it returned
ValueError: 'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S%z'
Can you give some insight?
The python iso8601 module is built with a wonderful parse_date method that can handle timezone info :
>>> import iso8601
>>> iso8601.parse_date("2007-01-25T12:00:00Z")
datetime.datetime(2007, 1, 25, 12, 0, tzinfo=<iso8601.iso8601.Utc ...>)
>>> iso8601.parse_date("2011-08-18T10:29:47+03:00")
datetime.datetime(2011, 8, 18, 10, 29, 47, tzinfo=<FixedOffset '+03:00'>)
If you want to convert it in another timezone, use the astimezone(tz) method
If you need to get the UTC datetime you can use the utctimetuple() method.
You'll need to add an external module that provides timezone support; the pytz module provides you with the necessary timezone database.
You'll either need to parse the timezone by hand to construct a pytz timezone, or use a package like zc.iso8601 or iso8601 to do the parsing for you:
from zc.iso8601.parse import datetimetz
datetimetz(timestamp)

how to convert and subtract dates, times in python

I have the following date/time:
2011-09-27 13:42:16
I need to convert it to:
9/27/2011 13:42:16
I also need to be able to subtract one date from another and get the result in HH:MM:SS format. I have tried to use the dateutil.parser.parse function, and it parses the date fine but sadly it doesn't seem to get the time correctly. I also tried to use another method I found on stackoverflow that uses "time", but I get an error that time is not defined.
You can use datetime's strptime function:
from datetime import datetime
date = '2011-09-27 13:42:16'
result = datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
You were lucky, as I had that above line written for a project of mine.
To print it back out, try strftime:
print result.strftime('%m/%d/%Y %H:%M:%S')
Use python-dateutil:
import dateutil.parser as dateparser
mydate = dateparser.parse("2011-09-27 13:42:16",fuzzy=True)
print(mydate.strftime('%m/%d/%Y T%H:%M:%S'))
http://docs.python.org/library/datetime.html#datetime.datetime.strptime
and
http://docs.python.org/library/datetime.html#datetime.datetime.strftime
(And the rest of the datetime module.)

Categories