Python convert date time not working - python

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.

Related

How to convert datetime to different timezone?

I'm trying to convert a datetime string into a different timezone. My code works but the result is not what I'm looking for.
I've already tried .localize() and .astimezone but the output is the same.
phtimezone = timezone('Asia/Manila')
test = datetime.datetime.strptime('Sun Sep 16 03:38:40 +0000 2018','%a %b %d %H:%M:%S +0000 %Y')
date = phtimezone.localize(test)
print (date)
date = test.astimezone(phtimezone)
print (date)
The output is 2018-09-16 03:38:40+08:00. I was expecting it to be 2018-09-16 11:38:40+08:00.
Your parsed object test does not contain a timezone. It's a naïve datetime object. Using both localize and astimezone cannot do any conversion, since they don't know what they're converting from; so they just attach the timezone as given to the naïve datetime.
Also parse the timezone:
datetime.strptime('Sun Sep 16 03:38:40 +0000 2018','%a %b %d %H:%M:%S %z %Y')
^^
This gives you an aware datetime object in the UTC timezone which can be converted to other timezones.
I was able to fix it thanks to #deceze. Here is the code:
phtimezone = pytz.timezone('Asia/Manila')
test = datetime.datetime.strptime('Sun Sep 16 03:38:40 +0000 2018','%a %b %d %H:%M:%S %z %Y')
test_utc = test.replace(tzinfo=timezone('UTC'))
date = test_utc.astimezone(pytz.timezone('Asia/Manila'))
print (date)
The output is now 2018-09-16 11:38:40+08:00

Python date conversion?

I'm currently trying to convert a file format into a slightly different style to allow easier importing into a program however I can't quite get my head around how to convert datetime strings between formats. The original I have is the following:
2016-12-15 17:26:45
However the required format for the date time is:
Thu Dec 15 17:19:03 2016
Does anyone know if there is an easy way to convert between these? These values are always in the same place and format so it doesn't need to be too dynamic so to speak outside of recognising what a certain day of the month is (if that can be done at all?)
Update - The conversion has worked for 1 date but not the other weirdly :/ The code to grab the two dates is the following:
startDate=startDate.replace("Started : ","")
startDate=startDate.replace(" (ISO format YYYY-MM-DD HH:MM:SS)","")
startDate=startDate.strip()
startDt = datetime.strptime(startDate, '%Y-%m-%d %H:%M:%S')
startDt=startDt.strftime('%a %b %d %H:%M:%S %Y ')
print (startDt)
This part works as inteded and outputs the required format:
"2016-12-15 17:26:45
Thu Dec 15 17:26:45 2016"
The end date part is a bit "ham fisted" so to speak and I'm sure there are better ways to do the re.sub search just to do anything in brackets but I'll edit that later.
endDate=endDate.replace("Ended : ","")
endDate=endDate.strip()
endDate = re.sub("\(.*?\)", "", endDate)
endDate.strip()
endDt = datetime.strptime(endDate, '%Y-%m-%d %H:%M:%S')
endDt=endDt.strftime('%a %b %d %H:%M:%S %Y ')
print (endDt)
This part however despite the outputs being an identical format
"2016-12-15 17:26:45
2016-12-15 21:22:11"
produces the following error:
endDt = datetime.strptime(endDate, '%Y-%m-%d %H:%M:%S')
File "C:\Python27\lib\_strptime.py", line 335, in _strptime
data_string[found.end():])
ValueError: unconverted data remains:
from datetime import datetime
dt = datetime.strptime('2016-06-01 1:33:45', '%Y-%m-%d %H:%M:%S')
dt.strftime('%a %b %d %H:%M:%S %Y ')
>>> 'Wed Jun 01 01:33:45 2016'
It's a pretty easy task with the Datetime module.
As it's been pointed out, checking the docs will get you a lot of useful info, starting from the directives to feed to the strptime and strftime (respectively, parse and format time) functions which you'll need here.
A working example for you case would be:
from datetime import datetime
myDateString = '2016-12-15 17:26:45'
myDateObj = datetime.strptime(myDateString, '%Y-%m-%d %H:%M:%S')
myDateFormat = myDateObj.strftime('%a %b %d %H:%M:%S %Y')
Check out this section of the docs to have a better understanding of the formatting placeholders.
You can use the datetime module:
from datetime import datetime
string = '2016-12-15 17:26:45'
date = datetime.strptime(string, '%Y-%m-%d %H:%M:%S')
date2 = date.strftime("%a %b %d %H:%M:%S %Z %Y")
print(date2)
Output:
Thu Dec 15 17:26:45 2016

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)

Converting String to Date Format in Python

I have the following date I need to convert:
Wed, 09 Jul 2014 12:22:17 +0000
This is currently stored as a String. I wrote this code to convert it to the date format I want (the String above is passed as an argument to the covertDate function):
def convertDate(dictValue):
date_string = dictValue
format_string = '%a, %d %b %Y %H:%M:%S %z'
date_object = datetime.datetime.strptime(date_string, format_string)
date_correct_form = date_object.strftime("%Y-%m-%d")
print(type(date_correct_form))
print(date_correct_form)
return date_correct_form
The output is as follows:
<class 'str'>
2014-10-30
I get the format that I want, but it still isn't recognized as a date.
How can I make it so?
You are returning date_correct_form, which is the result of strftime:
Return a string representing the date, controlled by an explicit format string.
(emphasis mine)
If you want the datetime object, return date_object. If you need both, you can return both:
return date_correct_form, date_object
You can call it like so:
date_string, date_obj = convertDate(dictValue)
You now have the already formatted string in date_string, and if you still need to do logic against the datetime object, that is in date_obj
You can use easy_date to make it easy:
import date_converter
converted_date = date_converter.string_to_date(date_string, '%a, %d %b %Y %H:%M:%S %z')

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

Categories