:param datetime timestamp: optional datetime value to use instead of
the current date and time (must be a
datetime, regular dates can't be converted
- between timezones.)"""
+ between timezones.)
+ :param dict context: the 'tz' key in the context should give the
+ name of the User/Client timezone (otherwise
+ UTC is used)
+ :rtype: str
+ """
today = timestamp or DT.datetime.now()
context_today = None
if context and context.get('tz'):
try:
utc = pytz.timezone('UTC')
context_tz = pytz.timezone(context['tz'])
- utc_today = utc.localize(today, is_dst=False)
+ utc_today = utc.localize(today, is_dst=False) # UTC = no DST
context_today = utc_today.astimezone(context_tz)
except Exception:
_logger.debug("failed to compute context/client-specific today date, "
return DT.datetime.now().strftime(
tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ @staticmethod
+ def context_timestamp(cr, uid, timestamp, context=None):
+ """Returns the given timestamp converted to the client's timezone.
+ This method is *not* meant for use as a _defaults initializer,
+ because datetime fields are automatically converted upon
+ display on client side. For _defaults you :meth:`fields.datetime.now`
+ should be used instead.
+
+ :param datetime timestamp: naive datetime value (expressed in UTC)
+ to be converted to the client timezone
+ :param dict context: the 'tz' key in the context should give the
+ name of the User/Client timezone (otherwise
+ UTC is used)
+ :rtype: datetime
+ :return: timestamp converted to timezone-aware datetime in context
+ timezone
+ """
+ assert isinstance(timestamp, DT.datetime), 'Datetime instance expected'
+ if context and context.get('tz'):
+ try:
+ utc = pytz.timezone('UTC')
+ context_tz = pytz.timezone(context['tz'])
+ utc_timestamp = utc.localize(timestamp, is_dst=False) # UTC = no DST
+ return utc_timestamp.astimezone(context_tz)
+ except Exception:
+ _logger.debug("failed to compute context/client-specific timestamp, "
+ "using the UTC value",
+ exc_info=True)
+ return timestamp
+
class time(_column):
_type = 'time'
_deprecated = True
import openerp.tools as tools
import zipfile
import common
-from openerp.osv.fields import float as float_class, function as function_class
+from openerp.osv.fields import float as float_field, function as function_field, datetime as datetime_field
from openerp.tools.translate import _
+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
_logger = logging.getLogger(__name__)
-DT_FORMAT = '%Y-%m-%d'
-DHM_FORMAT = '%Y-%m-%d %H:%M:%S'
-HM_FORMAT = '%H:%M:%S'
-
rml_parents = {
'tr':1,
'li':1,
'para': 'p',
}
-def get_date_length(date_format=DT_FORMAT):
+def get_date_length(date_format=DEFAULT_SERVER_DATE_FORMAT):
return len((datetime.now()).strftime(date_format))
class _format(object):
def __str__(self):
if self.val:
if getattr(self,'name', None):
- date = datetime.strptime(self.name[:get_date_length()], DT_FORMAT)
+ date = datetime.strptime(self.name[:get_date_length()], DEFAULT_SERVER_DATE_FORMAT)
return date.strftime(str(self.lang_obj.date_format))
return self.val
def __str__(self):
if self.val and getattr(self,'name', None):
- return datetime.strptime(self.name, DHM_FORMAT)\
+ return datetime.strptime(self.name, DEFAULT_SERVER_DATETIME_FORMAT)\
.strftime("%s %s"%(str(self.lang_obj.date_format),
str(self.lang_obj.time_format)))
return self.val
else:
d = res_digits(self.cr)[1]
elif (hasattr(obj, '_field') and\
- isinstance(obj._field, (float_class, function_class)) and\
+ isinstance(obj._field, (float_field, function_field)) and\
obj._field.digits):
d = obj._field.digits[1] or DEFAULT_DIGITS
return d
return ''
date_format = self.lang_dict['date_format']
- parse_format = DT_FORMAT
+ parse_format = DEFAULT_SERVER_DATE_FORMAT
if date_time:
- value=value.split('.')[0]
+ value = value.split('.')[0]
date_format = date_format + " " + self.lang_dict['time_format']
- parse_format = DHM_FORMAT
- if not isinstance(value, time.struct_time):
- return time.strftime(date_format, time.strptime(value[:get_date_length(parse_format)], parse_format))
-
+ parse_format = DEFAULT_SERVER_DATETIME_FORMAT
+ if isinstance(value, basestring):
+ date = datetime.strptime(value[:get_date_length(parse_format)], parse_format)
+ elif isinstance(value, time.struct_time):
+ date = datetime(*value[:6])
else:
date = datetime(*value.timetuple()[:6])
+ if date_time:
+ # Convert datetime values to the expected client/context timezone
+ date = datetime_field.context_timestamp(self.cr, self.uid,
+ timestamp=date,
+ context=self.localcontext)
return date.strftime(date_format)
res = self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)