datetime iso8601 string input

R

Rubic

I was a little surprised to recently discover
that datetime has no method to input a string
value. PEP 321 appears does not convey much
information, but a timbot post from a couple
years ago clarifies things:

http://tinyurl.com/epjqc
You can stop looking: datetime doesn't
support any kind of conversion from string.
The number of bottomless pits in any datetime
module is unbounded, and Guido declared this
particular pit out-of-bounds at the start so
that there was a fighting chance to get
*anything* done for 2.3.

I can understand why datetime can't handle
arbitrary string inputs, but why not just
simple iso8601 format -- i.e. the default
output format for datetime?

Given a datetime-generated string:
'2006-02-23 11:03:36.762172'

Why can't we have a function to accept it
as string input and return a datetime object?

datetime.parse_iso8601(now)

Jeff Bauer
Rubicon, Inc.
 
M

Magnus Lycka

Rubic said:
I can understand why datetime can't handle
arbitrary string inputs, but why not just
simple iso8601 format -- i.e. the default
output format for datetime?

Have you actually read the ISO 8601 standard?
If you have, you would know that parsing valid
ISO 8601 is fairly close to handling arbitrary
strings...

I suspect this absence is quite deliberate.

There are so many possible string formats that
are used and prefered in different situations,
and various loop holes with time zones and DST
etc, that it's probably better to let the
programmer take full responsibility over this
instead of providing a 10% solution.

ater all, it isn't very hard to use for instance
time.strptime() with some appropriate format,
and build datetime objects from that. Then
the programmer is in control.
 
R

Rubic

Magnus,

Thanks for your reply. I wasn't clear in my
prior post. Rather than support the entire
range of iso8601 formats, how about *just* the
format that datetime emits? Call it the
parse_datetime() function. Then it would be
possible to take the output string of a datetime
object and read it back in to round-trip the
data.
datetime.datetime(2006, 2, 24, 6, 58, 23, 737586)

Jeff Bauer
Rubicon, Inc.
 
P

Peter Hansen

Rubic said:
Thanks for your reply. I wasn't clear in my
prior post. Rather than support the entire
range of iso8601 formats, how about *just* the
format that datetime emits? Call it the
parse_datetime() function. Then it would be
possible to take the output string of a datetime
object and read it back in to round-trip the
data.

datetime.datetime(2006, 2, 24, 6, 58, 23, 737586)

Jeff Bauer
Rubicon, Inc.

If that's truly all you want, then it's a near trivial function to
write. One of those "throw-away" functions you tend to whip up a few
dozen times on every project, hardly noticing because you're using
Python and it's so easy to do.

-Peter
 
R

Rubic

Yeah, it's a trivial function that's rewritten for each new project
that passes datetime objects as strings <0.2 wink>. On the basis of it
being a trivial convenience, I could propose removing hundreds of
"redundant" functions from the library. ;-)

Never mind. I'll drop it.

Jeff Bauer
Rubicon, Inc.
 
M

Magnus Lycka

Rubic said:
Yeah, it's a trivial function that's rewritten for each new project
that passes datetime objects as strings <0.2 wink>. On the basis of it
being a trivial convenience, I could propose removing hundreds of
"redundant" functions from the library. ;-)

I think the big issue is that it solves such a microscopic part
of the convert-strings-to-datetimes problem. Believe me, I know,
I'm writing parsers for IATA timetable data now. There is a
distinct smell of punch cards, telex machines and handwritten
forms in this standard... Like writing 112233 instead of 2006-
02-11 22:33, and let the parser guess month and year from context.

If I have gotten a time into a datetime object I'll keep it there
if I'm in control. If I'm not in control, I'd be very lucky if
the string replresentation was in the One True Format.

Since I feel that the datetime module largely replaces the
older time module, I'd really like to see a strptime in the
datetime module though. Then I guess I could often drop use of
the old time module. (If it wasn't for the sad fact that we need
to support Python 2.2 a little longer...)
 
