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)))
5
  • 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. Commented Apr 20, 2015 at 0: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 ? Commented Apr 20, 2015 at 0:36
  • @mu無 shouldn't that not matter with the string manipulation i'm doing? Commented Apr 20, 2015 at 0: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? Commented Apr 20, 2015 at 0: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 Commented Apr 20, 2015 at 0:45

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

4 Comments

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 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.
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 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. If that helped, don't forget to accept and upvote :)
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

Comments

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)

2 Comments

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 your (legitimate) shout has been heard

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.