Python - Convert string representation of date to ISO 8601 - python

In Python, how can I convert a string like this:
Thu, 16 Dec 2010 12:14:05 +0000
to ISO 8601 format, while keeping the timezone?
Please note that the orginal date is string, and the output should be string too, not datetime or something like that.
I have no problem to use third parties libraries, though.

Using dateutil:
import dateutil.parser as parser
text = 'Thu, 16 Dec 2010 12:14:05 +0000'
date = parser.parse(text)
print(date.isoformat())
# 2010-12-16T12:14:05+00:00

Python inbuilt datetime package has build in method to convert a datetime object to isoformat. Here is a example:
>>>from datetime import datetime
>>>date = datetime.strptime('Thu, 16 Dec 2010 12:14:05', '%a, %d %b %Y %H:%M:%S')
>>>date.isoformat()
output is
'2010-12-16T12:14:05'
I wrote this answer primarily for people, who work in UTC and doesn't need to worry about time-zones. You can strip off last 6 characters to get that string.
Python 2 doesn't have very good internal library support for timezones, for more details and solution you can refer to this answer on stackoverflow, which mentions usage of 3rd party libraries similar to accepted answer.

Related

Does python time.strftime process timezone options correctly (for RFC 3339)

I'm trying to get RFC3339 compatible output from python's time module, using the time.strftime() function.
With the Linux 'date' command, I can use a format string like the following: "date +%F_%T%:z"
$ date +%F_%T%:z
2017-06-29_16:13:29-07:00
When used with python time.strftime, the %:z appears to not be supported.
$ python
>>> import time
>>> print time.strftime("%F %T%:z")
2017-06-29 16:16:15%:z
Apparently, '%z' is supported, but '%:z' is not:
>>> print time.strftime("%F %T%z")
2017-05-29 16:15:35-0700
RFC3339 specifically uses the timezone offset with the embedded colon.
That would be 07:00 in my case, instead of 0700.
I believe the omission of support for the "%:z' option is due to the underlying C implementation of strftime() not supporting the versions of timezone offset formatters with colons. That is '%:z', '%::z', etc.
Is there any workaround for this (e.g. another python module, or some option I'm missing int the 'time' module), other than writing code to get %z output and reformat it in %:z format, to solve this problem?
EDIT: Another question (Generate RFC 3339 timestamp in Python) gives solutions for other modules that can be used to output RFC3339 output. I'm going to self-answer with information that I found for the question in the title.
The strict answer to the question in the title "Does python time.strftime process timezone options correctly (for RFC3339)?" is: No.
The "%:z" supported by the Linux 'date' command is a GNU extension, and is not in the POSIX spec, or in the C implementation of strftime (as of this writing).
With regards to workarounds (requested in the body of the question), answers in Generate RFC 3339 timestamp in Python can be used as alternatives time.strftime to output RFC3339-compliant software.
Specifically, I used the pytz module to get timezone information, and datetime class isoformat() function to print in RFC3339-compliant format (with a colon in the timezone offset portion of the output). Like so:
(in Python 2.7 on Ubuntu 14.04)
>>> import pytz, datetime
>>> latz = pytz.timezone("America/Los_Angeles")
>>> latz
<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>
>>> dt = datetime.datetime.now(latz)
>>> dt2 = datetime.datetime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, 0, latz)
>>> dt2.isoformat()
'2017-07-06T11:50:07-08:00'
Note the conversion from dt to dt2, to set microseconds to 0. This prevents isoformat from printing microseconds as a decimal portion of seconds in the isoformat output (which RFC3339 does not support)

Converting date string with timezone to epoch

I'm trying to convert this date string including timezone to epoch time.
(python 2.7)
Mon, 08 Jun 2009 19:37:51 GMT
I tried to do so like that:
from dateutil import parser
parser.parse("Mon, 08 Jun 2009 19:37:51 GMT").strftime('%s')
The error I get is:
ValueError: Invalid format string
What is the problem? How can it be fixed?
Thanks.
Python 3.5 solution using timestamp() method:
from dateutil import parser
print(parser.parse("Mon, 08 Jun 2009 19:37:51 GMT").timestamp())
which yields:
1244489871.0
There are suggestions for not using strftime
References:
Convert python datetime to epoch with strftime
https://dateutil.readthedocs.io/en/stable/examples.html#parse-examples

Convert Spanish date in string format?

