Author akira
Recipients Daniel.O'Connor, akira, belopolsky, bignose, mumino, r.david.murray, santoso.wijaya, tim.peters, vstinner
Date 2014-06-24.00:09:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1403568547.34.0.757424158006.issue12750@psf.upfronthosting.co.za>
In-reply-to
Content
*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.
History
Date User Action Args
2014-06-24 00:09:07akirasetrecipients: + akira, tim.peters, belopolsky, vstinner, r.david.murray, santoso.wijaya, bignose, Daniel.O'Connor, mumino
2014-06-24 00:09:07akirasetmessageid: <1403568547.34.0.757424158006.issue12750@psf.upfronthosting.co.za>
2014-06-24 00:09:07akiralinkissue12750 messages
2014-06-24 00:09:06akiracreate