A

aurora

I agree. I just keep rewriting the parse method again and again.

wy

def parse_iso8601_date(s):
""" Parse date in iso8601 format e.g. 2003-09-15T10:34:54 and
returns a datetime object.
"""
y=m=d=hh=mm=ss=0
if len(s) not in [10,19,20]:
raise ValueError('Invalid timestamp length - "%s"' % s)
if s[4] != '-' or s[7] != '-':
raise ValueError('Invalid separators - "%s"' % s)
if len(s) > 10 and (s[13] != ':' or s[16] != ':'):
raise ValueError('Invalid separators - "%s"' % s)
try:
y = int(s[0:4])
m = int(s[5:7])
d = int(s[8:10])
if len(s) >= 19:
hh = int(s[11:13])
mm = int(s[14:16])
ss = int(s[17:19])
except Exception, e:
raise ValueError('Invalid timestamp - "%s": %s' % (s, str(e)))
return datetime(y,m,d,hh,mm,ss)
 
S

Sybren Stuvel

aurora enlightened us with:
I agree. I just keep rewriting the parse method again and again.

I just use the parser from mx.DateTime. Works like a charm, and can
even guess the used format.

Sybren
 
S

skip

aurora> I agree. I just keep rewriting the parse method again and again.

aurora> def parse_iso8601_date(s):
aurora> """ Parse date in iso8601 format e.g. 2003-09-15T10:34:54 and
aurora> returns a datetime object.
aurora> """
...

Why not

dt = datetime.datetime(*time.strptime(s, "%Y-%m-%dT%H:%M:%S")[0:6])

?

Skip
 
M

Magnus Lycka

Why not

dt = datetime.datetime(*time.strptime(s, "%Y-%m-%dT%H:%M:%S")[0:6])

?

Maybe due to neglection of the 7th commandment?
Most of the other commandments can be ignored while
coding Python, but the 7th certainly applies here.

http://www.lysator.liu.se/c/ten-commandments.html

As I've written before, the ISO 8601 spec contains
many variations in date formats. Making a full ISO
8601 parser is probably possible if we ignore time
deltas, but it's hardly worth the effort. Writing
something that parses a few percent of the possible
ISO 8601 messages and calling that an ISO 8601
parser seems silly to me.

With code like Skip's above it's obvious what kind
of strings are handled. In typical applications, one
such format is enough, and this needs to be properly
specified. In a recent case I wrote the spec like
this:

"The timestamp shall be an ISO 8601 combination of
UTC date and time with complete representation in
extended format, with representation of fractions
of seconds with up to six decimals preceeded by a
full stop as decimal sign.
E.g. 2005-06-20T13:42:55.2425Z"

Despite my verbosity here, someone who didn't follow
the example, would still be able to write ISO 8601
strings following the requirements above that we
won't parse, since I didn't actually write that dates
should be written as year-month-day.

For a brief summary of some of the allowed variation
see http://hydracen.com/dx/iso8601.htm
 
B

Ben Finney

Magnus Lycka said:
As I've written before, the ISO 8601 spec contains many variations
in date formats. Making a full ISO 8601 parser is probably possible
if we ignore time deltas, but it's hardly worth the effort. Writing
something that parses a few percent of the possible ISO 8601
messages and calling that an ISO 8601 parser seems silly to me.

The abundance of formats specified by ISO 8601 is indeed a barrier to
simple implementation of ISO-8601-consuming methods.

In response to this, the IETF have made RFC 3339:

"This document defines a date and time format for use in Internet
protocols that is a profile of the ISO 8601 standard for
representation of dates and times using the Gregorian calendar."
<URL:http://www.ietf.org/rfc/rfc3339.txt>

By "profile", the document essentially means a much more limited
subset of the myriad formats in ISO 8601, precisely to allow simple
conversion of timestamps to and from the format.

Could this be a candidate for a "default" consumption format for
date-time strings?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top