471,602 Members | 1,296 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,602 software developers and data experts.

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

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
2 3546

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
> 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.

Similar topics

7 posts views Thread by Jim Davis | last post: by
3 posts views Thread by Kevin Kenny | last post: by
6 posts views Thread by Bijoy Naick | last post: by
11 posts views Thread by Rubic | last post: by
1 post views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by
reply views Thread by MichaelMortimer | last post: by
reply views Thread by CCCYYYY | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.