How to convert "01 January 2016" to UTC ISO format? - python

So I have the following string : " 01 January 2016" to UTC ISO date format ?
I'm using arrow module and the following code, but it's full of errors, and I was thinking that may be, there was a smaller more elegent solution as python encourages elegant and easier ways to do things, anyways here's my code :
updateStr = " 01 January 2016" #Note the space at the beginning
dateList = updateStr.split[' ']
dateDict = {"day" : dateList[1],"month": months.index(dateList[2])+1, "year" : dateList[3]}
dateStr = str(dateDict['day']) + "-" + str(dateDict["month"]) + "-" + str(dateDict["year"])
dateISO = arrow.get(dateStr, 'YYYY-MM-DD HH:mm:ss')
Please help me I have to convert it to the UTC ISO formats, Also months is a list of months in the year .

You can use datetime:
>>> updateStr = " 01 January 2016"
>>> import datetime as dt
>>> dt.datetime.strptime(updateStr, " %d %B %Y")
datetime.datetime(2016, 1, 1, 0, 0)
>>> _.isoformat()
'2016-01-01T00:00:00'
Keep in mind that is a 'naive' object without a timezone. Check out pytz to deal with timezones elegantly, or just add an appropriate utcoffset to the datetime object for UTC.

Using arrow:
>>> import arrow
>>> updateStr = " 01 January 2016"
>>> arrow.get(updateStr, "DD MMMM YYYY").isoformat()
'2016-01-01T00:00:00+00:00'
>>>

You can use datetime's methods to parse this date string and then reformat it to UTC format:
>>> from datetime import datetime
>>> updateStr = " 01 January 2016" #Note the space at the beginning
>>> d = datetime.strptime(updateStr, ' %d %B %Y') # Same space here
>>> s = datetime.isoformat(d)
>>> s
'2016-01-01T00:00:00'

Related

How to extract second from date and time in python

By using:
import os,os.path,time,shutil,datetime
print time.ctime(os.path.getmtime("/home/sulata/Documents/source/"))
print time.ctime(os.path.getmtime("/home/sulata/Documents/destination/"))
I'm getting the outputs:
Mon Apr 2 15:56:00 2018
Mon Apr 2 15:56:03 2018
I want to get the time without seconds.
The general method is:
import time
time.strftime(format)
example:
>>>time.strftime("%H:%M:%S")
20:08:40
In your case:
>>> time.strftime("%H:%M")
13:41
>>>time.strftime("%a %b %d %H:%M %Y")
'Mon Apr 02 13:27 2018'
if you want to remove the Zero, you could do something like this...
>>> time.strftime("%a %b "+str(int(time.strftime("%d"))) +" %H:%M %Y")
'Mon Apr 2 13:33 2018'
Use datetime to get the seconds.
Ex:
import os,os.path,time,shutil,datetime
print datetime.datetime.strptime(time.ctime(os.path.getmtime(r"/home/sulata/Documents/source/")), "%a %b %d %H:%M:%S %Y").second
JulioCamPlaz has already provided a decent enough solution, but if you want to maintain the date format, you can use regex for this:
import re
x = time.ctime(os.path.getmtime("/home/sulata/Documents/source/"))
print(re.sub(r':\d{1,2}\s', ' ', x))
What this does is that it removes the final two digits (seconds) of the time which are followed by a space, and replaces it with a space.
Although this may be an over-complicated method, it is short, and gives you the exact same date format without the seconds, and without altering it in any way.
getmtime returns a timestamp, so you can format it using strftime to whatever format you need:
>>> import datetime as dt
>>> import os
>>> mTime = os.path.getmtime("/tmp/xauth-1000-_0")
>>> dt.datetime.fromtimestamp(mTime).strftime("%Y-%m-%d %H:%M")
'2018-04-01 22:07'
Format identifiers can be found in the docs.
You can try this -
>>> import time, os
>>>
>>> x = time.gmtime(os.path.getmtime('/home/abhi/test.file'))
>>>
>>> x
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=2, tm_hour=11, tm_min=19, tm_sec=43, tm_wday=0, tm_yday=92, tm_isdst=0)
>>> x.tm_sec
43
>>> x.tm_hour
11
>>>

Python strftime %A fixed length

