Python: How do you convert datetime/timestamp from

2019-01-18 05:03发布

问题:

Specifically, given the timezone of my server (system time perspective) and a timezone input, how do I calculate the system time as if it were in that new timezone (regardless of daylight savings, etc)?

import datetime
current_time = datetime.datetime.now() #system time

server_timezone = "US/Eastern"
new_timezone = "US/Pacific"

current_time_in_new_timezone = ???

回答1:

If you know your origin timezone and the new timezone you want to convert it to, first use pytz.localize to handle any localization (e.g. for daylight savings, etc), then use pytz.timezone to create timezone objects, and finally use datetime.astimezone(timezone) for an easy calculation. For example:

import datetime
import pytz # new import

my_timestamp = datetime.datetime.now() # some timestamp
old_timezone = pytz.timezone("US/Eastern")
new_timezone = pytz.timezone("US/Pacific")

# returns datetime in the new timezone
my_timestamp_in_new_timezone = old_timezone.localize(my_timestamp).astimezone(new_timezone) 

And of course, if all you want is the current time in a specific timezone, you can pass that timezone directly into datetime.now() to get the timestamp. Like this:

datetime.datetime.now(new_timezone)

Now with all that said, I strongly recommend storing all your timestamps in UTC as a system standard, and avoid the whole DST problem. For context on this, see: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/

And to know how difficult it is to deal with time calculations in general: http://yourcalendricalfallacyis.com



回答2:

How do you convert datetime/timestamp from one timezone to another timezone?

There are two steps:

  1. Create an aware datetime objects from the system time and timezone e.g., to get the current system time in the given timezone:

    #!/usr/bin/env python
    from datetime import datetime
    import pytz
    
    server_timezone = pytz.timezone("US/Eastern")
    server_time = datetime.now(server_timezone) # you could pass *tz* directly
    

    Note: datetime.now(server_timezone) works even during ambiguous times e.g., during DST transitions while server_timezone.localize(datetime.now()) may fail (50% chance).

    If you are sure that your input time exists in the server's timezone and it is unique then you could pass is_dst=None to assert that:

    server_time = server_timezone.localize(naive_time, is_dst=None)
    

    It raises an exception for invalid times.
    If it is acceptable to ignore upto a day error (though typically an error due to DST is around an hour) then you could drop is_dst parameter:

    server_time = server_timezone.normalize(server_timezone.localize(naive_time))
    

    .normalize() is called to adjust non-existing times (local time in the gap, during "spring forward" transitions). If the time zone rules haven't changed; your server shouldn't generate non-existing times. See "Can I just always set is_dst=True?"

  2. Convert an aware datetime object to the target timezone tz:

    tz = pytz.timezone("US/Pacific")
    server_time_in_new_timezone = server_time.astimezone(tz)