[date] Fix utcdatetime

Dates with a tzinfo get messed up by utcdatetime.

The unittest in this patch depends on pytz.

Closes #280794

authorChristophe de Vienne <christophe@unlish.com>
changeset123b72695560
branchdefault
phasepublic
hiddenno
parent revision#31725b8fa3f5 [coverage] Provides better tools to pause tracing
child revision#33bd3d623d2b [daemon] change umask after creating pid file
files modified by this revision
date.py
test/unittest_date.py
# HG changeset patch
# User Christophe de Vienne <christophe@unlish.com>
# Date 1417098588 -3600
# Thu Nov 27 15:29:48 2014 +0100
# Node ID 123b72695560acdabcbf4af77ccc36ea0a24e972
# Parent 31725b8fa3f58b94742899a20d939a781a65be42
[date] Fix utcdatetime

Dates with a tzinfo get messed up by utcdatetime.

The unittest in this patch depends on pytz.

Closes #280794

diff --git a/date.py b/date.py
@@ -312,11 +312,11 @@
1              return unicode(fmt) % fields
2 
3  def utcdatetime(dt):
4      if dt.tzinfo is None:
5          return dt
6 -    return datetime(*dt.utctimetuple()[:7])
7 +    return (dt.replace(tzinfo=None) - dt.utcoffset())
8 
9  def utctime(dt):
10      if dt.tzinfo is None:
11          return dt
12      return (dt + dt.utcoffset() + dt.dst()).replace(tzinfo=None)
diff --git a/test/unittest_date.py b/test/unittest_date.py
@@ -20,13 +20,14 @@
13  """
14  from logilab.common.testlib import TestCase, unittest_main, tag
15 
16  from logilab.common.date import date_range, endOfMonth
17  from logilab.common.date import add_days_worked, nb_open_days, \
18 -         get_national_holidays, ustrftime, ticks2datetime
19 +         get_national_holidays, ustrftime, ticks2datetime, utcdatetime
20 
21  from datetime import date, datetime, timedelta
22 +import pytz
23 
24  try:
25      from mx.DateTime import Date as mxDate, DateTime as mxDateTime, \
26           now as mxNow, RelativeDateTime, RelativeDate
27  except ImportError:
@@ -143,10 +144,30 @@
28          r = list(date_range(self.datecls(2006, 5, 6), self.datecls(2006, 8, 27),
29                              incmonth=True))
30          expected = [self.datecls(2006, 5, 6), self.datecls(2006, 6, 1), self.datecls(2006, 7, 1), self.datecls(2006, 8, 1)]
31          self.assertListEqual(expected, r)
32 
33 +    def test_utcdatetime(self):
34 +        if self.datetimecls is mxDateTime:
35 +            raise self.skipTest('standard datetime only test')
36 +        d = self.datetimecls(2014, 11, 26, 12, 0, 0, 57, tzinfo=pytz.utc)
37 +        d = utcdatetime(d)
38 +        self.assertEqual(d, self.datetimecls(2014, 11, 26, 12, 0, 0, 57))
39 +        self.assertIsNone(d.tzinfo)
40 +
41 +        d = pytz.timezone('Europe/Paris').localize(
42 +            self.datetimecls(2014, 11, 26, 12, 0, 0, 57))
43 +        d = utcdatetime(d)
44 +        self.assertEqual(d, self.datetimecls(2014, 11, 26, 11, 0, 0, 57))
45 +        self.assertIsNone(d.tzinfo)
46 +
47 +        d = pytz.timezone('Europe/Paris').localize(
48 +            self.datetimecls(2014, 7, 26, 12, 0, 0, 57))
49 +        d = utcdatetime(d)
50 +        self.assertEqual(d, self.datetimecls(2014, 7, 26, 10, 0, 0, 57))
51 +        self.assertIsNone(d.tzinfo)
52 +
53 
54  class MxDateTC(DateTC):
55      datecls = mxDate
56      datetimecls = mxDateTime
57      timedeltacls = RelativeDateTime