classification
Title: Add timespec optional flag to datetime isoformat() to choose the precision
Type: enhancement Stage: resolved
Components: Extension Modules Versions: Python 3.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: belopolsky Nosy List: acucci, belopolsky, berker.peksag, cvrebert, ezio.melotti, gvanrossum, haypo, jerry.elmore, lemburg, martin.panter, matrixise, python-dev, terry.reedy, tim.peters
Priority: normal Keywords: easy, patch

Created on 2013-11-01 17:05 by skip.montanaro, last changed 2016-03-06 19:58 by python-dev. This issue is now closed.

Files
File name Uploaded Description Edit
issue19475.patch acucci, 2015-07-25 14:12 Patch review
issue19475_v2.patch acucci, 2015-07-25 23:46 Patch review
issue19475_v3.patch acucci, 2015-08-03 19:46 Patch review
issue19475_v4.patch acucci, 2015-12-16 21:47 Patch v4 review
issue19475_v5.patch acucci, 2015-12-20 12:25 Patch v5 review
issue19475_v6.patch acucci, 2015-12-21 22:33 Patch v6 review
issue19475_v7.patch acucci, 2015-12-22 18:44 Patch v7 review
issue19475_v8.patch acucci, 2015-12-22 19:25 Patch v8 review
issue19475_v9.patch acucci, 2015-12-22 20:53 Patch v9 review
issue19475_v10_datetime_time.patch acucci, 2015-12-25 14:26 added timespec to time.isoformat review
issue19475_v11.patch acucci, 2015-12-29 18:44 Patch v11 review
issue19475_v12.patch acucci, 2016-01-01 12:50 review
issue19475_v13.patch acucci, 2016-02-21 18:20 added milliseconds format to timespec review
issue19475_v14.patch acucci, 2016-02-21 21:58 added milliseconds to documentation review
issue19475_v15.patch acucci, 2016-02-22 18:15 review
issue19475_v16.patch acucci, 2016-02-25 18:15 review
issue19475_v17.patch acucci, 2016-03-02 18:19 review
Messages (94)
msg201917 - (view) Author: Skip Montanaro (skip.montanaro) * Date: 2013-11-01 17:05
I have a CSV file. Here are a few rows:

"2013-10-30 14:26:46.000528","1.36097023829"
"2013-10-30 14:26:46.999755","1.36097023829"
"2013-10-30 14:26:47.999308","1.36097023829"
"2013-10-30 14:26:49.002472","1.36097023829"
"2013-10-30 14:26:50","1.36097023829"
"2013-10-30 14:26:51.000549","1.36097023829"
"2013-10-30 14:26:51.999315","1.36097023829"
"2013-10-30 14:26:52.999703","1.36097023829"
"2013-10-30 14:26:53.999640","1.36097023829"
"2013-10-30 14:26:54.999139","1.36097023829"

I want to parse the strings in the first column as timestamps. I can, and often do, use dateutil.parser.parse(), but in situations like this where all the timestamps are of the same format, it can be incredibly slow. OTOH, there is no single format I can pass to datetime.datetime.strptime() that will parse all the above timestamps. Using "%Y-%m-%d %H:%M:%S" I get errors about the leftover microseconds. Using "%Y-%m-%d %H:%M:%S".%f" I get errors when I try to parse a timestamp which doesn't have microseconds.

Alas, it is datetime itself which is to blame for this problem. The above timestamps were all printed from an earlier Python program which just dumps the str() of a datetime object to its output CSV file. Consider:

>>> dt = dateutil.parser.parse("2013-10-30 14:26:50")
>>> print dt
2013-10-30 14:26:50
>>> dt2 = dateutil.parser.parse("2013-10-30 14:26:51.000549")
>>> print dt2
2013-10-30 14:26:51.000549

The same holds for isoformat():

>>> print dt.isoformat()
2013-10-30T14:26:50
>>> print dt2.isoformat()
2013-10-30T14:26:51.000549

Whatever happened to "be strict in what you send, but generous in what you receive"? If strptime() is going to complain the way it does, then str() should always generate a full timestamp, including microseconds. The above is from a Python 2.7 session, but I also confirmed that Python 3.3 behaves the same.

I've checked 2.7 and 3.3 in the Versions list, but I don't think it can be fixed there. Can the __str__ and isoformat methods of datetime (and time) objects be modified for 3.4 to always include the microseconds? Alternatively, can the %S format character be modified to consume optional decimal point and microseconds? I rate this as "easy" considering the easiest fix is to modify __str__ and isoformat, which seems unchallenging.
msg201918 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2013-11-01 17:08
See #7342.
msg201922 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-11-01 17:47
It may be simple but as Ezio has pointed out, it has already been rejected :)

The problem with being generous in what you accept in this context is that the parsing is using a specific format string, and the semantics of that format string are based on external "standards" and are pretty inflexible.

The pythonic solution, IMO, is to have datetime's constructor accept what its str produces.  And indeed, exactly this has been suggested by Alexander Belopolsky in issue 15873. So I'm going to close this one as a duplicate of that one.
msg201924 - (view) Author: Skip Montanaro (skip.montanaro) * Date: 2013-11-01 17:55
I don't accept your conclusion. I understand that making %S consume microseconds or ".%f" be "optional" would be a load. What's the problem with forcing __str__ and isoformat to emit microseconds in all cases though? That would allow you to parse what they produce using existing code. No new constructor needed.

