Plone日历对于小于1970年的年份无效参数

Plone日历对于小于1970年的年份无效参数,plone,Plone,我们最近将我们的网站升级到了plone 4,并注意到如果日期早于1970年,我们的日历选择器将无法工作。经过小调试,注意到这条线有问题 plone.app.form.widgets.datecomponents.py -> result method 对于小于1970的日期date.timeTimeresult负值,我假设localtime方法期望正值 local_zone = date.localZone(localtime(date.timeTime())) 任何帮助、想法或建议都

我们最近将我们的网站升级到了plone 4,并注意到如果日期早于1970年,我们的日历选择器将无法工作。经过小调试,注意到这条线有问题

plone.app.form.widgets.datecomponents.py -> result method
对于小于1970的日期
date.timeTime
result负值,我假设localtime方法期望正值

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')
回溯(最里面的最后一个):
发布中的模块ZPublisher.Publish,第126行
模块ZPublisher.mapply,第77行,在mapply中
模块ZPublisher.Publish,第46行,在call_对象中
模块Products.CMFFormController.ControllerPageTemplate,第75行,输入调用__
模块Products.CMFFormController.BaseControllerPageTemplate,第31行,in\U调用
模块Shared.DC.Scripts.Bindings,第322行,在调用中__
模块Shared.DC.Scripts.Bindings,第359行,在_bindAndExec中
模块Products.PageTemplates.ZopePageTemplate,第334行,in_exec
pt_render中模块Products.PageTemplates.ZopePageTemplate,第431行
模块Products.PageTemplates.PageTemplate,第79行,在pt_render中
模块zope.pagetemplate.pagetemplate,第113行,在pt_渲染中
模块zope.tal.t interpreter,第271行,输入调用__
模块zope.tal.t解释程序第343行
do_useMacro中的模块zope.tal.tInterpreter,第888行
模块zope.tal.t解释程序第343行
do_optTag_tal中模块zope.tal.tInterpreter,第533行
do_optTag中第518行模块zope.tal.tInterpreter
模块zope.tal.tInterpreter,第513行,无标签
模块zope.tal.t解释程序第343行
do_defineSlot中模块zope.tal.tInterpreter,第954行
模块zope.tal.t解释程序第343行
do_optTag_tal中模块zope.tal.tInterpreter,第533行
do_optTag中第518行模块zope.tal.tInterpreter
模块zope.tal.tInterpreter,第513行,无标签
模块zope.tal.t解释程序第343行
模块zope.tal.tInterpreter,第858行,在do_defineMacro中
模块zope.tal.t解释程序第343行
do_defineSlot中模块zope.tal.tInterpreter,第954行
模块zope.tal.t解释程序第343行
do_optTag_tal中模块zope.tal.tInterpreter,第533行
do_optTag中第518行模块zope.tal.tInterpreter
模块zope.tal.tInterpreter,第513行,无标签
模块zope.tal.t解释程序第343行
模块zope.tal.t Interpreter,第946行,在do_defineSlot中
模块zope.tal.t解释程序第343行
do_optTag_tal中模块zope.tal.tInterpreter,第533行
do_optTag中第518行模块zope.tal.tInterpreter
模块zope.tal.tInterpreter,第513行,无标签
模块zope.tal.t解释程序第343行
模块zope.tal.tInterpreter,第821行,在do_循环中
模块zope.tal.t解释程序第343行
do_optTag_tal中模块zope.tal.tInterpreter,第533行
do_optTag中第518行模块zope.tal.tInterpreter
模块zope.tal.tInterpreter,第513行,无标签
模块zope.tal.t解释程序第343行
do_useMacro中的模块zope.tal.tInterpreter,第888行
模块zope.tal.t解释程序第343行
do_setLocal_tal中模块zope.tal.tInterpreter,第583行
模块zope.tales.tales,第696行,在评估中
-URL:calendar\u宏
-第12行第4列
-表达方式:
-姓名:
{'container':,
“上下文”:,
“默认值”:,
“这里”:,
'循环':{u'记录':},
“没有”:没有,
'options':{'args':(),
“state”:},
“重复”:,
“请求”:,
“根”:,
“模板”:,
“遍历子路径”:[],
“用户”:}
模块Products.PageTemplates.ZRPythonExpr,第48行,输入调用__
-\u回溯\u信息\u:日期\u组件\u支持\u视图。结果(inputvalue,0,开始\u年,结束\u年,未来\u年)
模块PythonExpr,第1行,在
模块plone.app.form.widgets.datecomponents,第97行,结果
ValueError:(22,“无效参数”)

进一步调查后,确实可以重现您报告的问题。我可以在除Windows之外的大多数平台上输入纪元之前(1970年1月1日)的日期

确实如此,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():


在您的本地egg中使用它,或者等待包的2.1分支的新版本。

几年前,我在plone2.5项目中使用它来存储1970年之前的日期。嗯。我想知道我们是如何储存这些生日的。。。。DateTime当然应该能够处理1970年以前的年份。不同构造的问题?您可以提供日期,但不能提供时间?datetime没有问题。它处理1970年以前的日期。它的timeTime方法返回负数秒,而localtime方法不喜欢它。不,我确实错了,在内部,它使用负数作为自纪元以来的秒数。会在我有时间的时候更新。更新了答案,Windows
time.localtime()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()))