36

Is there a cross-platform function in python (or pytz) that returns a tzinfo object corresponding to the timezone currently set on the computer?

environment variables cannot be counted on as they are not cross-platform

random guy
  • 2,225
  • 6
  • 24
  • 24

8 Answers8

15
>>> import datetime
>>> today = datetime.datetime.now()
>>> insummer = datetime.datetime(2009,8,15,10,0,0)
>>> from pytz import reference
>>> localtime = reference.LocalTimezone()
>>> localtime.tzname(today)
'PST'
>>> localtime.tzname(insummer)
'PDT'
>>> 
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 6
    [`pytz` docs say that `pytz.reference`](http://pytz.sourceforge.net/#problems-with-localtime) should be used *only for tests*. – jfs Sep 02 '13 at 08:42
  • That warning applies to `reference.USTimeZone`, which uses the pre-2007 rules for US DST. However `reference.LocalTimezone`, used here, probes the behavior of `time.localtime`, whose correctness is maintained with the system libraries. `reference.LocalTimezone` gives the correct DST transitions both before and after the 2007 change in US rules; I haven't tested for other countries. – rob Nov 02 '14 at 23:39
  • 5
    @rob: **wrong**. Do not use `LocalTimezone()`. `pytz` provides *historical* timezone data while `time.timezone`, `time.altzone` (used by `LocalTimezone()`) are constants i.e., at best they reflect *the most recent* timezone definition. The local timezone may have different utc offsets in the past/future e.g., try Europe/Moscow timezone in 2010-2015 and see what happens for yourself. – jfs Dec 22 '14 at 03:22
  • @J.F.Sebastian From my understanding, that will only affect handling historic times or arithmetic. For my purposes I only need to know the local system offset from UTC to parse future timestamps from the system (e.g. syslogs), then convert to UTC right away. Would it be safe to use `LocalTimezone()` for that? – notbad.jpeg Jan 22 '16 at 21:03
  • @notbad.jpeg no. The future UTC offset may also change. – jfs Jan 23 '16 at 05:45
  • `pytz` is present on my system but there is no `pytz.reference` (Python 2.7.5 on Mac OSX 10.6) – Jason S Apr 02 '16 at 20:10
11

tzlocal module that returns pytz timezones works on *nix and win32:

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

# get local timezone    
local_tz = get_localzone() 


print local_tz.localize(datetime(2012, 1, 15))
# -> 2012-01-15 00:00:00+04:00 # current utc offset
print local_tz.localize(datetime(2000, 1, 15))
# -> 2000-01-15 00:00:00+03:00 # past utc offset (note: +03 instead of +04)
print local_tz.localize(datetime(2000, 6, 15))
# -> 2000-06-15 00:00:00+04:00 # changes to utc offset due to DST

Note: it takes into account both DST and non-DST utc offset changes.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
10

Python 3.7:

import datetime

datetime.datetime.now().astimezone().tzinfo
user1338062
  • 11,939
  • 3
  • 73
  • 67
5

time.timezone returns current timezone offset. there is also a datetime.tzinfo, if you need more complicated structure.

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
  • 1
    time.timezone() just returns the offset from UTC. i want a tzinfo object. so i would probably would what the function to: 1. define a class corresponding to the tzinfo object 2. instanciate the object 3. return it – random guy Nov 05 '09 at 15:21
  • `datetime` docs have an example that explains the use of `tzinfo`. – SilentGhost Nov 05 '09 at 15:26
  • 3
    `datetime.datetime.now() + datetime.timedelta(seconds=time.timezone)` did the trick nicely. – Baczek Feb 12 '13 at 09:10
  • 2
    @Baczek: `time.timezone` doesn't take into account DST. – jfs Sep 02 '13 at 08:46
4

This following code snippet returns time in a different timezone irrespective of the timezone configured on the server.

# pip install pytz tzlocal

from tzlocal import get_localzone
from datetime import datetime
from pytz import timezone

local_tz = get_localzone()
local_datetime = datetime.now(local_tz)

zurich_tz = timezone('Europe/Zurich')
zurich_datetime = zurich_tz.normalize(local_datetime.astimezone(zurich_tz))
Sandeep
  • 28,307
  • 3
  • 32
  • 24
  • 1
    is there a reason, not to use `zurich_datetime = datetime.now(timezone('Europe/Zurich'))` here? btw, [it is not necessary to call `.normalize()` after `.astimezone()`](https://answers.launchpad.net/pytz/+question/249229#6) – jfs May 02 '16 at 08:58
  • how do you get 'Europe/Zurich' programmatically? i have many machines and don't know what their tz string is – JDPeckham Mar 02 '20 at 17:07
1

I have not used it myself, but dateutil.tz.tzlocal() should do the trick.

http://labix.org/python-dateutil#head-50221b5226c3ccb97daa06ea7d9abf0533ec0310

  • `tzlocal()` might fail for dates from the past e.g., `'Europe/Moscow'` timezone had different utc offset before 2011 (`dateutil` fails, but `pytz` works for such timezones) – jfs Sep 02 '13 at 09:01
1

Maybe try:

import time

print time.tzname #or time.tzname[time.daylight]

Adi Inbar
  • 12,097
  • 13
  • 56
  • 69
Rain Lee
  • 511
  • 2
  • 6
  • 11
  • Compare this with the first answer, why -1? – Rain Lee Aug 29 '13 at 02:18
  • 1
    [`time.daylight`] says whether the current timezone has DST. It doesn't indicate whether DST is in effect right now. Also `time.tzname` is not a `tzinfo` instance (it is a string). See [How to get system timezone setting and pass it to pytz.timezone?](http://stackoverflow.com/q/13218506/4279) to understand that even if you would get the correct tzname; it won't mean that you would find the local timezone. See [Getting computer's utc offset in Python](http://stackoverflow.com/a/3168394/4279) that demonstrates several approaches to get the current utc offset. – jfs Dec 22 '14 at 03:40
-1

I was asking the same to myself, and I found the answer in [1]:

Take a look at section 8.1.7: the format "%z" (lowercase, the Z uppercase returns also the time zone, but not in the 4-digit format, but in the form of timezone abbreviations, like in [3]) of strftime returns the form "+/- 4DIGIT" that is standard in email headers (see section 3.3 of RFC 2822, see [2], which obsoletes the other ways of specifying the timezone for email headers).

So, if you want your timezone in this format, use:

time.strftime("%z")

[1] http://docs.python.org/2/library/datetime.html

[2] https://www.rfc-editor.org/rfc/rfc2822#section-3.3

[3] Timezone abbreviations: http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations , only for reference.

Community
  • 1
  • 1
David L
  • 1,058
  • 12
  • 9
  • It doesn't give `tzinfo` object. You could get the current utc offset for the local timezone as number of seconds: `-altzone if daylight and localtime().tm_isdst > 0 else -timezone` (all names are from `time` module). – jfs Dec 11 '13 at 03:51