How to create tzinfo when I have UTC offset?
If you can, take a look at the excellent dateutil package instead of implementing this yourself.
Specifically, tzoffset. It's a fixed offset tzinfo
instance initialized with offset
, given in seconds, which is what you're looking for.
Update
Here's an example. Be sure to run pip install python-dateutil
first.
from datetime import datetime
from dateutil import tz
# First create the tzinfo object
tzlocal = tz.tzoffset('IST', 19800)
# Now add it to a naive datetime
local = naive.replace(tzinfo=tzlocal)
# Or convert another timezone to it
utcnow = datetime.utcnow().replace(tzinfo=tz.tzutc())
now = utcnow.astimezone(tzlocal)
I looked up the name IST
from here. The name can really be anything. Just be careful if you deviate, since if you use code that relies on the name, it could lead to bugs later on.
By the way, if you have the timezone name upfront, and your operating system supports it, you can use gettz instead:
# Replace the above with this
tzlocal = tz.gettz('IST')
With Python 3.2 or higher, you can do this using the builtin datetime library:
import datetime
datetime.timezone(-datetime.timedelta(hours=5, minutes=30)
To solve your specific problem, you could use regex:
sign, hours, minutes = re.match('([+\-]?)(\d{2})(\d{2})', '+0530').groups()
sign = -1 if sign == '-' else 1
hours, minutes = int(hours), int(minute)
tzinfo = datetime.timezone(sign * datetime.timedelta(hours=hours, minutes=minutes))
datetime.datetime(2013, 2, 3, 9, 45, tzinfo=tzinfo)
Python Standard Library (8.1.6) says that :
- tzinfo is an abstract base class
- the datetime module does not supply any concrete subclasses of tzinfo
- you need to derive a concrete subclass, and (at least) supply implementations of the standard tzinfo methods needed by the datetime methods you use
-
a concrete subclass of tzinfo may need to implement the following methods ... If in doubt, simply implement all of them
- tzinfo.utcoffset(self, dt) : return offset of local time from UTC, in minutes east of UTC
- tzinfo.dst(self, dt) : return the daylight saving time (DST) adjustment, in minutes east of UTC, or None if DST information isn’t known
- tzinfo.tzname(self, dt) : return the time zone name corresponding to the datetime object dt, as a string
All that means that you will have to provide your own implementation for the tzinfo. For example :
class UTC0530(datetime.tzinfo):
"""tzinfo derived concrete class named "+0530" with offset of 19800"""
# can be configured here
_offset = datetime.timedelta(seconds = 19800)
_dst = datetime.timedelta(0)
_name = "+0530"
def utcoffset(self, dt):
return self.__class__._offset
def dst(self, dt):
return self.__class__._dst
def tzname(self, dt):
return self.__class__._name
Usage :
tz = UTC0530()
d = datetime.datetime.now(tz)
d.isoformat()
output :
2015-01-27T20:19:41.257000+05:30
You have to implement subclass of datetime.tzinfo
class. General guide is described here, where you also can find excellent examples of custom tzinfo implementations.
Here is example (given that there is no daylight saving time) :
from datetime import tzinfo, timedelta, datetime
from pytz import UTC
class MyUTCOffsetTimezone (tzinfo):
def __init__(self, offset=19800, name=None):
self.offset = timedelta(seconds=offset)
self.name = name or self.__class__.__name__
def utcoffset(self, dt):
return self.offset
def tzname(self, dt):
return self.name
def dst(self, dt):
return timedelta(0)
now = datetime.now(tz=UTC)
print now
# -> 2015-01-28 10:46:42.256841+00:00
print now.astimezone(MyUTCOffsetTimezone())
# -> 2015-01-28 16:16:42.256841+05:30
print datetime.now(MyUTCOffsetTimezone())
# -> 2015-01-28 16:16:42.256915+05:30