Python strftime %A fixed length - python

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)

Related

Python datetime strptime() does not match format

I get the following error in which you can see the time data and the format I am using
time data '20:07:35 EEDT Wed Mar 31 2021' does not match format '%H:%M:%S %Z %a %b %d %Y'
I used the directives from here and I see that the format matches the description of each directive.
Can you see what is the issue here?
import datetime
time = '20:07:35 EEDT Wed Mar 31 2021'
time = time.replace('EEDT', '+0300')
datetime.datetime.strptime(time, '%H:%M:%S %z %a %b %d %Y')
you can map the abbreviated time zone to a IANA time zone name by dateutil's parser:
import dateutil
s = '20:07:35 EEDT Wed Mar 31 2021'
tzmapping = {"EEDT": dateutil.tz.gettz('Europe/Athens'),
"EEST": dateutil.tz.gettz('Europe/Athens')} # add more if needed...
dtobj = dateutil.parser.parse(s, tzinfos=tzmapping)
that will give you
dtobj
# >>> datetime.datetime(2021, 3, 31, 20, 7, 35, tzinfo=tzfile('Europe/Athens'))
dtobj.utcoffset()
# >>> datetime.timedelta(seconds=10800) # UTC+3
Note that timedelta arithmetic works correctly, i.e. includes DST changes:
from datetime import timedelta
dtobj -= timedelta(7) # DST change: dtobj is now EEST, UTC+2
dtobj.utcoffset()
# >>> datetime.timedelta(seconds=7200)
Problem is with EEDT. If you ignore EEDT(quickfix, not ideal), then your code may look like:
text = '20:07:35 EEDT Wed Mar 31 2021';
fmt = '%H:%M:%S EEDT %a %b %d %Y';
datetime.strptime(text, fmt)
--edit--
parsing datetime with timezone is difficult to pure datetime module. I'm not big expert, but pytz or python-datetutil should be good choice, according to this page: https://medium.com/#nqbao/python-timezone-and-daylight-savings-e511a0093d0
For those who are interested in different approach for similar, like GMT and BST or EEST and EEDT, it can be represented like this:
import datetime
try:
Time1 = datetime.datetime.strptime(DropTm,"%a %b %d %H:%M:%S GMT %Y")
except:
Time1 = datetime.datetime.strptime(DropTm,"%a %b %d %H:%M:%S BST %Y")
In your situation it will be:
import datetime
try:
Time1 = datetime.datetime.strptime(SomeValue,"%H:%M:%S EEDT %a %b %d %Y")
except:
Time1 = datetime.datetime.strptime(SomeValue,"%H:%M:%S EEST %a %b %d %Y")
Where is "SomeValue" your data!!
It did worked for me and do not need any other libraries! Good Luck with coding!!!

Python - Convert String date "17 Apr" to Date "17-04-2018"

I've this string variable:
date_string = "17 Apr"
How can I get this: 17-04-2018?
I'm trying with this
datetime_object = datetime.strptime(date_string, "%d %B")
But I'm getting:
builtins.ValueError: time data '17 Apr' does not match format '%d %B
Thanks!
As you can see in the documentation, you should use %b (lowercase) for "Locale’s abbreviated month name". %B is for "Locale’s full month name".
import time
date_string = "17 Apr"
datetime_object = time.strptime(date_string, "%d %b")
print(datetime_object)
Pyfiddle
Using datetime module.
Ex:
import datetime
s = "17 Apr"
print(datetime.datetime.strptime("{0} 2018".format(s), "%d %b %Y").strftime("%d-%m-%Y"))
Output:
17-04-2018

Time data does not match specified format

I'm trying to convert a string given in "DD MM YYYY" format into a datetime object. Here's the code for the same:
from datetime import date, timedelta
s = "23 July 2001"
d = datetime.datetime.strptime(s, "%d %m %Y")
However, I get the following error:
ValueError: time data '23 July 2001' does not match format '%d %m %Y'
What's wrong ? Isn't the format specified in the string the same as that specified by "%d %m %Y" ?
%m means "Month as a zero-padded decimal number."
Your month is July so you should use %B, which is "Month as locale’s full name."
Reference: https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior
Like behzad.nouri said, Use d = datetime.datetime.strptime(s, "%d %B %Y").
Or make s = '23 07 2001' and d = datetime.datetime.strptime(s, "%d %m %Y")

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).

Python convert date time not working

I am trying to parse string into python datetime object and this is the code:
created = datetime.strptime(r.json()[x]["created_at"], "%a %b %d %H:%M:%S +0000 %Y")
The error I get is:
ValueError: time data '"Wed Jan 16 22:08:18 +0000 2013"' does not match format '%a %b %d %H:%M:%S +0000 %Y'
It should be correct, obviously I am doing something wrong. As a note, the r.json returns the text in unicode, but I tried it with a str() conversion as well.
The full program:
import requests
from datetime import datetime
from simplejson import dumps
url = 'https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name='
username = 'gtklondike'
count = '5'
url += username + "&count=" + count
r = requests.get(url)
x = 0
while x < count:
print "<div id='tw-body'>" + r.json()[x]["text"] + "</div>"
created = datetime.strptime(dumps(r.json()[x]["created_at"]), "%a %b %d %H:%M:%S +0000 %Y")
print "<div id='tw-date'>Date: " + r.json()[x]["created_at"] + "</div><br />\n" # TMP --> until I get datetime working... but at least it shows you the date
x = x + 1
It looks to me like there's an extra set of quotes in your string - one ' denoting that it's a string, and one " inside the string.
Try:
created = datetime.strptime((r.json()[x]["created_at"]).strip('"'), "%a %b %d %H:%M:%S +0000 %Y")
strip('"') removes the "s from the string.
I found the issue! #wrgrs solution worked, but actually it is from the dumps() being around it, created an extra set of quotes. (It was his solution that triggered my idea)
created = datetime.strptime(r.json()[x]["created_at"], "%a %b %d %H:%M:%S +0000 %Y")
works just fine!
I would use the parse function provided by Delorean for future dealings with strptime e.g
>>> from delorean import parse
>>> parse("2011/01/01 00:00:00 -0700")
Delorean(datetime=2011-01-01 07:00:00+00:00, timezone=UTC)
It accepts a wide range of string input as well as take into account different timezones and provides easy mechanisms for shifting, to retrieve the required datetime object simple .datetime on the delorean object.

Categories