The issue of sometimes emitting microseconds, sometimes not, is annoying, even beyond this issue. I think for consistency's sake it makes sense for the string version of datetime and time objects to always be the same length.
msg201925 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-11-01 18:01
It's not my conclusion.  It's Guido's and the other developers who designed datetime.  Argue with them.  (I'd guess it would be better argued on python-ideas rather than python-dev, but use your own judgement.)
msg201926 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2013-11-01 18:07
The decision to omit microseconds when 0 was a Guido pronouncement, back when datetime was first written.  The idea is that str() is supposed to be friendly, and for the vast number of applications that don't use microseconds at all, it's unfriendly to shove ".000000" in their face all the time.  Much the same reason is behind why, e.g., str(2.0) doesn't produce "2.0000000000000000".

I doubt this will change.  If you want to use a single format, you could massage the data first, like

if '.' not in dt:
    dt += ".000000"
msg201929 - (view) Author: Skip Montanaro (skip.montanaro) * Date: 2013-11-01 18:12
Okay, so no to __str__. What about isoformat?
msg201931 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2013-11-01 18:25
I don't know, Skip.  Since `.isoformat()` and `str()` have *always* worked this way, and that was intentional, it's probably going to take a strong argument to change either.
msg201932 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013-11-01 18:40
Well, I don't know if this sways anything, but I was probably responsible, and I think my argument was something about not all timestamp sources having microseconds, and not wanting to emit the ".000000" in that case. If I could go back I'd probably do something else; after all str(1.0) doesn't return '1' either. But that's water under the bridge; "fixing" this is undoubtedly going to break a lot of code.

Maybe we can give isoformat() a flag parameter to force the inclusion or exclusion of the microseconds (with a default of None meaning the current behavior)?
msg201934 - (view) Author: Skip Montanaro (skip.montanaro) * Date: 2013-11-01 18:50
The ultimate culprit here is actually the csv module. :-) It calls str() on every element it's about to write. In my applications which write to CSV files I can special case datetime objects.

I will stop swimming upstream.
msg201935 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-11-01 18:55
I suppose in an ideal world the csv module would have some sort of hookable serialization protocol, like the database modules do :)
msg201943 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2013-11-01 22:14
As I understand Guido's message, he reopened this to consider adding a new parameter.

