The function below is designed to return a UTC offset string, in the form used widely by timestamps, of the user's current time for when only naive date time objects are available (no time zone information).
I've tested it on two systems, which are in different time zones, and it works perfectly. However I'd like confirmation that it will work on all systems running Python versions>= 2.6. Can anyone see any potential problems?
Note: The function will only ever be used with the user's current time and so present or past dates and times are not an issue.
import time
from datetime import datetime
def get_utc_offset_str():
"""
Returns a UTC offset string of the current time suitable for use in the
most widely used timestamps (i.e. ISO 8601, RFC 3339). For example:
10 hours ahead, 5 hours behind, and time is UTC: +10:00, -05:00, +00:00
"""
# Calculate the UTC time difference in seconds.
timestamp = time.time()
time_now = datetime.fromtimestamp(timestamp)
time_utc = datetime.utcfromtimestamp(timestamp)
utc_offset_secs = (time_now - time_utc).total_seconds()
# Flag variable to hold if the current time is behind UTC.
is_behind_utc = False
# If the current time is behind UTC convert the offset
# seconds to a positive value and set the flag variable.
if utc_offset_secs < 0:
is_behind_utc = True
utc_offset_secs *= -1
# Build a UTC offset string suitable for use in a timestamp.
if is_behind_utc:
pos_neg_prefix = "-"
else:
pos_neg_prefix = "+"
utc_offset = time.gmtime(utc_offset_secs)
utc_offset_fmt = time.strftime("%H:%M", utc_offset)
utc_offset_str = pos_neg_prefix + utc_offset_fmt
return utc_offset_str
-
2\$\begingroup\$ Times with no time zone specified are often called "floating" times. \$\endgroup\$200_success– 200_success2016年06月01日 16:29:48 +00:00Commented Jun 1, 2016 at 16:29
-
\$\begingroup\$ Thanks. The Python documentation differentiates between objects that 'know' about time zones and those that do not by calling them aware and naive respectively. \$\endgroup\$mattst– mattst2016年06月01日 16:37:23 +00:00Commented Jun 1, 2016 at 16:37
1 Answer 1
Take advantage of Python operator overloading
is_behind_utc = time_now < time_utc
If the current time is less the the UTC time then we are behind UTC time.
There is no need to use logic concerning seconds.
Longer names> comments
# Flag variable to hold if the current time is behind UTC.
is_behind_utc = False
Let's analyze the comment:
Flag variable
: this can easily be deduced as it is a booleanto hold if
: each variable holds somethingthe current time
: valuable informationis behind UTC
: already present in the variable name
So I could write:
current_time_is_behind_utc = time_now < time_utc
The name incorporates the valuable information in the comment, avoids the unnecessary and the repetition of the same concept.
Use ternary when sensible
if is_behind_utc:
pos_neg_prefix = "-"
else:
pos_neg_prefix = "+"
I cringe because such verbosity obscures what is simple:
pos_neg_prefix = '-' if current_time_is_behind_utc else '+'
Simplify avoiding too many variables
utc_offset_fmt = time.strftime("%H:%M", utc_offset)
utc_offset_str = pos_neg_prefix + utc_offset_fmt
return utc_offset_str
Can simply be:
return pos_neg_prefix + time.strftime("%H:%M", utc_offset)
I think that each additional variable is an addition burden and point of failure in the code being another layer of indirection, and tend to avoid too many variables when sensible.
-
\$\begingroup\$ Thanks for your comments. You said there is no need to use the logic concerning seconds, but it is needed for the all important call to
time.gmtime(utc_offset_secs)
. I've never liked the Python ternary operator, so almost never use it, nothing wrong with the conditional IMO. My reason for posting was to find out if the way I'm getting the UTC offset will work on all systems running Python versions >= 2.6, as clearly stated in my post, you make no mention of this and just give a critique of my code! \$\endgroup\$mattst– mattst2016年06月01日 21:10:04 +00:00Commented Jun 1, 2016 at 21:10 -
1\$\begingroup\$ @mattst It works for me in Ubuntu 14.04 Python 3.4 \$\endgroup\$Caridorc– Caridorc2016年06月01日 22:22:59 +00:00Commented Jun 1, 2016 at 22:22