Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial![](https://ecs-static.teamtreehouse.com/assets/views/marketing/shared/community-banner-white-47072046c51352fe6a69f5e691ff5700b28bb11d45197d7bdf066d9ea3f72d0c.webp)
![Chris White](https://secure.gravatar.com/avatar/7b2b8d32d620943bc90ef5d0399bd8f1?s=96&d=https%3A%2F%2Fecs-static.teamtreehouse.com%2Fassets%2Fcontent%2Fdefault_avatar-445fbbabfc8dc9188fb5967fe43322ee0c3e0dd1e10f378bf8343784af5a13eb.webp&r=pg)
Chris White
6,212 PointsStuck with Python timezone issue
I think half the problem is I'm not entirely sure what the end result it's expecting is - weather to use a pytz. notation approach or the .astimezone() approach (maybe neither?). But I'm stuck on this:
Create a function named to_timezone that takes a timezone name as a string. Convert starter to that timezone using pytz's timezones and return the new datetime.
Here's what I've got, which is obviously incorrect, and I've been stuck here for a few days:
import datetime
import pytz
starter = pytz.utc.localize(datetime.datetime(2015, 10, 21, 23, 29))
def to_timezone(new_timezone):
starter.astimezone(new_timezone)
return starter
1 Answer
![Chris Freeman](https://uploads.teamtreehouse.com/production/profile-photos/1153532/micro_image.jpg)
Chris Freeman
Treehouse Moderator 68,425 PointsThe Timezone Strings Challenge asks:
Create a function named to_timezone
that takes a timezone name as a string. Convert starter to that timezone using pytz
's timezones and return the new datetime
.
The function will need to do three things: create a new timezone, create a new datetime
object based on starter
, and return the new datetime
object. Here is one solution:
import datetime
import pytz
starter = pytz.utc.localize(datetime.datetime(2015, 10, 21, 23, 29))
def to_timezone(new_timezone):
# generate timezone from string
new_tz = pytz.timezone(new_timezone)
# convert starter to new datetime
new_dt = starter.astimezone(new_tz)
# Return new datetime object
return new_dt
The last two statement could be combined and return the new datetime
directly:
# Return new datetime object
return starter.astimezone(new_tz)
Of if you insist on approaching unreadable, you could do:
def to_timezone(new_timezone):
return starter.astimezone( pytz.timezone(new_timezone) )
![Chris White](https://secure.gravatar.com/avatar/7b2b8d32d620943bc90ef5d0399bd8f1?s=60&d=https%3A%2F%2Fecs-static.teamtreehouse.com%2Fassets%2Fcontent%2Fdefault_avatar-445fbbabfc8dc9188fb5967fe43322ee0c3e0dd1e10f378bf8343784af5a13eb.webp&r=pg)
Chris White
6,212 PointsThanks, that did the trick, and reading it makes total sense.
I'll really need to go back at some point and spend a lot more time here. Very frustrating stuff.
But a quick question: Why wouldn't it (or would it?) work to just skip creating new_dt and plug in the argument straight into the .astimezone part? If we assume the string is a timezone, why wouldn't it work to just say:
return starter.astimezone(string)?
![Chris Freeman](https://uploads.teamtreehouse.com/production/profile-photos/1153532/micro_image.jpg)
Chris Freeman
Treehouse Moderator 68,425 PointsChris White: While going straight to return starter.astimezone(string)
looks inviting, it definately will not work! Coding would be a breeze if it did. Why? it's all about type
.
Functions expect parameters of a specific object type: integer (int
), string ('str'), etc. Some functions take other functions (as callable object) as parameters!
The function pytz.timezone()
expects a string parameter and returns a timezone
object. Whereas, starter
is a "timzone aware" datetime
object with an astimezone()
method which expects a timezone
object and returns and updated datetime
object. Say THAT 10 times fast!
If you're unsure what is being produced by a statement, you can inspect the output using type()
and dir()
. Doing this on the above code yields this:
In [229]: import pytz
In [230]: import datetime
In [231]: starter = pytz.utc.localize(datetime.datetime(2015, 10, 21, 23, 29))
In [232]: new_tz = pytz.timezone('US/Eastern')
In [233]: type(new_tz)
Out[233]: pytz.tzfile.US/Eastern
In [234]: dir(new_tz)
Out[234]:
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_dst', '_transition_info', '_tzinfos', '_tzname', '_utc_transition_times', '_utcoffset', 'dst', 'fromutc', 'localize', 'normalize', 'tzname', 'utcoffset', 'zone']
In [235]: new_dt = starter.astimezone(new_tz)
In [236]: type(new_dt)
Out[236]: datetime.datetime
In [237]: dir(new_dt)
Out[237]:
['__add__', '__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'astimezone', 'combine', 'ctime', 'date', 'day', 'dst', 'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime', 'strptime', 'time', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year']
For grins, let's try calling starter.astimezone()
with a string argument:
In [238]: starter.astimezone('US/Eastern')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-238-d536f300de46> in <module>()
----> 1 starter.astimezone('US/Eastern')
TypeError: astimezone() argument 1 must be datetime.tzinfo, not str
As you can see, the astimezone()
method does not care for a string input.
Robert Richey
Courses Plus Student 16,352 PointsRobert Richey
Courses Plus Student 16,352 PointsHi Chris,
Just fixed the formatting to help make it more readable. I haven't yet gotten to this step in Python, but I'm not far behind. I'll keep an eye on this thread and when I reach a point I can answer it, I'll do so if no one else has. This could take days - because, learning timezones is like running through mud for me.