Given an existing csv file like that given, either Tim's solution or
try: parse with microseconds
except ValueError: parse without
should work.
msg202220 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2013-11-05 15:48
+1 on adding an option to isoformat().  We already have an optional <sep> argument, so the symmetry with __str__ is not complete.  To make this option more useful, rather than implementing always_emit_microseconds=False flag, I would add a keyword argument 'precision' that would take ('hour'|'minute'|'second'|millisecond'|'microsecond') value.
msg202238 - (view) Author: Andrei Dorian Duma (andrei.duma) * Date: 2013-11-05 20:14
I would like to implement this feature. I already wrote the Python part. Is there anything else to decide?
msg202239 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2013-11-05 20:31
2013/11/5 Alexander Belopolsky <report@bugs.python.org>:
> +1 on adding an option to isoformat().  We already have an optional <sep> argument, so the symmetry with __str__ is not complete.  To make this option more useful, rather than implementing always_emit_microseconds=False flag, I would add a keyword argument 'precision' that would take ('hour'|'minute'|'second'|millisecond'|'microsecond') value.

Hour precision is not part of the ISO 8601 standard.

"resolution" is maybe a better name for the new parameter than "precision":
http://www.python.org/dev/peps/pep-0418/#glossary

The new parameter should be added to datetime.datetime.isoformat() but
also datetime.time.isoformat().
msg202242 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2013-11-05 21:24
+1 on all Victor's points.

I like 'resolution' because this is the term that datetime module uses already:

>>> from datetime import *
>>> datetime.resolution
datetime.timedelta(0, 0, 1)

There is a slight chance of confusion stemming from the fact that datetime.resolution is timedelta, but proposed parameter is a string.

I believe ISO 8601 uses the word "accuracy" to describe this kind of format variations.  I am leaning towards "resolution", but would like to hear from others.  Here are the candidates:

1. resolution
2. accuracy
3. precision

(Note that "accuracy" is the shortest but "resolution" is the most correct.)
msg202243 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2013-11-05 21:32
On 05.11.2013 21:31, STINNER Victor wrote:
> 
> 2013/11/5 Alexander Belopolsky <report@bugs.python.org>:
>> +1 on adding an option to isoformat().  We already have an optional <sep> argument, so the symmetry with __str__ is not complete.  To make this option more useful, rather than implementing always_emit_microseconds=False flag, I would add a keyword argument 'precision' that would take ('hour'|'minute'|'second'|millisecond'|'microsecond') value.
> 
> Hour precision is not part of the ISO 8601 standard.
> 
> "resolution" is maybe a better name for the new parameter than "precision":
> http://www.python.org/dev/peps/pep-0418/#glossary
> 
> The new parameter should be added to datetime.datetime.isoformat() but
> also datetime.time.isoformat().

Since this ticket is about being able to remove the seconds fraction
part, I think it's better to use a name that is not already overloaded
with other meanings, e.g. show_us=False or show_microseconds=False.

BTW: Have you thought about the rounding/truncation issues
associated with not showing microseconds ?

A safe bet is truncation, but this can lead to inaccuracies of
up to a second. Rounding is difficult, since it can lead to
a "60" second value showing up for e.g. 11:00:59.95 seconds,
or the need to return "12:00:00" for 11:59:59.95.
msg202270 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2013-11-06 15:51
MAL: Have you thought about the rounding/truncation issues
associated with not showing microseconds ?

I believe it has to be the truncation.  Rounding is better left to the user code where it can be done either using timedelta arithmetics or at the time source.  I would expect that in the majority of cases where lower resolution printing is desired the times will be already at lower resolution at the source.
msg202274 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2013-11-06 17:05
On 06.11.2013 16:51, Alexander Belopolsky wrote:
> 
> MAL: Have you thought about the rounding/truncation issues
> associated with not showing microseconds ?

Sure, otherwise I wouldn't have mentioned it :-)

mxDateTime always uses 2 digit fractions when displaying date/time values.
This has turned out to be a good compromise between accuracy and
usability. In early version, I used truncation, but that caused
(too many) roundtrip problems, so I started using careful rounding
in later versions:

/* Fix a second value for display as string.

   Seconds are rounded to the nearest microsecond in order to avoid
   cases where e.g. 3.42 gets displayed as 03.41 or 3.425 is diplayed
   as 03.42.

   Special care is taken for second values which would cause rounding
   to 60.00 -- these values are truncated to 59.99 to avoid the value
   of 60.00 due to rounding to show up even when the indicated time
   does not point to a leap second. The same is applied for rounding
   towards 61.00 (leap seconds).

   The second value returned by this function should be formatted
   using '%05.2f' (which rounds to 2 decimal places).

*/

This approach has worked out well, though YMMV.

> I believe it has to be the truncation.  Rounding is better left to the user code where it can be done either using timedelta arithmetics or at the time source.  I would expect that in the majority of cases where lower resolution printing is desired the times will be already at lower resolution at the source.

In practice you often don't know the resolution of
the timing source. Nowadays, the reverse of what you said
is usually true: the source resolution is higher than the
precision you use to print it.

MS SQL Server datetime is the exception to that rule, with a
resolution of 333ms and weird input "rounding":

http://msdn.microsoft.com/en-us/library/ms187819.aspx

For full seconds, truncation will add an error of +/- 1 second,
whereas rounding only adds +/- 0.5 seconds. This is what convinced
me to use rounding instead of truncation.
msg202276 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2013-11-06 17:20
I am afraid that the rounding issues may kill this proposal.  Can we start with something simple?  For example, we can start with show=None keyword argument and allow a single value 'microseconds' (or 'us').  This will solve the issue at hand with a reasonable syntax: t.isoformat(show='us').  If other resolutions will be required, we can later add more values and may even allow t.isoformat(show=2) to show 2 decimal digits.
msg202282 - (view) Author: Skip Montanaro (skip.montanaro) * Date: 2013-11-06 18:22
> I am afraid that the rounding issues may kill this proposal.  Can we start with something simple?  For example, we can start with show=None keyword argument and allow a single value 'microseconds' (or 'us').  This will solve the issue at hand with a reasonable syntax: t.isoformat(show='us').  If other resolutions will be required, we can later add more values and may even allow t.isoformat(show=2) to show 2 decimal digits.

I don't think the meaning of this proposed show keyword argument
should be overloaded as you suggest. If you show microseconds, just
show all of them.

Furthermore...

If we go far enough back, my original problem was really that the
inclusion of microseconds in csv module output was inconsistent,
making it impossible for me to later parse those values in another
script using a fixed strptime format. Since the csv module uses str()
to convert input values for output, nothing you do to isoformat() will
have any effect on my original problem.

In my own code (where I first noticed the problem) I acquiesced, and
changed this

d["time"] = now

to this:

d["time"] = now.strftime("%Y-%m-%dT%H:%M:%S.%f")

where "now" is a datetime object. I thus guarantee that I can parse
these timestamps later using the same format. I realize the inclusion
of "T" means my fields changed in other ways, but that was
intentional, and not germane to this discussion.

So, fiddle all you want with isoformat(), but do it right. I vote that
if you want to add a show parameter it should simply include all
fields down to that level, omitting any lower down. If people want to
round or truncate things you can give them that option, returning a
suitably adjusted, new datetime object. I don't think rounding,
truncation, or other numeric operations should be an element of
conversion to string form. This does not happen today:

>>> import datetime
>>> x = datetime.datetime.now()
>>> x
datetime.datetime(2013, 11, 6, 12, 19, 5, 759020)
>>> x.strftime("%Y-%m-%d %H:%M:%S")
'2013-11-06 12:19:05'

(%S doesn't produce "06")

Skip
msg221958 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-06-30 13:26
Here is some "prior art": GNU date utility has an --iso-8601[=timespec] option defined as

‘-I[timespec]’
‘--iso-8601[=timespec]’
Display the date using the ISO 8601 format, ‘%Y-%m-%d’.
The argument timespec specifies the number of additional terms of the time to include. It can be one of the following:

‘auto’
Print just the date. This is the default if timespec is omitted. 
‘hours’
Append the hour of the day to the date. 
‘minutes’
Append the hours and minutes. 
‘seconds’
Append the hours, minutes and seconds. 
‘ns’
Append the hours, minutes, seconds and nanoseconds.
If showing any time terms, then include the time zone using the format ‘%z’. 

https://www.gnu.org/software/coreutils/manual/html_node/Options-for-date.html
msg221959 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-06-30 13:33
Based on GNU date "prior art", we can introduce timespec='auto' keyword argument with the following values:

'auto' - (default) same as current behavior
'hours' - %H
'minutes' - %H:%M
'seconds' - %H:%M:%S
'us' - %H:%M:%S.%f
msg247265 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2015-07-24 09:53
> 'seconds' - %H:%M:%S
> 'us' - %H:%M:%S.%f

'us' is not consistent with the datetime module: it should be 'microseconds.

>>> datetime.datetime.now().second
50
>>> datetime.timedelta(seconds=1)
datetime.timedelta(0, 1)

>>> datetime.datetime.now().microsecond
123710
>>> datetime.timedelta(microseconds=1)
datetime.timedelta(0, 0, 1)
msg247401 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2015-07-25 22:28
@acucci: Nice first try, but your patch contains multiple bugs.
msg247402 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-07-25 23:11
@haypo thanks for the review and the suggestions, I'll correct the code soon
msg247439 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-07-26 16:52
udloaded a new patch, hope i had all bugs fixed!
msg247723 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2015-07-31 01:21
Thanks, Alessandro! I left some additional comments on Rietveld: https://bugs.python.org/review/19475/#ps15278
msg247948 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-08-03 19:46
uploaded a new patch!
msg256458 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-15 13:10
Please can I have an update on this? It's already 4 months old, I'd like to see it closed. :)
msg256470 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2015-12-15 17:34
I like the idea. I have one suggestion: can we add 'milliseconds' as an option too? And might a well add 'nanoseconds' too, for future-proofing. I suppose there isn't a real use case for 'hours' but it seems silly to  leave it out. I expect that 'minutes' will be the most popular option, since HH:MM is the precision that most people care about for meetings and stuff.
msg256475 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-12-15 19:33
It looks like issue19475_v3.patch uses some fancy Unicode quotes in the docstrings and .rst docs.  Please change them to ASCII.
msg256476 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-15 19:56
I can work on that, although I'll need help from some senior dev. The problem here is that millisecond and nanosecond seems not to be attributes of the datetime object. What about open a new issue if we have to add them? Is not about adding an optional flag anymore...
Anyway, as I said, any help is appreciated!
msg256477 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-12-15 19:58
GvR> I suppose there isn't a real use case for 'hours' but it seems silly to  leave it out.

Shouldn't we also have 'none' to leave out the time component entirely?
msg256478 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-12-15 20:01
> The problem here is that millisecond and nanosecond seems not to be attributes of the datetime object.

millisecond = dt.microsecond // 1000

nanosecond = 0  # until we add it to datetime.
msg256479 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2015-12-15 20:11
Actually, nanosecond = dt.microsecond*1000.

I don't think we need 'none' -- you should just extract the date component
and call its isoformat() method if that's what you want.

On Tue, Dec 15, 2015 at 12:01 PM, Alexander Belopolsky <
report@bugs.python.org> wrote:

>
> Alexander Belopolsky added the comment:
>
> > The problem here is that millisecond and nanosecond seems not to be
> attributes of the datetime object.
>
> millisecond = dt.microsecond // 1000
>
> nanosecond = 0  # until we add it to datetime.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue19475>
> _______________________________________
>
msg256480 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-12-15 20:22
> Actually, nanosecond = dt.microsecond*1000.

I was thinking in terms breaking the fractional part of say

00:00:00.123456789

into

mili = 123
micro = 456
nano = 789

but you are right, a correct analogy for dt.microsecond in this case will be nanosecond=123456789 or 123456000 until we start storing enough precision.
msg256481 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-12-15 20:27
I think timespec= option should also be added to the time.isoformat method.
msg256483 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-12-15 20:39
Alessandro, did you try running the test suite? It is broken for me. One of the bugs is that it now omits zero hours, minutes, and seconds in addition to microseconds. (Kind of the reverse of what the bug was originally about :).

Other failures look like this:

======================================================================
ERROR: test_isoformat (test.datetimetester.TestDateTime)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/media/disk/home/proj/python/cpython/Lib/test/datetimetester.py", line 1560, in test_isoformat
    timespec_error = self.time()
AttributeError: 'TestDateTime_Pure' object has no attribute 'time'

I will leave some review comments.
msg256486 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-12-15 21:07
The doc string in the C module needs updating.
msg256513 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-16 07:35
Thanks for all the comments, here and on Rietveld. I'll keep working on it. Hope to upload a new patch soon.
msg256536 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-16 21:47
Uploaded a new patch (v4):
DONE:
- now all tests work (I also added one more)
- removed non ascii chars
- added milliseconds and nanoseconds as multiple of microseconds
- removed code duplication in the datetime.py
- update the docstring.

TODO:
> The doc string in the C module needs updating. 
Where? I guess "Macros to extract fields from datetime objects." in c-api/datetime.rst Tell me if I'm wrong

> I think timespec= option should also be added to the time.isoformat method.
I'll do it when I'm sure that the datetime.isoformat method is correct.
msg256552 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-12-16 22:41
With patch v4 many tests still fail for me. How are you running the test suite? Some excerpts:

  File "/media/disk/home/proj/python/cpython/Lib/test/datetimetester.py", line 1567, in test_isoformat
    self.assertEqual(t.isoformat(timespec='milliseconds'), "0001-02-03T04:05:01.000")
AssertionError: '0001-02-03T04:05:01.000000' != '0001-02-03T04:05:01.000'

  File "/media/disk/home/proj/python/cpython/Lib/test/datetimetester.py", line 2310, in test_isoformat
    self.assertEqual(t.isoformat(), "00:00:00")
AssertionError: '00:00:00.000000' != '00:00:00'

  File "/media/disk/home/proj/python/cpython/Lib/test/datetimetester.py", line 2379, in test_str
    self.assertEqual(str(self.theclass(12, 2, 3, 0)), "12:02:03")
AssertionError: '12:02:03.000000' != '12:02:03'

The C module doc string I referred to is this one; I left a review comment at the source:

>>> print(datetime.isoformat.__doc__)
[sep] -> string in ISO 8601 format, YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].

sep is used to separate the year from the time, and defaults to 'T'.
msg256556 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-16 22:50
I just did that...

~/Documenti/cpython$ ./configure --with-pydebug
~/Documenti/cpython$ make -s -j2
~/Documenti/cpython$ ./python -m test -v datetimetester
...
...

----------------------------------------------------------------------
Ran 325 tests in 1.128s

OK (skipped=1)
1 test OK.
msg256560 - (view) Author: SilentGhost (SilentGhost) * Date: 2015-12-16 23:01
Even that produces 3 failures on my setup, though the full list would be available when running: ./python -m test -v test_datetime

It is obvious, however, that the tests would fail: you've changed "if us:" to "if us is None:".
msg256561 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-12-16 23:03
> ~/Documenti/cpython$ ./python -m test -v datetimetester

You shouldn't use "datetimetester" on the command line.  Use "test_datetime" instead.
msg256591 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-12-17 08:35
If the timespec allowed any arbitrary number of digits after the decimal point, that would remove any argument about nanoseconds not being supported. It would also mean I could use this in one case where I currently format to two decimal places (my compromise between accurate timestamps and excessive information). Just a suggestion :)
msg256764 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-20 12:25
Uploaded a new patch. 

This time I ran tests using:
$ ./python -m test -v test_datetime

and got no errors.

I've written the c docstring, updated docs, and rewrote _format_time function.

I know it's boring review this another time, but I'm doing my best.

Thanks to all.
msg256813 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-21 22:33
Uploaded a new patch after SilentGhost review comments.

As he told me, I've left out milliseconds and nanoseconds, but refactored both python and c code so we could easily add support for them when they will be available.
msg256855 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-22 19:25
Sorry @SilentGhost, I didn't seen your comment at the bottom of the review. With this patch is microsecond is 0, the time will display 6 zeroes.
msg256858 - (view) Author: SilentGhost (SilentGhost) * Date: 2015-12-22 20:08
I think the patch is nearly finalised, but I'd appreciate if someone else would carefully go over the new C code. After that, I think, the patch could be committed.
msg256866 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-22 20:53
Thanks SilentGhost!
msg256967 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-24 18:47
Can anyone please review the c code of the last patch?
msg256991 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-25 14:26
> I think timespec= option should also be added to the time.isoformat method.

@belopolsky I've done it in my last patch.
msg257196 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2015-12-29 16:08
Thanks for the patch, Alessandro. I left some comments about documentation part of the patch, but I can fix them myself if you don't have time.
msg257202 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-29 18:16
what about the comment left by SilentGhost about versionadded?
msg257203 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-29 18:44
Berker, thank you. 
In the last patch, I removed details about timespec options in Python and C docstrings, corrected the rst quotes, and checked PEP7 in the c file.

The only problem now is about versionchanged vs versionadded. I leave it as it was, as Silent and the official doc say, if you want to change it, i'll leave it to you. 

Again, many many thanks to all. This was my first issue here, I learnt a lot!
msg257284 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-01-01 10:39
I think there is a memory leak in the C code. I left some other minor suggestions as well, but it almost looks ready.
msg257288 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-01-01 12:50
Thanks @martin.panter, here is another patch made after your comments.
msg257534 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-01-05 15:30
up
msg258289 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-01-15 12:18
I there anything else I can do for this?
msg258473 - (view) Author: SilentGhost (SilentGhost) * Date: 2016-01-17 15:38
> I there anything else I can do for this?
I think you've done all you could, it's just someone needs to commit it.  I don't think they're being rude on purpose - it's just that there are so many committers in the nosy list that no one is feeling like it's their job.
msg258477 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-01-17 18:52
I think Alexander has commit rights, he did most of the review, I trust him
to commit it.
msg258479 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-01-17 19:46
Not seeing any indication that this has been tested on Windows, I applied, compiled (32 bit), and ran test_datetime on Win10 without error.  I did not rebuild the doc.
msg258480 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-01-17 20:33
Is issue19475_v12.patch the final patch?  I don't see it addressing Guido's suggestion in msg256470 to add milli- and nanoseconds options.
msg258481 - (view) Author: SilentGhost (SilentGhost) * Date: 2016-01-17 20:46
Yes, version 12 is the final patch. It doesn't add those options. To copy my opinion from the rietveld (https://bugs.python.org/review/19475/#msg14): 

> I don't really think nanoseconds belong here. If they don't
> exist anywhere else in the module, why should they be suddenly introduced here?
> of all places. It would be fine to use some generic solution that would enable
> or ease their addition in the future, but they shall not be added at this time.

(there are altogether 27 messages there, which everyone's naturally CCed on).
msg258482 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-01-17 21:23
I left some comments on Rietveld.
msg258483 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-01-17 21:33
> I don't really think nanoseconds belong here.

What about milliseconds?  I'll leave it for Guido to make a call on nanoseconds.  My vote is +0.5.

> If they don't
> exist anywhere else in the module, why should they be suddenly 
> introduced here?

The timespec feature is modeled after GNU date --iso-8601[=timespec] option which does support nanoseconds.  It is fairly common to support nanoseconds these days and it does not cost much to implement.
msg258485 - (view) Author: SilentGhost (SilentGhost) * Date: 2016-01-17 22:07
> What about milliseconds?  I'll leave it for Guido to make a call on nanoseconds.  My vote is +0.5.
The only reason I didn't mention milliseconds because they exist in timedelta instantiation. And really, being the only place in the whole module they're as confusing there as would be nanoseconds.

> > If they don't
> > exist anywhere else in the module, why should they be suddenly 
> > introduced here?

> The timespec feature is modeled after GNU date --iso-8601[=timespec] option which does support nanoseconds.  It is fairly common to support nanoseconds these days and it does not cost much to implement.

Yes, but the module does not support nanoseconds. And putting any such options would require a huge banner saying that the nanosecond option will just always result in three zeros at the end. My suggestion is not to pretend that we suddenly "support" nanoseconds, but rather to follow the actual implementation of the module and add the support for nanoseconds timespec when the module actually adds support for them.
msg258493 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-01-18 02:59
You can leave out the nanoseconds but please do add the milliseconds. I'm sure they would find more use than the option to show only the hours.
msg260629 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-02-21 18:20
New patch
msg260645 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-02-21 22:32
Left some review suggestions
msg260695 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-02-22 18:15
New patch after @martin.panter comments on Rietveld. I left only this:

- ``'milliseconds'``: Append the hours, minutes, seconds and milliseconds.

> vadmium 2016/02/21 23:30:20
> I think this should explain that fractions are truncated to zero, never 
> rounded
> up. At least for fractions of milliseconds, although this could apply 
> to the
> other options as well.

I think is quite obvious that a datetime.now() can't be rounded to the future if microseconds are 999500.
msg260725 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-02-23 10:33
About rounding: I’m not too sure what people would expect. Obviously it is much easier to implement truncating to zero. But it is different to many other rounding cases in Python; that is why I thought to make it explicit.

>>> datetime.fromtimestamp(59.9999999).isoformat(timespec="microseconds")
'1970-01-01T00:01:00.000000'
>>> datetime.fromtimestamp(59.999999).isoformat(timespec="milliseconds")
'1970-01-01T00:00:59.999'
>>> format(59.999999, ".3f")
'60.000'
msg260875 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-02-25 18:15
Oh, now I see your point.

I've uploaded a new patch with a note for that.
msg260876 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-02-25 18:29
Out of context here, but regarding round vs. truncate, IIUC for time
truncating down is the norm. My digital clock shows "12:00" for the
duration of the minute starting at noon. People look for clocks to
flip to know when it is exactly a given time (if the clock is accurate
enough).
msg260878 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-02-25 18:49
We discussed truncation vs. rounding some time ago.  See msg202270 and the posts around it.  The consensus was the same as Guido's current advise: do the truncation.
msg261060 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-03-01 18:05
@belopolsky could you please review one of the latest two patches submitted? I think I've done all required. Now I'll wait from you if I have to do more.
msg261066 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-01 20:11
Guido,

Did you consider MAL's msg202274?  I am still in favor of truncation, but would like to make sure we are not missing something that MAL knows from experience.
msg261068 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-01 20:22
Another argument for truncation is that this is what GNU date does:

$ date --iso-8601=seconds --date="2016-03-01 15:00:00.999"
2016-03-01T15:00:00-0500
msg261073 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-03-01 21:13
Given that we're talking about what to do when we're suppressing the usecs I don't think roundtripping matters. :-)
msg261074 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2016-03-01 21:16
> Given that we're talking about what to do when we're suppressing the usecs I don't think roundtripping matters. :-)

I changed many times how Python rounds nanoseconds in the private PyTime API, and I got a bug report because of that! => issue #23517.

By the way, I wrote an article to explain the history the private PyTime API, especially changes on rounding ;-) https://haypo.github.io/pytime.html
msg261077 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-03-01 21:32
But what should we do in your opinion?
msg261078 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-01 21:35
I hope my prediction "I am afraid that the rounding issues may kill this proposal" (see msg202276) will not come true.

I think the correct way to view "timespec" is a way to suppress/enforce printing of trailing digits.

Users that choose printing less than full usec format should make sure that their datetime instances are properly rounded before printing.

Unfortunately, I does not look like the datetime module makes rounding easy.  The best I can think of is something like

def round_datetime(dt, delta):
    dt0 = datetime.combine(dt.date(), time(0))
    return dt0 + round((dt - dt0) / delta) * delta

Maybe a datetime.round() method along these lines will be a worthwhile addition?
msg261080 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2016-03-01 21:47
> But what should we do in your opinion?

Use ROUND_FLOOR rounding method.

time.time(), datetime.datetime.now(), etc. round the current time using the ROUND_FLOOR rounding method.

Only datetime.datetime.fromtimestamp() uses ROUND_HALF_EVEN, but it's more an exception than the rule: this function uses a float as input. To be consistent, we must use the same rounding method than other Python functions taking float as parameter, like round(), so use ROUND_HALF_EVEN.

So I suggest to also use ROUND_FLOOR for .isoformat().

Hopefully, we don't have to discuss about the exact rounding method for negative numbers, since the minimum datetime object is datetime.datetime(1, 1, 1) which is "positive" ;-)

You have a similar rounding question for file timestamps. Depending on the file system, you may have a resolution of 2 seconds (FAT), 1 second (ext3) or 1 nanosecond (ext4). But Linux syscalls accept subsecond resolution. The Linux kernel uses ROUND_FLOOR rounding method if I recall correctly. I guess that it's a requirement for makefiles. If you already experimented a system clock slew, you may understand me :-)


> For full seconds, truncation will add an error of +/- 1 second,
> whereas rounding only adds +/- 0.5 seconds. This is what convinced
> me to use rounding instead of truncation.

What is truncation? Is it the ROUND_FLOOR (towards -inf) rounding method? Like math.floor(float).

Python int(float) uses ROUND_DOWN (towards zero) which is different than ROUND_FLOOR, but only different for negative numbers. int(-0.9) returns 0, whereas math.floor(-0.9) returns -1.

I guess that "rounding" means ROUND_HALF_EVEN here? The funny "Round to nearest with ties going to nearest even integer" rounding method. Like round(float).
msg261081 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-03-01 21:48
Except for the case where you're closer than half a usec from the next value, IMO rounding makes no sense when suppressing digits. I most definitely would never want 9:59:59 to be rounded to 10:00 when suppressing seconds. If you really think there are use cases for that you could add a 'round=True' flag (as long as it defaults to False). That seems better than supporting rounding on datetime objects themselves. But I think you're just speculating.
msg261082 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-03-01 21:50
IIUC truncation traditionally means "towards zero" -- that's why we have separate "floor" and "ceiling" operations meaning "towards [negative] infinity". Fortunately we shouldn't have to deal with negative values here so floor and truncate mean the same thing. Agreed that isoformat() should also truncate.
msg261083 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2016-03-01 21:52
> Maybe a datetime.round() method along these lines will be a worthwhile addition?

Sorry, what is the use case of this method?
msg261084 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-01 22:00
Personally, I don't rounding is that useful.  My working assumption is that users will select say timespec='millisecond' only when they know that their time source produces datetime instances with millisecond precision and they don't want to kill more trees by printing redundant 0's.

MAL's objection this this line of arguments was that some time sources have odd resolution (he reported MS SQL's use of 333 ms) and a user may want to have a perfect round-tripping when using a sub-usec timespec and such an odd time source or destination.
msg261085 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2016-03-01 22:06
> Personally, I don't rounding is that useful.

