Paul
Paul

Reputation: 4430

Getting computer's UTC offset in Python

In Python, how do you find what UTC time offset the computer is set to?

Upvotes: 77

Views: 73094

Answers (10)

jfs
jfs

Reputation: 414139

time.timezone:

import time

print -time.timezone

It prints UTC offset in seconds (to take into account Daylight Saving Time (DST) see time.altzone:

is_dst = time.daylight and time.localtime().tm_isdst > 0
utc_offset = - (time.altzone if is_dst else time.timezone)

where utc offset is defined via: "To get local time, add utc offset to utc time."

In Python 3.3+ there is tm_gmtoff attribute if underlying C library supports it:

utc_offset = time.localtime().tm_gmtoff

Note: time.daylight may give a wrong result in some edge cases.

tm_gmtoff is used automatically by datetime if it is available on Python 3.3+:

from datetime import datetime, timedelta, timezone

d = datetime.now(timezone.utc).astimezone()
utc_offset = d.utcoffset() // timedelta(seconds=1)

To get the current UTC offset in a way that workarounds the time.daylight issue and that works even if tm_gmtoff is not available, @jts's suggestion to substruct the local and UTC time can be used:

import time
from datetime import datetime

ts = time.time()
utc_offset = (datetime.fromtimestamp(ts) -
              datetime.utcfromtimestamp(ts)).total_seconds()

To get UTC offset for past/future dates, pytz / zoneinfo timezones could be used:

from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal

tz = get_localzone() # local timezone 
d = datetime.now(tz) # or some other local date 
utc_offset = d.utcoffset().total_seconds()

It works during DST transitions, it works for past/future dates even if the local timezone had different UTC offset at the time e.g., Europe/Moscow timezone in 2010-2015 period.

Upvotes: 111

fontoura
fontoura

Reputation: 1

What did the trick for me was doing:

timezone_offset = (datetime.now(tz(DESIRED_TIMEZONE)).utcoffset().total_seconds()) / 3600

This way, I'm able to get the utc offset of an arbitrary timezone not only the machine's timezone(which can be a VM with a misconfigured timezone)

Upvotes: 0

HelloGoodbye
HelloGoodbye

Reputation: 3902

You can use the datetime and dateutil libraries to get the offset as a timedelta object:

>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>>
>>> # From a datetime object
>>> current_time = datetime.now(tzlocal())
>>> current_time.utcoffset()
datetime.timedelta(seconds=7200)
>>> current_time.dst()
datetime.timedelta(seconds=3600)
>>>
>>> # From a tzlocal object
>>> time_zone = tzlocal()
>>> time_zone.utcoffset(datetime.now())
datetime.timedelta(seconds=7200)
>>> time_zone.dst(datetime.now())
datetime.timedelta(seconds=3600)
>>>
>>> print('Your UTC offset is {:+g}'.format(current_time.utcoffset().total_seconds()/3600))
Your UTC offset is +2

Upvotes: 3

Data-phile
Data-phile

Reputation: 349

the time module has a timezone offset, given as an integer in "seconds west of UTC"

import time
time.timezone

Upvotes: 3

jts
jts

Reputation: 1329

gmtime() will return the UTC time and localtime() will return the local time so subtracting the two should give you the utc offset.

From https://pubs.opengroup.org/onlinepubs/009695399/functions/gmtime.html

The gmtime() function shall convert the time in seconds since the Epoch pointed to by timer into a broken-down time, expressed as Coordinated Universal Time (UTC).

So, despite the name gmttime, the function returns UTC.

Upvotes: 35

Tilek
Tilek

Reputation: 636

hours_delta = (time.mktime(time.localtime()) - time.mktime(time.gmtime())) / 60 / 60

Upvotes: 1

Stephen Blum
Stephen Blum

Reputation: 6834

Create a Unix Timestamp with UTC Corrected Timezone

This simple function will make it easy for you to get the current time from a MySQL/PostgreSQL database date object.

def timestamp(date='2018-05-01'):
    return int(time.mktime(
        datetime.datetime.strptime( date, "%Y-%m-%d" ).timetuple()
    )) + int(time.strftime('%z')) * 6 * 6

Example Output

>>> timestamp('2018-05-01')
1525132800
>>> timestamp('2018-06-01')
1527811200

Upvotes: 0

Alecs
Alecs

Reputation: 2930

This works for me:

if time.daylight > 0:
        return time.altzone
    else:
        return time.timezone

Upvotes: -4

toppk
toppk

Reputation: 700

Here is some python3 code with just datetime and time as imports. HTH

>>> from datetime import datetime
>>> import time
>>> def date2iso(thedate):
...     strdate = thedate.strftime("%Y-%m-%dT%H:%M:%S")
...     minute = (time.localtime().tm_gmtoff / 60) % 60
...     hour = ((time.localtime().tm_gmtoff / 60) - minute) / 60
...     utcoffset = "%.2d%.2d" %(hour, minute)
...     if utcoffset[0] != '-':
...         utcoffset = '+' + utcoffset
...     return strdate + utcoffset
... 
>>> date2iso(datetime.fromtimestamp(time.time()))
'2015-04-06T23:56:30-0400'

Upvotes: -1

dstromberg
dstromberg

Reputation: 7167

I like:

>>> strftime('%z')
'-0700'

I tried JTS' answer first, but it gave me the wrong result. I'm in -0700 now, but it was saying I was in -0800. But I had to do some conversion before I could get something I could subtract, so maybe the answer was more incomplete than incorrect.

Upvotes: 6

Related Questions