Message221385
*If* the support for %s strftime format code is added then it should
keep backward compatibility on Linux, OSX: it should produce an
integer string with the correct rounding.
Currently, datetime.strftime delegates to a platform strftime(3) for
format specifiers that are not described explicitly [1]:
> The full set of format codes supported varies across platforms,
> because Python calls the platform C library’s strftime() function,
> and platform variations are common. To see the full set of format
> codes supported on your platform, consult the strftime(3)
> documentation.
[1]: https://docs.python.org/3.4/library/datetime.html#strftime-strptime-behavior
%s is not defined in C, POSIX but is already defined on Linux, BSD [2]
where `datetime.now().strftime('%s')` can print an integer timestamp.
> %s is replaced by the number of seconds since the Epoch, UTC (see
> mktime(3)).
[2]: http://www.openbsd.org/cgi-bin/man.cgi?query=strftime
Unsupported format code is *undefined behavior* (crash, launch a
missile is a valid behavior) otherwise.
Support for additional codes on some platforms is explicitly mentioned
in datetime docs therefore %s behavior shouldn't change if it is
well-defined on a given platform i.e., `datetime.now().strftime('%s')`
should keep producing an integer string on Linux, BSD.
- old code: `aware_dt.astimezone().strftime('%s')`
- proposed code: `aware_dt.strftime('%s')` (all platforms)
'%d' produces the wrong rounding on my machine:
>>> from datetime import datetime, timezone
>>> dt = datetime(1969, 1, 1, 0,0,0, 600000, tzinfo=timezone.utc)
>>> '%d' % dt.timestamp()
'-31535999'
>>> dt.astimezone().strftime('%s')
'-31536000'
`math.floor` could be used instead:
>>> '%d' % math.floor(dt.timestamp())
'-31536000'
There is no issue with the round-trip via a float timestamp for
datetime.min...datetime.max range on my machine. `calendar.timegm`
could be used to avoid floats if desired:
>>> import calendar
>>> calendar.timegm(dt.astimezone(timezone.utc).timetuple())
-31536000
Note: dt.utctimetuple() is not used to avoid producing the wrong
result silently if dt is a naive datetime object; an exception is
raised instead.
The result is equivalent to `time.strftime('%s',
dt.astimezone().timetuple())` (+/- date/time range issues).
---
It is not clear what the returned value for %s strptime should be:
naive or timezone-aware datetime object and what timezone e.g.,
- old code: `datetime.fromtimestamp(int('-31536000'), timezone.utc)`
- proposed code: `datetime.strptime('-31536000', '%s')`
The result is an aware datetime object in UTC timezone. |
|
Date |
User |
Action |
Args |
2014-06-24 00:09:07 | akira | set | recipients:
+ akira, tim.peters, belopolsky, vstinner, r.david.murray, santoso.wijaya, bignose, Daniel.O'Connor, mumino |
2014-06-24 00:09:07 | akira | set | messageid: <1403568547.34.0.757424158006.issue12750@psf.upfronthosting.co.za> |
2014-06-24 00:09:07 | akira | link | issue12750 messages |
2014-06-24 00:09:06 | akira | create | |
|