Nice, it looks like I agree with you on using ROUNDING_FLOOR :-)

I don't think that we should be prepared for theorical user requests, but rather focus on the concrete and well defined current existing user request: "Add timespec optional flag to datetime isoformat() to choose the precision".

Let's wait until users request a datetime.round() method to understand better concrete issues.
msg261086 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-01 22:09
I feel odd trying to advocate a POV that I disagree with, so let me just quote MAL:


"""
In practice you often don't know the resolution of
the timing source. Nowadays, the reverse of what you said
is usually true: the source resolution is higher than the
precision you use to print it.
..

For full seconds, truncation will add an error of +/- 1 second,
whereas rounding only adds +/- 0.5 seconds. This is what convinced
me to use rounding instead of truncation.
"""

I somehow missed this argument when Marc-Andre made it, so I want to make sure that it is properly considered before we finalize this issue.
msg261133 - (view) Author: Alessandro Cucci (acucci) * Date: 2016-03-02 18:19
Meanwhile I made corrections after @belopolsky latest review
msg261135 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-02 18:25
Alessandro, thank you very much for your work and perseverance.  I will do my best to commit this next weekend.
msg261269 - (view) Author: Roundup Robot (python-dev) Date: 2016-03-06 19:58
New changeset eb120f50df4a by Alexander Belopolsky in branch 'default':
Closes #19475: Added timespec to the datetime.isoformat() method.
https://hg.python.org/cpython/rev/eb120f50df4a
History
Date User Action Args
2016-03-06 19:58:58python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg261269

