Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
360 views
in Technique[技术] by (71.8m points)

python - Time zone field in isoformat

I have a timestamp that is supposed to be in EST:

2014-10-06T18:06:40-04:56

I understand this first part: 2014-10-06T18:06:40, but not -04:56.

What does -04:56 mean here?`

Here is how I got that timestamp:

import datetime
start_time = datetime.datetime(year  = 2014, 
                               month = 10, 
                               day   = 6, 
                               hour  = 18, 
                               tzinfo = pytz.timezone('US/Eastern'))
end_time   = start_time + datetime.timedelta(seconds=400)

And then:

end_time.isoformat()

returns:

2014-10-06T18:06:40-04:56
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that pytz:

…?differs from the documented Python API for tzinfo implementations; if you want to create local wallclock times you need to use the localize() method documented in this document …

Further down, it says:

Unfortunately using the tzinfo argument of the standard datetime constructors "does not work" with pytz for many timezones.

>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt)
'2002-10-27 12:00:00 LMT+0020'

So, you need to do what the docs suggest—using normalize, constructing UTC times and using astimezone, etc. Which one you want depends on exactly what you're trying to do. For example:

>>> from datetime import datetime
>>> from pytz import timezone
>>> utc = timezone('UTC')
>>> eastern = timezone('US/Eastern')
>>> datetime(2014, 10, 6, 18, tzinfo=eastern).isoformat()
'2014-10-06T18:00:00-04:56'
>>> eastern.normalize(datetime(2014, 10, 6, 18, tzinfo=eastern)).isoformat()
'2014-10-06T18:56:00-04:00'
>>> datetime(2014, 10, 6, 18, tzinfo=utc).astimezone(eastern).isoformat()
'2014-10-06T14:00:00-04:00'
>>> eastern.localize(datetime(2014, 10, 6, 18)).isoformat()
'2014-10-06T18:00:00-04:00'

I think it's the last you want. As the docs for localize say:

Convert naive time to local time.

This method should be used to construct localtimes, rather than passing a tzinfo argument to a datetime constructor.

And I think constructing a local time is exactly what you wanted here.


If you're wondering why… well, if you look at the data that's in your Olson database, or just print out eastern._utcoffset, you'll see -1 day, +68640 minutes. That's 19.0166+ hours, not 19. Why? Because every timezone is defined with its starting offset, with adjustments from there. Eastern is based on New York's timezone as of 1883 Nov 18 12:03:58, at which point it was -04:56:02 from GMT. There's an adjustment for dates starting in 1920 that subtracts the extra 00:03:58. And of course the yearly adjustments back and forth one hour for DST. So, as of right now, Eastern is -04:00, but without any idea of what date it's supposed to represent, it's -04:56. And, because datetime just asks a timezone for its offset, rather than its offset at a particular time, that's what it gets.


One last thing: EST is Eastern Standard Time, which is -05:00. That's not the time zone of any location in the US on 6 October 2014, because in 2014, the US's daylight saving time goes to 2 November. (There used to be counties in Indiana that were on EST during the summer, but there no longer are.) What you're looking for is EDT, Eastern Daylight Time, which is -04:00. Or, of course, ET, which is EDT during the summer and EST during the winter, which is what you get from looking up 'US/Eastern' or 'America/New_York'.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...