6

There are a ton of questions about UTC datetime conversions and there doesn't seems to be a consensus of a "best way".

According to this: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ , pytz is the best way to go. he shows converting to timezone like this datetime.datetime.utcnow().replace(tzinfo=pytz.utc) but he doesn't say how to get the user's timezone...

This guy https://stackoverflow.com/a/7465359/523051 says "localize adjusts for Daylight Savings Time, replace does not"

Everyone I see using pytz is supplying their own timezone (users_timezone = timezone("US/Pacific")), which I don't understand because you can't know if that's where your viewer is...

This guy https://stackoverflow.com/a/4771733/523051 has a way to auto-detect the timezones, but this is using the dateutil library, and not pytz, as is recommended by both Armin Ronacher and the official python docs ( http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior , just above that anchor in yellow box)

All I need is the most simplest, future-proof, all daylight savings time/etc considered way to take my datetime.utcnow() stamp (2012-08-25 10:59:56.511479), convert it the user's timezone. And show it like this:

Aug 25 - 10:59AM

and if the year is not the current year, I'd like to say

Aug 25 '11 - 10:59AM
Community
  • 1
  • 1
chrickso
  • 2,994
  • 5
  • 30
  • 53

1 Answers1

4

alright, here it is (also, my first contribution to SO :))

it does require 2 external libraries which may throw some off...

from datetime import datetime
from dateutil import tz
import pytz

def standard_date(dt):
    """Takes a naive datetime stamp, tests if time ago is > than 1 year,
       determines user's local timezone, outputs stamp formatted and at local time."""

    # determine difference between now and stamp
    now = datetime.utcnow()
    diff = now - dt

    # show year in formatting if date is not this year
    if (diff.days / 365) >= 1:
        fmt = "%b %d '%y @ %I:%M%p"
    else:
        fmt = '%b %d @ %I:%M%p'   

    # get users local timezone from the dateutils library
    # http://stackoverflow.com/a/4771733/523051
    users_tz = tz.tzlocal()

    # give the naive stamp timezone info
    utc_dt = dt.replace(tzinfo=pytz.utc)
    # convert from utc to local time
    loc_dt = utc_dt.astimezone(users_tz)
    # apply formatting
    f = loc_dt.strftime(fmt)

    return f
chrickso
  • 2,994
  • 5
  • 30
  • 53
  • I have learned that the tzlocal() does not work at all on heroku. the above function simply returns UTC time. – chrickso Aug 26 '12 at 11:40
  • also note, i have lost all hope that their is a reliable way to accurately determine a user's timezone and adjust times automatically. i see that twitter has a setting to adjust your timezone so this must be the way: store user's preference and use that for conversions. – chrickso Aug 26 '12 at 11:42