0

I know there are some posts about using timedelta objects in Python and Python doc is clear enough to understand everything. But I cannot figure out one thing. Let's assume that we have two dates:

t1 = 'Fri 11 Feb 2078 00:05:21 +0400'
t2 = 'Mon 29 Dec 2064 03:33:48 -1100' 

I parsed both t1 and t2 using the code below to find the difference between them in seconds:

def offset(arg):
    return timedelta(hours = arg / 100, minutes = arg % 100)

def normalize(time, offset, sign):
    return time+offset if sign == '-' else time-offset

def main():
    t1offset = offset(int(t1[-5:]))
    t2offset = offset(int(t2[-5:]))

    t1 = normalize(datetime.strptime(t1[:-6], 
                   "%a %d %b %Y %H:%M:%S"), t1offset, t1[-5])
    t2 = normalize(datetime.strptime(t2[:-6], 
                   "%a %d %b %Y %H:%M:%S"), t2offset, t2[-5])

    if t1>t2:
        print (t1-t2).total_seconds()
    elif t2>t1:
        print (t2-t1).total_seconds()
    else:
        print 0

The right answer is |t1-t2| = 413962293 while my result is 414041493. It's a difference of 79200 secs -> 22 hours. What am I doing wrong? What did I skip or what should I think about to solve this problem?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
hebius
  • 133
  • 1
  • 14
  • Whoever voted it to close, it is perfectly valid question with sufficient code to easily reproduce the problem. – Andrey Sep 07 '15 at 14:16
  • @Andrey but it isn't the *minimal* code to reproduce the problem (see [mcve]), as the OP has failed to do basic binary search debugging. – jonrsharpe Sep 07 '15 at 14:18
  • @jonrsharpe code is not absolutely minimal but small enough, not perfect but it is good to understand the problem. This question is not bad enough to be closed. – Andrey Sep 07 '15 at 14:22
  • Hint: t1: `Fri 11 Feb 2078 00:05:21 +0400` --> `datetime.datetime(2078, 2, 10, 20, 5, 21)` while t2: `Mon 29 Dec 2064 03:33:48 -1100` --> `datetime.datetime(2064, 12, 28, 16, 33, 48)`. So both `+0400` and `-1100` will decrease the time in convertion? – Mp0int Sep 07 '15 at 14:31

3 Answers3

0

You put the sign of the offset into the offset function.

'Fri 11 Feb 2078 00:05:21 +0400'[-5:] == '+0400'

I think it should be only the digits:

'Fri 11 Feb 2078 00:05:21 +0400'[-4:] == '0400'

This way your offset has negative values, and in the normalize function you are applying the sign again. Try this:

def main():
    t1offset = offset(int(t1[-4:]))
    t2offset = offset(int(t2[-4:]))

    t1 = normalize(datetime.strptime(t1[:-6], 
           "%a %d %b %Y %H:%M:%S"), t1offset, t1[-5])
    t2 = normalize(datetime.strptime(t2[:-6], 
                   "%a %d %b %Y %H:%M:%S"), t2offset, t2[-5])

    if t1>t2:
        print (t1-t2).total_seconds()
    elif t2>t1:
        print (t2-t1).total_seconds()
    else:
        print 0

However, you really shouldn't parse string timestamps like this, using hardcoded string indices.

Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
  • hege_hegedus, your answer was enough to help me solve the problem. I just skipped that I am applying the sign in the normalize function again :) – hebius Sep 08 '15 at 09:53
  • @hebius I'm glad to help, and happy you got your code working. If you do not have further questions, could you please accept this answer? – Tamas Hegedus Sep 08 '15 at 11:53
  • Done men :) And one more time thanx for your help :) – hebius Sep 10 '15 at 09:23
0

The time format is similar to the date/time format used in emails. You could use email module to parse it:

>>> from email.utils import parsedate_tz, mktime_tz
>>> ts1 = mktime_tz(parsedate_tz('Fri 11 Feb 2078 00:05:21 +0400'))
>>> ts2 = mktime_tz(parsedate_tz('Mon 29 Dec 2064 03:33:48 -1100'))
>>> ts1 - ts2
413962293
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
-1

This is not the best way to parse dates with timezones but if you want it this way that is your mistake:

def normalize(time, offset, sign):
    return time+offset if sign == '+' else time-offset
                                   ^

Normalize should be other way around.

If you are using Python 3+ (which you should) you can just do:

datetime.strptime(t1, "%a %d %b %Y %H:%M:%S %z")

Timezone specifier doesn't work in Python 2.x

Or use dateutils lib:

import dateutil
dateutil.parser.parse('Fri 11 Feb 2078 00:05:21 +0400')

Edit: better way to do it in original fashion is to drop sign comparison completely and rely on sign of parsed number:

def offset(arg):
    return -timedelta(hours = arg / 100, minutes = arg % 100)

def normalize(time, offset):
    return time+offset
Andrey
  • 59,039
  • 12
  • 119
  • 163