How would I convert a date in string format to compare it with the current time?
I tried this:
import time, datetime
if time.strptime(date.find(text=True), "%a, %d/%m/%Y").now() > datetime.now():
But I get this error:
ValueError: time data u'Dom, 07/02/2016' does not match format '%a, %d/%m/%Y'
Need advice on how to do this.
You need to setup the proper locale before handling language/region specific data.
Try again with
import locale
locale.setlocale(locale.LC_TIME, '')
time.strptime(date_string, "%a, %d/%m/%Y")
The '' tells the library to pickup the current locale of your system (if one is set).
If you need to parse the date in a different locale, the situation is a little bit more complex. See How do I strftime a date object in a different locale? for the gritty details.
It is possible to explicitly set a specific locale, e.g.
locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8')
time.strptime('Dom, 01/02/1903', '%a, %d/%m/%Y')
=> time.struct_time(tm_year=1903, tm_mon=2, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=32, tm_isdst=-1)
but remember, that this setting is global. strptime() does not accept a parameter to specify a particular locale to parse with, it always picks up the global locale.
If the date is user-supplied, I have used dateparser package as a welcome alternative. Especially so, since its parse() function accepts an explicit languages parameter.

Convert String to Time Python

I have a time String like this:
07/01/2015-14:31:58.520
I use this command line to convert it:
import time
timeStr = "07/01/2015-14:31:58.520"
time.strptime(timeStr,'%d/%m/%y-%H:%M:%S.%f')
But this returns:
ValueError: time data '07/01/2015-14:31:58.520' does not match format
'%d/%m/%y-%H:%M:S.%f'
My python version is 2.7.7
%y denotes a 2 digit year, but your string has a 4 digit year. Use %Y (capital Y) to denote a 4 digit year. See the docs for more information.
time.strptime(timeStr, '%d/%m/%Y-%H:%M:%S.%f')
Note that datetime.strptime may be more useful, as it will return a full datetime object rather than a tuple. The format syntax is essentially the same.
It should have been capital Y for year (%Y in place of %y)
time.strptime(timeStr,'%d/%m/%Y-%H:%M:%S.%f')
You need to use %Y instead of %y
time.strptime(timeStr,'%d/%m/%Y-%H:%M:%S.%f')
To get a datetime object, use python-dateutil
To install
pip install python-dateutil
Then
t = "07/01/2015-14:31:58.520"
from dateutil import parser
>>>parser.parse(t)
datetime.datetime(2015, 7, 1, 14, 31, 58, 520000)
tim = parser.parse(t)
>>>str(tim.date())
'2015-07-01'
All operations to datetime objects is possible.
the time.strptime syntax %d/%m/%y-%H:%M:%S.%f is incorrect, it should be
"%d/%m/%Y-%H:%M:%S.%f"
where the only difference is that %y has become %Y. The reason is because from the docs %y is without century number ( [00,99] ), whereas %Y is with century number, which is the syntax you use with "2015"
Tested and functinal in python 2.7.5 and 3.4.1
Edit: Zero answers when I started typing this, 6 answers by time of post, sorry about that!
Edit #2: datetime.strptime functions similarly, so if you want to use that as well, you can!

How to convert a UTC datetime string into date?

There is a datetime string that I would like to convert back into a date. The time zone is giving me trouble and I don't know how to solve it.
datetime.datetime.strptime(json_event['date_time'], '%a, %d %b %Y %H:%M:%S %Z')
I get the error message:
ValueError: time data 'Tue, 08 Apr 2014 17:57:34 -0000' does not match
format '%a, %d %b %Y %H:%M:%S %Z'
If I leave %Z out, I get this error message:
ValueError: unconverted data remains: -0000
The date is originally a UTC:
current_date = datetime.datetime.utcnow()
UPDATE:
I would like to solve this natively without any external libraries such as dateutil.parser, hence the solution in the duplicate doesn't help me.
import dateutil.parser
date = dateutil.parser.parse(json_event['date_time'])
If you don't have dateutil, get it.
pip install python-dateutil
If you are always getting UTC times: Ignore the last 6 chars (space, sign, 4 digts) and then convert to datetime as you've done without the %Z.
One issue you'll have is that your system will assume that it is your local timezone and if you convert it to any other timezone, it will convert wrongly. In that case, next step is to use this answer from another question.
If you get non-UTC times as well:
crop out the last 6 chars.
Do the strptime on the last 4 digits, with the format HHMM (%H%M) --> Y
Get the sign and reverse in step 5 below.
Then get the rest of the datetime as you have above (leaving those last 6 chars and no %Z in the format) --> X
Then X-Y (or X+Y, invert what is got from step 3) will give you a datetime object. Then follow the steps in the linked answer to make the datetime obj timezone aware.

Categories