resolution: fixed
stage: commit review -> resolved
2016-03-02 18:25:44belopolskysetmessages: + msg261135
stage: patch review -> commit review
2016-03-02 18:24:42SilentGhostsetnosy: - SilentGhost
2016-03-02 18:19:23acuccisetfiles: + issue19475_v17.patch

messages: + msg261133
2016-03-01 22:09:32belopolskysetmessages: + msg261086
2016-03-01 22:06:38hayposetmessages: + msg261085
2016-03-01 22:00:34belopolskysetmessages: + msg261084
2016-03-01 21:52:02hayposetmessages: + msg261083
2016-03-01 21:50:55gvanrossumsetmessages: + msg261082
2016-03-01 21:48:07gvanrossumsetmessages: + msg261081
2016-03-01 21:47:08hayposetmessages: + msg261080
2016-03-01 21:35:47belopolskysetmessages: + msg261078
2016-03-01 21:32:29gvanrossumsetmessages: + msg261077
2016-03-01 21:16:26hayposetmessages: + msg261074
2016-03-01 21:13:33gvanrossumsetmessages: + msg261073
2016-03-01 20:22:38belopolskysetmessages: + msg261068
2016-03-01 20:11:22belopolskysetmessages: + msg261066
2016-03-01 19:20:57belopolskysetstage: needs patch -> patch review
2016-03-01 18:05:27acuccisetmessages: + msg261060
2016-02-25 18:49:58belopolskysetmessages: + msg260878
2016-02-25 18:29:22gvanrossumsetmessages: + msg260876
2016-02-25 18:15:49acuccisetfiles: + issue19475_v16.patch

