[FIX] treat imported datetime as local to the context-provided or user's datetime
bzr revid: xmo@openerp.com-20121009085446-obfpn4c5r250zonc
This commit is contained in:
parent
35c0e73eb4
commit
10345423b1
|
@ -1,10 +1,14 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
import functools
|
||||
import operator
|
||||
import itertools
|
||||
import psycopg2
|
||||
import time
|
||||
from openerp.osv import orm, fields
|
||||
|
||||
import psycopg2
|
||||
import pytz
|
||||
|
||||
from openerp.osv import orm
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools.misc import DEFAULT_SERVER_DATE_FORMAT,\
|
||||
DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
@ -131,16 +135,42 @@ class ir_fields_converter(orm.Model):
|
|||
'moreinfo': _(u"Use the format '%s'") % u"2012-12-31"
|
||||
})
|
||||
|
||||
def _input_tz(self, cr, uid, context):
|
||||
# if there's a tz in context, try to use that
|
||||
if context.get('tz'):
|
||||
try:
|
||||
return pytz.timezone(context['tz'])
|
||||
except pytz.UnknownTimeZoneError:
|
||||
pass
|
||||
|
||||
# if the current user has a tz set, try to use that
|
||||
user = self.pool['res.users'].read(
|
||||
cr, uid, [uid], ['tz'], context=context)[0]
|
||||
if user['tz']:
|
||||
try:
|
||||
return pytz.timezone(user['tz'])
|
||||
except pytz.UnknownTimeZoneError:
|
||||
pass
|
||||
|
||||
# fallback if no tz in context or on user: UTC
|
||||
return pytz.UTC
|
||||
|
||||
def _str_to_datetime(self, cr, uid, model, column, value, context=None):
|
||||
if context is None: context = {}
|
||||
try:
|
||||
time.strptime(value, DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
return value, []
|
||||
parsed_value = datetime.datetime.strptime(
|
||||
value, DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
except ValueError:
|
||||
raise ValueError(
|
||||
_(u"'%s' does not seem to be a valid datetime for field '%%(field)s'") % value, {
|
||||
'moreinfo': _(u"Use the format '%s'") % u"2012-12-31 23:59:59"
|
||||
})
|
||||
|
||||
input_tz = self._input_tz(cr, uid, context)# Apply input tz to the parsed naive datetime
|
||||
dt = input_tz.localize(parsed_value, is_dst=False)
|
||||
# And convert to UTC before reformatting for writing
|
||||
return dt.astimezone(pytz.UTC).strftime(DEFAULT_SERVER_DATETIME_FORMAT), []
|
||||
|
||||
def _get_translations(self, cr, uid, types, src, context):
|
||||
types = tuple(types)
|
||||
# Cache translations so they don't have to be reloaded from scratch on
|
||||
|
|
|
@ -1039,5 +1039,54 @@ class test_datetime(ImporterCase):
|
|||
moreinfo=u"Use the format '2012-12-31 23:59:59'")])
|
||||
self.assertIs(result['ids'], False)
|
||||
|
||||
# function, related, reference: written to db as-is...
|
||||
# => function uses @type for value coercion/conversion
|
||||
def test_checktz1(self):
|
||||
""" Imported date should be interpreted as being in the tz provided by
|
||||
the context
|
||||
"""
|
||||
# write dummy tz in user (Asia/Hovd UTC+0700), should be superseded by
|
||||
# context
|
||||
self.registry('res.users').write(
|
||||
self.cr, openerp.SUPERUSER_ID, [openerp.SUPERUSER_ID],
|
||||
{'tz': 'Asia/Hovd'})
|
||||
|
||||
# UTC+1400
|
||||
result = self.import_(
|
||||
['value'], [['2012-02-03 11:11:11']], {'tz': 'Pacific/Kiritimati'})
|
||||
self.assertFalse(result['messages'])
|
||||
self.assertEqual(
|
||||
values(self.read(domain=[('id', 'in', result['ids'])])),
|
||||
['2012-02-02 21:11:11'])
|
||||
|
||||
# UTC-0930
|
||||
result = self.import_(
|
||||
['value'], [['2012-02-03 11:11:11']], {'tz': 'Pacific/Marquesas'})
|
||||
self.assertFalse(result['messages'])
|
||||
self.assertEqual(
|
||||
values(self.read(domain=[('id', 'in', result['ids'])])),
|
||||
['2012-02-03 20:41:11'])
|
||||
|
||||
def test_usertz(self):
|
||||
""" If the context does not hold a timezone, the importing user's tz
|
||||
should be used
|
||||
"""
|
||||
# UTC +1000
|
||||
self.registry('res.users').write(
|
||||
self.cr, openerp.SUPERUSER_ID, [openerp.SUPERUSER_ID],
|
||||
{'tz': 'Asia/Yakutsk'})
|
||||
|
||||
result = self.import_(
|
||||
['value'], [['2012-02-03 11:11:11']])
|
||||
self.assertFalse(result['messages'])
|
||||
self.assertEqual(
|
||||
values(self.read(domain=[('id', '=', result['ids'])])),
|
||||
['2012-02-03 01:11:11'])
|
||||
|
||||
def test_notz(self):
|
||||
""" If there is no tz either in the context or on the user, falls back
|
||||
to UTC
|
||||
"""
|
||||
result = self.import_(['value'], [['2012-02-03 11:11:11']])
|
||||
self.assertFalse(result['messages'])
|
||||
self.assertEqual(
|
||||
values(self.read(domain=[('id', '=', result['ids'])])),
|
||||
['2012-02-03 11:11:11'])
|
||||
|
|
Loading…
Reference in New Issue