我们最近将我们的网站升级为plone 4,并注意到如果日期早于1970年我们的日历选择器不起作用。经过小调试后,注意到这一行是问题
plone.app.form.widgets.datecomponents.py -> result method
日期少于1970 date.timeTime
结果为负值,而本地时间方法期望正值我假设。
local_zone = date.localZone(localtime(date.timeTime()))
任何帮助,想法或建议总是好的
这是追溯
Traceback (innermost last):
Module ZPublisher.Publish, line 126, in publish
Module ZPublisher.mapply, line 77, in mapply
Module ZPublisher.Publish, line 46, in call_object
Module Products.CMFFormController.ControllerPageTemplate, line 75, in __call__
Module Products.CMFFormController.BaseControllerPageTemplate, line 31, in _call
Module Shared.DC.Scripts.Bindings, line 322, in __call__
Module Shared.DC.Scripts.Bindings, line 359, in _bindAndExec
Module Products.PageTemplates.ZopePageTemplate, line 334, in _exec
Module Products.PageTemplates.ZopePageTemplate, line 431, in pt_render
Module Products.PageTemplates.PageTemplate, line 79, in pt_render
Module zope.pagetemplate.pagetemplate, line 113, in pt_render
Module zope.tal.talinterpreter, line 271, in __call__
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 888, in do_useMacro
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 954, in do_defineSlot
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 858, in do_defineMacro
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 954, in do_defineSlot
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 946, in do_defineSlot
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 821, in do_loop_tal
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 888, in do_useMacro
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 583, in do_setLocal_tal
Module zope.tales.tales, line 696, in evaluate
- URL: calendar_macros
- Line 12, Column 4
- Expression: <PythonExpr date_components_support_view.result(inputvalue, 0, starting_year, ending_year, future_years)>
- Names:
{'container': <ATFolder at /rcseng/account>,
'context': <ATFolder at /rcseng/account>,
'default': <object object at 0x01DE1830>,
'here': <ATFolder at /rcseng/account>,
'loop': {u'record': <Products.PageTemplates.Expressions.PathIterator object at 0x0E0BEAB0>},
'nothing': None,
'options': {'args': (),
'state': <Products.CMFFormController.ControllerState.ControllerState object at 0x0E287F30>},
'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x0E21E810>,
'request': <HTTPRequest, URL=http://dev.rcseng.ac.uk/account/my_details>,
'root': <Application at >,
'template': <ControllerPageTemplate at /rcseng/account/my_details>,
'traverse_subpath': [],
'user': <PloneUser '227225'>}
Module Products.PageTemplates.ZRPythonExpr, line 48, in __call__
- __traceback_info__: date_components_support_view.result(inputvalue, 0, starting_year, ending_year, future_years)
Module PythonExpr, line 1, in <expression>
Module plone.app.form.widgets.datecomponents, line 97, in result
ValueError: (22, 'Invalid argument')
答案 0 :(得分:3)
进一步调查后,确实可以重现您报告的问题。我能够在大多数平台上进入pre-epoch(1970年1月1日)日期,除了 Windows。
确实如此,Zope的DateTime实例在纪元之前的时间戳使用负的第二个值,但Python的time.localtime
通常处理负值就好了:
>>> import time
>>> time.localtime(-10000)
time.struct_time(tm_year=1969, tm_mon=12, tm_mday=31, tm_hour=22, tm_min=13, tm_sec=20, tm_wday=2, tm_yday=365, tm_isdst=0)
我在Mac,FreeBSD和Linux上的几个python 2.x版本中测试了这个。但是,在Windows上测试时,确实会出现ValueError。请注意,这是python和Plone版本的问题,这是Windows特有的问题!
有问题的代码正在尝试确定给定日期的当地时区,可能是夏令时(夏令时)或冬令时。因此,在Windows上,我们还可以将日期中的年份换成当前年份,以便进行此计算。 可能可能会导致DST计算错误,具体取决于确切的本地时区,但由于无法正确计算1970年以前的日期 ,这是一个很好的折衷方案。
我刚刚将第97行替换为git(commit 63b043a7ba):
try:
local_zone = date.localZone(localtime(date.timeTime()))
except ValueError:
# Dates before 1970 use a negative timeTime() value, which on
# on some platforms are not handled well and lead to a ValueError.
# In those cases, calculate the local timezone (which is DST based)
# from the same date in the *current year* instead. This is better
# than failing altogether!
timeZoneDate = DateTime(localtime().tm_year, *date.parts()[1:])
local_zone = date.localZone(localtime(timeZoneDate.timeTime()))
在你当地的鸡蛋中使用它,或等待包的2.1分支的新版本。