Commit 10536ddb authored by Andreas Jung's avatar Andreas Jung

merge from ajung-european-datetime-support-branch

parent 1635ca94
...@@ -22,6 +22,14 @@ Zope Changes ...@@ -22,6 +22,14 @@ Zope Changes
support for obtaining a more useful value from other headers if a support for obtaining a more useful value from other headers if a
front-end proxy is in use. See doc/ENVIRONMENT.txt for details. front-end proxy is in use. See doc/ENVIRONMENT.txt for details.
- DateTime module: added support to parse international dateformats. The
Datetime constructor has a new "datefmt" parameter to enforce the
parsing of a date as "us" or "international" date. The new field
descriptor field descriptor "date_international" can be used to
enforce this behaviour inside the ZPublisher. See also
doc/ENVIRONMENT.txt to check with the DATETIME_FORMAT
Bugs Fixed Bugs Fixed
- Collector #771: ZCatalog failed to index DTML Document if the name - Collector #771: ZCatalog failed to index DTML Document if the name
......
...@@ -276,8 +276,6 @@ Structured Text ...@@ -276,8 +276,6 @@ Structured Text
The default level is 3. The default level is 3.
DTML
ZOPE_DTML_REQUEST_AUTOQUOTE ZOPE_DTML_REQUEST_AUTOQUOTE
Set this variable to one of 'no', '0' or 'disabled' to disable Set this variable to one of 'no', '0' or 'disabled' to disable
...@@ -288,6 +286,15 @@ DTML ...@@ -288,6 +286,15 @@ DTML
HTML quoted when interpolated with a <dtml-var> or &dtml-; HTML quoted when interpolated with a <dtml-var> or &dtml-;
construct. construct.
DateTime
DATETIME_FORMAT
Set this variable either to "us" or "international" to force
the DateTime module to parse date strings either with
month before days before year or days before month before
year. If unset the default behaviour of DateTime is untouched
and parses ambigious date formats as US date.
Esoteric Esoteric
......
...@@ -12,16 +12,21 @@ ...@@ -12,16 +12,21 @@
############################################################################## ##############################################################################
"""Encapsulation of date/time values""" """Encapsulation of date/time values"""
__version__='$Revision: 1.84 $'[11:-2] __version__='$Revision: 1.85 $'[11:-2]
import re, math, DateTimeZone import os, re, math, DateTimeZone
from time import time, gmtime, localtime, asctime from time import time, gmtime, localtime, asctime
from time import daylight, timezone, altzone, strftime from time import daylight, timezone, altzone, strftime
from types import InstanceType,IntType,FloatType,StringType,UnicodeType from types import InstanceType,IntType,FloatType,StringType,UnicodeType
try: from time import tzname try: from time import tzname
except: tzname=('UNKNOWN','UNKNOWN') except: tzname=('UNKNOWN','UNKNOWN')
_default_datefmt = os.environ.get('DATETIME_FORMAT', "us").lower()
if not _default_datefmt in ('us', 'international'):
raise ValueError, "DATETIME_FORMAT must be either 'us' or 'international'"
# To control rounding errors, we round system time to the nearest # To control rounding errors, we round system time to the nearest
# millisecond. Then delicate calculations can rely on that the # millisecond. Then delicate calculations can rely on that the
# maximum precision that needs to be preserved is known. # maximum precision that needs to be preserved is known.
...@@ -456,7 +461,7 @@ class DateTime: ...@@ -456,7 +461,7 @@ class DateTime:
__roles__=None __roles__=None
__allow_access_to_unprotected_subobjects__=1 __allow_access_to_unprotected_subobjects__=1
def __init__(self,*args): def __init__(self,*args, **kw):
"""Return a new date-time object """Return a new date-time object
A DateTime object always maintains its value as an absolute A DateTime object always maintains its value as an absolute
...@@ -601,6 +606,13 @@ class DateTime: ...@@ -601,6 +606,13 @@ class DateTime:
effect of this is as if you had taken the value of time.time() effect of this is as if you had taken the value of time.time()
at that time on a machine in the specified timezone). at that time on a machine in the specified timezone).
New in Zope 2.7:
A new keyword parameter "datefmt" can be passed to the
constructor. If set to "international", the constructor
is forced to treat ambigious dates as "days before month
before year". This useful if you need to parse non-US
dates in a reliable way
In any case that a floating point number of seconds is given In any case that a floating point number of seconds is given
or derived, it's rounded to the nearest millisecond. or derived, it's rounded to the nearest millisecond.
...@@ -613,6 +625,9 @@ class DateTime: ...@@ -613,6 +625,9 @@ class DateTime:
timezones recognized by the DateTime module. Recognition of timezones recognized by the DateTime module. Recognition of
timezone names is case-insensitive.""" #' timezone names is case-insensitive.""" #'
datefmt = kw.get('datefmt', _default_datefmt)
assert datefmt in ('us', 'international')
d=t=s=None d=t=s=None
ac=len(args) ac=len(args)
millisecs = None millisecs = None
...@@ -656,7 +671,7 @@ class DateTime: ...@@ -656,7 +671,7 @@ class DateTime:
if arg.find(' ')==-1 and arg[4]=='-': if arg.find(' ')==-1 and arg[4]=='-':
yr,mo,dy,hr,mn,sc,tz=self._parse_iso8601(arg) yr,mo,dy,hr,mn,sc,tz=self._parse_iso8601(arg)
else: else:
yr,mo,dy,hr,mn,sc,tz=self._parse(arg) yr,mo,dy,hr,mn,sc,tz=self._parse(arg, datefmt)
if not self._validDate(yr,mo,dy): if not self._validDate(yr,mo,dy):
...@@ -860,7 +875,7 @@ class DateTime: ...@@ -860,7 +875,7 @@ class DateTime:
tz = self.localZone(ltm) tz = self.localZone(ltm)
return tz return tz
def _parse(self,st): def _parse(self,st, datefmt=_default_datefmt):
# Parse date-time components from a string # Parse date-time components from a string
month=year=tz=tm=None month=year=tz=tm=None
spaces =self.space_chars spaces =self.space_chars
...@@ -987,8 +1002,13 @@ class DateTime: ...@@ -987,8 +1002,13 @@ class DateTime:
day=ints[0] day=ints[0]
month=ints[1] month=ints[1]
else: else:
if datefmt=="us":
day=ints[1] day=ints[1]
month=ints[0] month=ints[0]
else:
day=ints[0]
month=ints[1]
elif ints[0] <= 12: elif ints[0] <= 12:
month=ints[0] month=ints[0]
day=ints[1] day=ints[1]
...@@ -1685,3 +1705,4 @@ class strftimeFormatter: ...@@ -1685,3 +1705,4 @@ class strftimeFormatter:
def Timezones(): def Timezones():
"""Return the list of recognized timezone names""" """Return the list of recognized timezone names"""
return _cache._zlst return _cache._zlst
...@@ -306,6 +306,19 @@ class DateTimeTests(unittest.TestCase): ...@@ -306,6 +306,19 @@ class DateTimeTests(unittest.TestCase):
self.assertEqual(dts[5], "%+03d%02d" % divmod( (-offset/60), 60) ) self.assertEqual(dts[5], "%+03d%02d" % divmod( (-offset/60), 60) )
def testInternationalDateformat(self):
for year in range(1990, 2020):
for month in range (1,13):
for day in range(1,32):
try: d_us = DateTime("%d/%d/%d" % (year,month,day))
except: continue
d_int = DateTime("%d.%d.%d" % (day,month,year), datefmt="international")
self.assertEqual(d_us, d_int)
def test_suite(): def test_suite():
return unittest.makeSuite(DateTimeTests) return unittest.makeSuite(DateTimeTests)
......
...@@ -195,6 +195,13 @@ class DateTime: ...@@ -195,6 +195,13 @@ class DateTime:
effect of this is as if you had taken the value of time.time() effect of this is as if you had taken the value of time.time()
at that time on a machine in the specified timezone). at that time on a machine in the specified timezone).
New in Zope 2.7:
A new keyword parameter "datefmt" can be passed to the
constructor. If set to "international", the constructor
is forced to treat ambigious dates as "days before month
before year". This useful if you need to parse non-US
dates in a reliable way
If a string argument passed to the DateTime constructor cannot be If a string argument passed to the DateTime constructor cannot be
parsed, it will raise DateTime.SyntaxError. Invalid date, time, or parsed, it will raise DateTime.SyntaxError. Invalid date, time, or
timezone components will raise a DateTime.DateTimeError. timezone components will raise a DateTime.DateTimeError.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment