Reputation: 5582
My purpose is simply to output a time zone string like -0700 used in e-mail. Specifically, I want it to reflect the exact time zone, daylight saving included. This means I will get -0700 in California in summer, -0800 in California in winter, and always +0800 in China (no daylight saving).
I find it difficult for two reasons:
I ended up with code like the following. It is longer than I expected (esp. for Python!):
import math
import time
def my_divide(dividend, divisor):
if dividend < 0:
if divisor < 0:
diff_sign = False
else:
diff_sign = True
else:
if divisor >= 0:
diff_sign = False
else:
diff_sign = True
if diff_sign:
return (int(math.ceil(1.0 * dividend / divisor)), dividend % -divisor)
else:
return (int(math.floor(1.0 * dividend / divisor)), dividend % divisor)
def my_timezone():
gt = time.gmtime()
lt = time.localtime()
lt_write = list(lt)
lt_write[8] = 0 # is_dst
lt = time.struct_time(lt_write)
seconds = time.mktime(lt) - time.mktime(gt)
(hours, minutes) = my_divide(seconds, 3600)
minutes = abs(minutes) // 60
return '%(hours)+03d%(minutes)02d' % {'hours': hours, 'minutes': minutes}
Anybody having a better implementation?
Upvotes: 0
Views: 508
Reputation: 1122152
You can use the time.timezone
and time.altzone
values.
These provide:
The offset of the local (non-DST) timezone, in seconds west of UTC (negative in most of Western Europe, positive in the US, zero in the UK)
and
The offset of the local DST timezone, in seconds west of UTC, if one is defined. This is negative if the local DST timezone is east of UTC (as in Western Europe, including the UK). Only use this if
daylight
is nonzero.
As the documentation for time.altzone
explains, use the latter when time.daylight
is non-zero, but only if the current time is in summer time:
import time
def my_timezone():
is_dst = time.daylight and time.localtime().tm_isdst
offset = time.altzone if is_dst else time.timezone
westerly = offset > 0
minutes, seconds = divmod(abs(offset), 60)
hours, minutes = divmod(minutes, 60)
return '{}{:02d}{:02d}'.format('-' if westerly else '+', hours, minutes)
Using seconds as a base and divmod()
there should be no rounding errors here.
For my British summertime location, that gives:
>>> my_timezone()
'+0100'
Upvotes: 2