messages: + msg260875
2016-02-23 10:33:09martin.pantersetmessages: + msg260725
2016-02-22 18:15:41acuccisetfiles: + issue19475_v15.patch

messages: + msg260695
2016-02-22 17:53:10andrei.dumasetnosy: - andrei.duma
2016-02-21 22:32:03martin.pantersetmessages: + msg260645
2016-02-21 21:58:13acuccisetfiles: + issue19475_v14.patch
2016-02-21 18:20:29acuccisetfiles: + issue19475_v13.patch

messages: + msg260629
2016-01-18 02:59:56gvanrossumsetmessages: + msg258493
2016-01-17 22:07:12SilentGhostsetmessages: + msg258485
2016-01-17 21:33:15belopolskysetmessages: + msg258483
2016-01-17 21:23:54belopolskysetmessages: + msg258482
stage: commit review -> needs patch
2016-01-17 20:46:12SilentGhostsetmessages: + msg258481
2016-01-17 20:33:35belopolskysetmessages: + msg258480
2016-01-17 20:25:37belopolskysetassignee: belopolsky
stage: patch review -> commit review
2016-01-17 19:46:33terry.reedysetmessages: + msg258479
2016-01-17 18:52:20gvanrossumsetmessages: + msg258477
2016-01-17 15:38:07SilentGhostsetmessages: + msg258473
2016-01-15 15:09:21r.david.murraysetnosy: - r.david.murray
2016-01-15 12:18:09acuccisetmessages: + msg258289
2016-01-05 15:30:32acuccisetmessages: + msg257534
2016-01-01 12:50:31acuccisetfiles: + issue19475_v12.patch

