3

i'm a python beginner and having an issue. Trying to pull API info and convert the extracted JSON time object to a datetime object in Python so I can run the date.weekday() function on it eventually (the overall goal is to extract all the dates from the API and see which the output by days - I plan on populating a empty dictionary once I can extract all the dates).

For some reason, even with my conditional statements, I'm still printing (2015, 04, 06) with all the zeroes. That's my problem.

I have a feeling I'm getting something basic wrong, and that there's also a better way to go about this than doing all the ifs/elses with the 0-padding in the date object.

here's my code so far:

from datetime import date
import datetime
import json
import requests

r = requests.get('https://api.github.com/repos/mbostock/d3/commits?since=2015-04-12330:00:000')
jsonoutput = r.json()
modified = (jsonoutput[0]["commit"]["author"]["date"])
#at this point, modified gives something like: "2015-04-06T22:28:16Z"

if modified[5] == 0:
    if modified[8] == 0:
        new_format = ("(" + modified[0:4] + ", " + modified[6] + ", " + modified[9] + ")")
        #with the particular jsonoutput[0] pulled here, this one should be triggered
    else:
        new_format = ("(" + modified[0:4] + ", " + modified[6] + ", " + modified[8:10] + ")")

else:
    if modified[8] == 0:
        new_format = ("(" + modified[0:4] + ", " + modified[5:7] + ", " + modified[9] + ")")
    else:
        new_format = ("(" + modified[0:4] + ", " + modified[5:7] + ", " + modified[8:10] + ")")

print(new_format)

print(date.weekday(datetime.date(new_format)))
SpicyClubSauce
  • 4,076
  • 13
  • 37
  • 62
  • `NameError` occurs when you try to use a variable that you have not yet declared Your code only declares new_format if `modified[5] == 0` or `modifies[5] == 1` -- but if `modified[5] ` doesn't equal either, the variable is undefined. – jwilner Apr 20 '15 at 00:34
  • ah, i just needed to change the second if to an else. But I'm still getting an output of (2015, 04, 06) with all the zeroes. any idea why @jwilner ? – SpicyClubSauce Apr 20 '15 at 00:36
  • @mu無 shouldn't that not matter with the string manipulation i'm doing? – SpicyClubSauce Apr 20 '15 at 00:40
  • @jwilner Given that modified is a timestamp, `modified[5]` could only be 0 or 1, so the elif vs else shouldn't matter right? – Anshul Goyal Apr 20 '15 at 00:41
  • 1
    @mu無, the code was failing with a NameError because the variable was undefined. The variable was defined within both `if` and `elif` blocks; therefore, it never hit either block -- probably because modified[5] was a string, and `0 == "1" or 0 == "0" # False` – jwilner Apr 20 '15 at 00:45

3 Answers3

2

The error happens in your current code because new_format is defined as a string, while the datetime.date takes the arguments as integers. Also, since you compare the string "0" with the numerical 0, the modified is simply not created.

Instead of this:

new_format = ("(" + modified[0:4] + ", " + modified[6] + ", " + modified[8:10]) + ")")

do this:

new_format = (int(modified[0:4]), int(modified[5:7]), int(modified[8:10]))

The above will work with all of your cases, so you can remove the convoluted if-else blocks as well.

Alternatively, you could split this modeified string by "T", and then use another split by "-" to get the integer values:

new_format = map(int, modified.split("T")[0].split("-"))

You'll also need to unpack the list when passing as the argument, so your complete code becomes:

import json
import requests
from datetime import date

r = requests.get('https://api.github.com/repos/mbostock/d3/commits?since=2015-04-12330:00:000')
jsonoutput = r.json()
modified = jsonoutput[0]["commit"]["author"]["date"]
new_format = (int(modified[0:4]), int(modified[5:7]), int(modified[8:10]))
print(date.weekday(date(*new_format)))

Also, as others have already pointed out in their answers, it might be a better idea to dateutil.parser.parse than to write your own parsing logic. (dateutil is not a builtin package, you'll have to install it) :)

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • thanks @mu 無 - looks like the dateutil.parser.parse works fine but I'm wondering why, after replacing my conditionals with your format, i'm still struggling to convert the output to a datetime.date object. datetime.date(new_format) is telling me an integer is required, not a tuple, but datetime.date(int(new_format) isn't giving me luck either. Sorry for all the absolutely beginner lvl questions man. – SpicyClubSauce Apr 20 '15 at 01:00
  • @SpicyClubSauce I ran the current code in my answer, and it works allright, so can you re-check? Also, I've made a series of edits, so have a look at the answer in its current form. – Anshul Goyal Apr 20 '15 at 01:01
  • hey @mu 無 - that works! what does the * do? I didnt have that in, and that gives an error when I don't have that in. – SpicyClubSauce Apr 20 '15 at 01:05
  • @SpicyClubSauce That unpacks the tuple/list. Without the `*`, the list is passed as a single argument. With it, the elements of the list are passed as the multiple arguments. [Check here](https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists). If that helped, don't forget to [accept and upvote](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) :) – Anshul Goyal Apr 20 '15 at 01:08
0

What you get from the json is actually a datetime representation in an ISO format

You can refer to this SO answer https://stackoverflow.com/a/15228038/58129 to convert the string

Community
  • 1
  • 1
Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
0

You're trying to make your own parsing functions where Python has its own.

from dateutil import parser
from datetime import date

my_date = dateutil.parser.parse(modified)

is_week_day = date.weekday(my_date)

If dateutil is not installed on your machine, try pip install python-dateutil


However, if you want to go with Python's standard library:

from datetime import date, datetime
from time import strptime

mytime = strptime(modified, '%Y-%m-%dT%H:%M:%SZ')
my_date = datetime(*my_time[:6])

is_week_day = date.weekday(my_date)
Jivan
  • 21,522
  • 15
  • 80
  • 131
  • I'm also just going to put in a shout out for the standard `datetime` library. Being explicit about expected inputs is always better, IMO, and `datetime.datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%sZ")` is way more explicit. Plus, no third party libraries. – jwilner Apr 20 '15 at 00:49
  • @jwilner your (legitimate) shout has been heard – Jivan Apr 20 '15 at 00:57