I am using the following date format:
d.strftime("%A, %d %B %Y %H:%m")
and since the length of the weekday (%A) changes,
I would like to always print the weekday with
10 characters, pad spaces to the left, and align it right.
Something like
d.strftime("10%A, %d %B %Y %H:%m")
What is the simplest way?
str.rjust(10) does exactly that:
s = d.strftime('%A').rjust(10) + d.strftime(', %d %B %Y %H:%M')
It is likely that you want %M (minutes), not %m (months) in your format string as #Ahmad pointed out.
In Python 3.6+, to get a more concise version, one can abuse nested f-strings:
>>> f"{f'{d:%A}':>10}, {d:%d %B %Y %H:%M}"
' Friday, 15 December 2017 21:31'
Prefer standard time formats such as rfc 3339:
>>> from datetime import datetime
>>> datetime.utcnow().isoformat() + 'Z'
'2016-02-05T14:00:43.089828Z'
Or rfc 2822:
>>> from email.utils import formatdate
>>> formatdate(usegmt=True)
'Fri, 05 Feb 2016 14:00:51 GMT'
instead.
How about this:
d.strftime("%A") + " " * (10 - len(d.strftime("%A")) + "," + d.strftime("%d %B %Y %H:%m")
Jack
This is roughly equivalent to jfs's answer, but you can use .format() to make it slightly shorter:
s = '{:>10}, {:%d %B %Y %H:%m}'.format(d.strftime('%A'), d)
or if you're putting more than just the date into the string:
args = {
'weekday' = d.strftime('%A'),
'date' = d,
'foo' = some_other_stuff(),
'bar' = 17.5422,
}
s = '{weekday:>10}, {date:%d %B %Y %H:%m} {foo} {bar:>3.2f}'.format(**args)

How do I retrieve all RSS entries that are no more than X days old

I am using Python and the RSS feedparser module to retrieve RSS entries. However I only want to retrieve a news item if it is no more than x days old.
For example if x=4 then my Python code should not fetch anything four days older than the current date.
Feedparser allows you to scrape the 'published' date for the entry, however it is of type unicode and I don't know how to convert this into a datetime object.
Here is some example input:
date = 'Thu, 29 May 2014 20:39:20 +0000'
Here is what I have tried:
from datetime import datetime
date_object = datetime.strptime(date, '%a, %d %b %Y %H:%M:%S %z')
This is the error I get:
ValueError: 'z' is a bad directive in format '%a, %d %b %Y %H:%M:%S %z'
This is what I hope to do with it:
from datetime import datetime
a = datetime(today)
b = datetime(RSS_feed_entry_date)
>>> a-b
datetime.timedelta(6, 1)
(a-b).days
6
For this, you already have a time.struct_time look at feed.entries[0].published_parsed
you can use time.mktime to convert this to a timestamp and compare it with time.time() to see how far in the past it is:
An example:
>>> import feedparser
>>> import time
>>> f = feedparser.parse("http://feeds.bbci.co.uk/news/rss.xml")
>>> f.entries[0].published_parsed
time.struct_time(tm_year=2014, tm_mon=5, tm_mday=30, tm_hour=14, tm_min=6, tm_sec=8, tm_wday=4, tm_yday=150, tm_isdst=0)
>>> time.time() - time.mktime(feed.entries[0].published_parsed)
4985.511506080627
obviosuly this will be a different value for you, but if this is less than (in your case) 86400 * 4 (number of seconds in 4 days), it's what you want.
So, concisely
[entry for entry in f.entries if time.time() - time.mktime(entry.published_parsed) < (86400*4)]
would give you your list
from datetime import datetime
date = 'Thu, 29 May 2014 20:39:20 +0000'
if '+' in date:
dateSplit = date.split('+')
offset = '+' + dateSplit[1]
restOfDate = str(dateSplit[0])
date_object = datetime.strptime(restOfDate + ' ' + offset, '%a, %d %b %Y %H:%M:%S ' + offset)
print date_object
Yields 2014-05-29 20:39:20, as I was researching your timezone error I came across this other SO question that says that strptime has trouble with time zones (link to question).

Convert datetime object to a String of date only in Python

I see a lot on converting a date string to an datetime object in Python, but I want to go the other way.
I've got
datetime.datetime(2012, 2, 23, 0, 0)
and I would like to convert it to string like '2/23/2012'.
You can use strftime to help you format your date.
E.g.,
import datetime
t = datetime.datetime(2012, 2, 23, 0, 0)
t.strftime('%m/%d/%Y')
will yield:
'02/23/2012'
More information about formatting see here
date and datetime objects (and time as well) support a mini-language to specify output, and there are two ways to access it:
direct method call: dt.strftime('format here')
format method (python 2.6+): '{:format here}'.format(dt)
f-strings (python 3.6+): f'{dt:format here}'
So your example could look like:
dt.strftime('The date is %b %d, %Y')
'The date is {:%b %d, %Y}'.format(dt)
f'The date is {dt:%b %d, %Y}'
In all three cases the output is:
The date is Feb 23, 2012
For completeness' sake: you can also directly access the attributes of the object, but then you only get the numbers:
'The date is %s/%s/%s' % (dt.month, dt.day, dt.year)
# The date is 02/23/2012
The time taken to learn the mini-language is worth it.
For reference, here are the codes used in the mini-language:
%a Weekday as locale’s abbreviated name.
%A Weekday as locale’s full name.
%w Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.
%d Day of the month as a zero-padded decimal number.
%b Month as locale’s abbreviated name.
%B Month as locale’s full name.
%m Month as a zero-padded decimal number. 01, ..., 12
%y Year without century as a zero-padded decimal number. 00, ..., 99
%Y Year with century as a decimal number. 1970, 1988, 2001, 2013
%H Hour (24-hour clock) as a zero-padded decimal number. 00, ..., 23
%I Hour (12-hour clock) as a zero-padded decimal number. 01, ..., 12
%p Locale’s equivalent of either AM or PM.
%M Minute as a zero-padded decimal number. 00, ..., 59
%S Second as a zero-padded decimal number. 00, ..., 59
%f Microsecond as a decimal number, zero-padded on the left. 000000, ..., 999999
%z UTC offset in the form +HHMM or -HHMM (empty if naive), +0000, -0400, +1030
%Z Time zone name (empty if naive), UTC, EST, CST
%j Day of the year as a zero-padded decimal number. 001, ..., 366
%U Week number of the year (Sunday is the first) as a zero padded decimal number.
%W Week number of the year (Monday is first) as a decimal number.
%c Locale’s appropriate date and time representation.
%x Locale’s appropriate date representation.
%X Locale’s appropriate time representation.
%% A literal '%' character.
Another option:
import datetime
now=datetime.datetime.now()
now.isoformat()
# ouptut --> '2016-03-09T08:18:20.860968'
If you are looking for a simple way of datetime to string conversion and can omit the format. You can convert datetime object to str and then use array slicing.
In [1]: from datetime import datetime
In [2]: now = datetime.now()
In [3]: str(now)
Out[3]: '2019-04-26 18:03:50.941332'
In [5]: str(now)[:10]
Out[5]: '2019-04-26'
In [6]: str(now)[:19]
Out[6]: '2019-04-26 18:03:50'
But note the following thing. If other solutions will rise an AttributeError when the variable is None in this case you will receive a 'None' string.
In [9]: str(None)[:19]
Out[9]: 'None'
You could use simple string formatting methods:
>>> dt = datetime.datetime(2012, 2, 23, 0, 0)
>>> '{0.month}/{0.day}/{0.year}'.format(dt)
'2/23/2012'
>>> '%s/%s/%s' % (dt.month, dt.day, dt.year)
'2/23/2012'
You can easly convert the datetime to string in this way:
from datetime import datetime
date_time = datetime(2012, 2, 23, 0, 0)
date = date_time.strftime('%m/%d/%Y')
print("date: %s" % date)
These are some of the patterns that you can use to convert datetime to string:
For better understanding, you can take a look at this article on how to convert strings to datetime and datetime to string in Python or the official strftime documentation
type-specific formatting can be used as well:
t = datetime.datetime(2012, 2, 23, 0, 0)
"{:%m/%d/%Y}".format(t)
Output:
'02/23/2012'
If you want the time as well, just go with
datetime.datetime.now().__str__()
Prints 2019-07-11 19:36:31.118766 in console for me
The sexiest version by far is with format strings.
from datetime import datetime
print(f'{datetime.today():%Y-%m-%d}')
It is possible to convert a datetime object into a string by working directly with the components of the datetime object.
from datetime import date
myDate = date.today()
#print(myDate) would output 2017-05-23 because that is today
#reassign the myDate variable to myDate = myDate.month
#then you could print(myDate.month) and you would get 5 as an integer
dateStr = str(myDate.month)+ "/" + str(myDate.day) + "/" + str(myDate.year)
# myDate.month is equal to 5 as an integer, i use str() to change it to a
# string I add(+)the "/" so now I have "5/" then myDate.day is 23 as
# an integer i change it to a string with str() and it is added to the "5/"
# to get "5/23" and then I add another "/" now we have "5/23/" next is the
# year which is 2017 as an integer, I use the function str() to change it to
# a string and add it to the rest of the string. Now we have "5/23/2017" as
# a string. The final line prints the string.
print(dateStr)
Output --> 5/23/2017
You can convert datetime to string.
published_at = "{}".format(self.published_at)
String concatenation, str.join, can be used to build the string.
d = datetime.now()
'/'.join(str(x) for x in (d.month, d.day, d.year))
'3/7/2016'
end_date = "2021-04-18 16:00:00"
end_date_string = end_date.strftime("%Y-%m-%d")
print(end_date_string)
An approach to how far from now
support different languages by passing in param li, a list corresponding timestamp.
from datetime import datetime
from dateutil import parser
t1 = parser.parse("Tue May 26 15:14:45 2021")
t2 = parser.parse("Tue May 26 15:9:45 2021")
# 5min
t3 = parser.parse("Tue May 26 11:14:45 2021")
# 4h
t4 = parser.parse("Tue May 26 11:9:45 2021")
# 1day
t6 = parser.parse("Tue May 25 11:14:45 2021")
# 1day4h
t7 = parser.parse("Tue May 25 11:9:45 2021")
# 1day4h5min
t8 = parser.parse("Tue May 19 11:9:45 2021")
# 1w
t9 = parser.parse("Tue Apr 26 11:14:45 2021")
# 1m
t10 = parser.parse("Tue Oct 08 06:00:20 2019")
# 1y7m, 19m
t11 = parser.parse("Tue Jan 08 00:00:00 2019")
# 2y4m, 28m
# create: date of object creation
# now: time now
# li: a list of string indicate time (in any language)
# lst: suffix (in any language)
# long: display length
def howLongAgo(create, now, li, lst, long=2):
dif = create - now
print(dif.days)
sec = dif.days * 24 * 60 * 60 + dif.seconds
minute = sec // 60
sec %= 60
hour = minute // 60
minute %= 60
day = hour // 24
hour %= 24
week = day // 7
day %= 7
month = (week * 7) // 30
week %= 30
year = month // 12
month %= 12
s = []
for ii, tt in enumerate([sec, minute, hour, day, week, month, year]):
ss = li[ii]
if tt != 0:
if tt == 1:
s.append(str(tt) + ss)
else:
s.append(str(tt) + ss + 's')
return ' '.join(list(reversed(s))[:long]) + ' ' + lst
t = howLongAgo(t1, t11, [
'second',
'minute',
'hour',
'day',
'week',
'month',
'year',
], 'ago')
print(t)
# 2years 4months ago
I have used this method to insert dates to JSON object
my_json_string = json.dumps({'date_of_birth': '''{}'''.format(date_of_birth)})

Parse this date in Python: 5th November 2010

I'm having a bad time with date parsing and formatting today.
Points for somebody who can parse this date format into a datetime.date or datetime.datetime (I'm not too fussy but I'd prefer .date):
5th November 2010
Using dateutil:
In [2]: import dateutil.parser as dparser
In [3]: date = dparser.parse('5th November 2010')
In [4]: date
Out[4]: datetime.datetime(2010, 11, 5, 0, 0)
Unfortunately, strptime has no format characters for "skip an ordinal suffix" -- so, I'd do the skipping first, with a little RE, and then parse the resulting "clear" string. I.e.:
>>> import re
>>> import datetime
>>> ordn = re.compile(r'(?<=\d)(st|nd|rd|th)\b')
>>> def parse(s):
... cleans = ordn.sub('', s)
... dt = datetime.datetime.strptime(cleans, '%d %B %Y')
... return dt.date()
...
>>> parse('5th November 2010')
datetime.date(2010, 11, 5)
Your preference for date vs datetime is no problem of course, that's what the .date() method of datetime objects is for;-).
Third-party extensions like dateutil can be useful if you need to do a lot of "fuzzy" date parsing (or other fancy date-related stuff;-), by the way.
If the ordinal is constant then:
datetime.strptime(s, '%dth %B %Y')
Else:
date_str = '5th November 2010'
modified_date_str = date_str[0:1] + date_str[3:]
datetime.strptime(modified_date_str, '%d %B %Y')
Or like ~unutbu said use dateutil :)

Categories