messages: + msg257288
2016-01-01 10:39:52martin.pantersetmessages: + msg257284
2015-12-29 18:44:40acuccisetfiles: + issue19475_v11.patch

messages: + msg257203
2015-12-29 18:16:39acuccisetmessages: + msg257202
2015-12-29 16:08:47berker.peksagsetmessages: + msg257196
stage: commit review -> patch review
2015-12-29 15:46:13SilentGhostsetstage: patch review -> commit review
2015-12-25 14:26:19acuccisetfiles: + issue19475_v10_datetime_time.patch

messages: + msg256991
2015-12-24 18:47:30acuccisetmessages: + msg256967
2015-12-23 18:18:12skip.montanarosetnosy: - skip.montanaro
2015-12-22 20:53:45acuccisetfiles: + issue19475_v9.patch

messages: + msg256866
2015-12-22 20:08:26SilentGhostsetmessages: + msg256858
2015-12-22 19:25:41acuccisetfiles: + issue19475_v8.patch

messages: + msg256855
2015-12-22 18:44:34acuccisetfiles: + issue19475_v7.patch
2015-12-21 22:33:19acuccisetfiles: + issue19475_v6.patch

messages: + msg256813
2015-12-20 12:25:35acuccisetfiles: + issue19475_v5.patch

messages: + msg256764
2015-12-17 08:35:55martin.pantersetmessages: + msg256591
2015-12-16 23:03:06belopolskysetmessages: + msg256561
2015-12-16 23:01:18SilentGhostsetmessages: + msg256560
2015-12-16 22:50:35acuccisetmessages: + msg256556
2015-12-16 22:41:13martin.pantersetmessages: + msg256552
2015-12-16 21:47:21acuccisetfiles: + issue19475_v4.patch

