3

I was wondering whether python makes a distinction between left-hand (sinistral) and right-hand (dextral) timestamps. This becomes a problem when localizing timestamps on DST days.

Say I have right-hand stamped half-hourly values in local European time, where a DST change occured from hour 02:00 to hour 03:00 on March 30th 2014.

2014-03-30 00:30:00
2014-03-30 01:00:00
2014-03-30 01:30:00
2014-03-30 02:00:00
2014-03-30 03:30:00
2014-03-30 04:00:00

If I want to localize these timestamps, I naturally get an error:

NonExistentTimeError: 2014-03-30 02:00:00

since there is no timestamp 02:00 in my local timezone on that day. So I wonder whether python can make a distinction between left/righ-hand timestamps?

alx
  • 53
  • 1
  • 4
  • If you sure that the timestamps are strictly increasing then you could [parse them using `pytz` module](http://stackoverflow.com/a/26221183/4279) – jfs Jun 08 '15 at 13:16
  • NonExistentTimeError suggests that either your input is wrong or you're using a wrong timezone to interpret it. – jfs Jun 08 '15 at 13:18
  • 1
    I've been working with time issues for quite a while and I've never heard the terms "left-hand" vs "right-hand", or "sinistral" vs "dextral" applied to timestamps. If this is a known thing that I just haven't heard about, then please point me at your sources. Either way, please explain exactly what you mean by this distinction, so others can learn as well. – Matt Johnson-Pint Jun 08 '15 at 17:12
  • @Matt: Think of data that is recorded over an interval, say 30min, but the data sampling system only stores aggregate values, typically mean, max, min over that interval. Then a timestamp of, say 02:00 is ambiguous as it could refer to the interval [01:30-02:00] or to the interval [02:00-02:30]. The former case would be right-hand stamped, the latter case left-hand stamped. Hopefully that explains it more clearly! – alx Jun 09 '15 at 13:58
  • It's common practice to use half-open intervals when time is involved. Example: `[01:30-2:00)[02:00-2:30)`. These would be "left-hand stamped" by your terminology. I have never encountered right-hand stamped time intervals. Think about any event you may have been to - The end time is when the event is *over*, so it is not part of that interval. – Matt Johnson-Pint Jun 10 '15 at 21:12

2 Answers2

0

I think the right approach is to use UTC when doing any arithmetic, and converting from/to UTC using the pytz package, which supports DST changes.

wouter bolsterlee
  • 3,879
  • 22
  • 30
0

pytz allows you to choose the utc offset before/after DST transition using is_dst parameter:

>>> import pytz
>>> tz = pytz.timezone('Europe/Paris')                                                               
>>> from datetime import datetime                                                                    
>>> naive = datetime.strptime('2014-03-30 02:00:00', '%Y-%m-%d %H:%M:%S')                            
>>> tz.localize(naive, is_dst=None)                            
Traceback (most recent call last)
...
NonExistentTimeError: 2014-03-30 02:00:00
>>> tz.localize(naive) #XXX WRONG
datetime.datetime(2014, 3, 30, 2, 0, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
>>> tz.normalize(tz.localize(naive)) # you want this (default is after the transition)
datetime.datetime(2014, 3, 30, 3, 0, tzinfo=<DstTzInfo 'Europe/Paris' CEST+2:00:00 DST>)
>>> tz.localize(naive, is_dst=False) #XXX WRONG 
datetime.datetime(2014, 3, 30, 2, 0, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
>>> tz.localize(naive, is_dst=True) #XXX WRONG 
datetime.datetime(2014, 3, 30, 2, 0, tzinfo=<DstTzInfo 'Europe/Paris' CEST+2:00:00 DST>)
>>> tz.normalize(tz.localize(naive, is_dst=False)) # time corresponding to the offset
datetime.datetime(2014, 3, 30, 3, 0, tzinfo=<DstTzInfo 'Europe/Paris' CEST+2:00:00 DST>)
>>> tz.normalize(tz.localize(naive, is_dst=True)) # time corresponding to the offset
datetime.datetime(2014, 3, 30, 1, 0, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
jfs
  • 399,953
  • 195
  • 994
  • 1,670