By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,965 Members | 1,631 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,965 IT Pros & Developers. It's quick & easy.

Timezone and ISO8601 struggles with datetime and xml.utils.iso8601.parse

P: n/a
Hello,

I am trying to convert a local time into UTC ISO8601, then parse it
back into local time. I tried the following:

----------------------
#!/usr/bin/python
import time
import datetime
import xml.utils.iso8601

year = 2005
month = 7
day = 22
hour = 10 # This is localtime
minute = 30

mydatetime = datetime.datetime(year, month, day, hour, minute)
strtime = mydatetime.isoformat()

print "Time: " + strtime # Localtime too
mytimestamp = xml.utils.iso8601.parse(strtime)
----------------------

How can I convert this into UTC? Commonsense would have me guess that
the date is converted into UTC on construction of the datetime object,
hovever, this doesn't seem to be the case. I also found the
astimezone(tz) method, but where can I obtain the concrete tz object?

The second problem has to do with the ISO8601 parser, which raises the
following error:

----------------------
Traceback (most recent call last):
File "./timetest.py", line 16, in ?
mytimestamp = xml.utils.iso8601.parse(strtime)
File "/usr/lib/python2.4/site-packages/_xmlplus/utils/iso8601.py",
line 22, in parse
raise ValueError, "unknown or illegal ISO-8601 date format: " + `s`
ValueError: unknown or illegal ISO-8601 date format:
'2005-07-22T10:30:00'
----------------------

Why does it fail to parse the value returned by the datetime object,
and how can I create a parseable time from the datetime object?

Thanks,
-Samuel

Sep 9 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a

Samuel> mydatetime = datetime.datetime(year, month, day, hour, minute)
Samuel> strtime = mydatetime.isoformat()

Take a look at the utcoffset method of datetime objects.

Samuel> The second problem has to do with the ISO8601 parser, which
Samuel> raises the following error:

Samuel> ----------------------
Samuel> Traceback (most recent call last):
Samuel> File "./timetest.py", line 16, in ?
Samuel> mytimestamp = xml.utils.iso8601.parse(strtime)
Samuel> File "/usr/lib/python2.4/site-packages/_xmlplus/utils/iso8601.py",
Samuel> line 22, in parse
Samuel> raise ValueError, "unknown or illegal ISO-8601 date format: " + `s`
Samuel> ValueError: unknown or illegal ISO-8601 date format:
Samuel> '2005-07-22T10:30:00'
Samuel> ----------------------

Samuel> Why does it fail to parse the value returned by the datetime
Samuel> object, and how can I create a parseable time from the datetime
Samuel> object?

One possibility might be that datetime objects stringify with microseconds
included:
t = datetime.datetime.now()
t datetime.datetime(2005, 9, 9, 12, 52, 38, 677120) strtime = t.isoformat()
strtime '2005-09-09T12:52:38.677120'

You can try stripping the microseconds first:
time.strptime(strtime, "%Y-%m-%dT%H:%M:%S") Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/Users/skip/local/lib/python2.5/_strptime.py", line 295, in strptime
raise ValueError("unconverted data remains: %s" %
ValueError: unconverted data remains: .677120 time.strptime(strtime.split(".")[0], "%Y-%m-%dT%H:%M:%S")

(2005, 9, 9, 12, 52, 38, 4, 252, -1)

Skip
Sep 9 '05 #2

P: n/a
> Take a look at the utcoffset method of datetime objects.

This returns 0.
However, meanwhile I figured out a way to do this:

Every datetime object by default does not handle timezones at all, and
as such "isoformat" does not return an offset in the ISO8601 string.
The only way around this appears to be passing the tzinfo to the
constructor every time (datetime.tzinfo is not writeable). I am not
aware of a python-provided implementation for a conrete tzinfo, so I
copied this code:

------------------------------------
from datetime import *
import time as _time

STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
DSTOFFSET = STDOFFSET

DSTDIFF = DSTOFFSET - STDOFFSET

class LocalTimezone(tzinfo):
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET

def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO

def tzname(self, dt):
return _time.tzname[self._isdst(dt)]

def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, -1)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
------------------------------------

from the Python documentation into my program. (I am sure there must be
a better way to do this though.) Then, when passing the
tz.LocalTimezone instance to datetime, isoformat() returns the string
with an offset appended (e.g. +02:00).
The resulting string can then also successfully be parsed with
xml.utils.iso8601.parse().

Thanks for your help!

-Samuel

Sep 9 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.