messages: + msg256536
2015-12-16 20:11:15SilentGhostsetnosy: + SilentGhost
2015-12-16 07:35:50acuccisetmessages: + msg256513
2015-12-15 21:07:50martin.pantersetmessages: + msg256486
2015-12-15 20:39:12martin.pantersetnosy: + martin.panter
messages: + msg256483
2015-12-15 20:27:35belopolskysetmessages: + msg256481
2015-12-15 20:22:28belopolskysetmessages: + msg256480
2015-12-15 20:11:20gvanrossumsetmessages: + msg256479
2015-12-15 20:01:28belopolskysetmessages: + msg256478
2015-12-15 19:58:25belopolskysetmessages: + msg256477
2015-12-15 19:56:32acuccisetmessages: + msg256476
2015-12-15 19:33:00belopolskysetmessages: + msg256475
2015-12-15 17:34:46gvanrossumsetmessages: + msg256470
2015-12-15 13:12:06hayposetnosy: + matrixise
2015-12-15 13:10:48acuccisetmessages: + msg256458
2015-08-03 19:46:13acuccisetfiles: + issue19475_v3.patch

messages: + msg247948
2015-07-31 01:21:21berker.peksagsetnosy: + berker.peksag

messages: + msg247723
stage: needs patch -> patch review
2015-07-26 16:52:22acuccisetmessages: + msg247439
2015-07-25 23:46:13acuccisetfiles: + issue19475_v2.patch
2015-07-25 23:11:19acuccisetnosy: + acucci
messages: + msg247402
2015-07-25 22:28:13hayposetmessages: + msg247401
2015-07-25 14:12:16acuccisetfiles: + issue19475.patch
keywords: + patch
2015-07-24 09:53:38hayposettitle: Add microsecond flag to datetime isoformat() -> Add timespec optional flag to datetime isoformat() to choose the precision
2015-07-24 09:53:22hayposetmessages: + msg247265
2015-07-24 09:45:49berker.peksagsetstage: resolved -> needs patch
superseder: datetime: add ability to parse RFC 3339 dates and times ->
versions: + Python 3.6, - Python 3.5
2015-07-14 04:10:18jerry.elmoresetnosy: + jerry.elmore
2014-06-30 13:33:49belopolskysetmessages: + msg221959
2014-06-30 13:26:46belopolskysetmessages: + msg221958
versions: + Python 3.5, - Python 3.4
2014-04-23 06:23:00cvrebertsetnosy: + cvrebert
2013-11-06 18:22:31skip.montanarosetmessages: + msg202282
2013-11-06 17:20:54belopolskysetmessages: + msg202276
2013-11-06 17:05:25lemburgsetmessages: + msg202274
2013-11-06 15:51:03belopolskysetmessages: + msg202270
2013-11-05 21:32:18lemburgsetnosy: + lemburg
messages: + msg202243
2013-11-05 21:24:47belopolskysetmessages: + msg202242
2013-11-05 20:31:16hayposetmessages: + msg202239
2013-11-05 20:14:15andrei.dumasetmessages: + msg202238
2013-11-05 15:48:38belopolskysetmessages: + msg202220
2013-11-05 15:38:32belopolskysetnosy: + belopolsky
2013-11-05 10:35:42hayposetnosy: + haypo
2013-11-04 00:50:22andrei.dumasetnosy: + andrei.duma
2013-11-01 22:14:26terry.reedysetnosy: + terry.reedy
title: Inconsistency between datetime's str()/isoformat() and its strptime() method -> Add microsecond flag to datetime isoformat()
messages: + msg201943

versions: - Python 2.7, Python 3.3
type: behavior -> enhancement
2013-11-01 18:55:55r.david.murraysetmessages: + msg201935
2013-11-01 18:50:19skip.montanarosetmessages: + msg201934
2013-11-01 18:40:37gvanrossumsetstatus: closed -> open

nosy: + gvanrossum
messages: + msg201932

resolution: duplicate -> (no value)
2013-11-01 18:25:32tim.peterssetmessages: + msg201931
2013-11-01 18:12:10skip.montanarosetmessages: + msg201929
2013-11-01 18:07:37tim.peterssetnosy: + tim.peters
messages: + msg201926
2013-11-01 18:01:09r.david.murraysetstatus: open -> closed

messages: + msg201925
2013-11-01 17:55:53skip.montanarosetmessages: + msg201924
2013-11-01 17:47:22r.david.murraysetnosy: + r.david.murray
messages: + msg201922
resolution: duplicate

superseder: datetime: add ability to parse RFC 3339 dates and times
stage: resolved
2013-11-01 17:08:38ezio.melottisetnosy: + ezio.melotti
messages: + msg201918
2013-11-01 17:05:21skip.montanarocreate