[GRASS-SVN] r71573 - in grass/trunk/lib/python/temporal: . testsuite
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Oct 21 08:01:49 PDT 2017
Author: huhabla
Date: 2017-10-21 08:01:49 -0700 (Sat, 21 Oct 2017)
New Revision: 71573
Modified:
grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
grass/trunk/lib/python/temporal/core.py
grass/trunk/lib/python/temporal/datetime_math.py
grass/trunk/lib/python/temporal/space_time_datasets.py
grass/trunk/lib/python/temporal/temporal_algebra.py
grass/trunk/lib/python/temporal/testsuite/test_doctests.py
Log:
temporal framework: Better datetime string parsing. Parsing of datetime strings is now done in a single place.
Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2017-10-21 13:34:13 UTC (rev 71572)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2017-10-21 15:01:49 UTC (rev 71573)
@@ -26,7 +26,7 @@
from .spatio_temporal_relationships import count_temporal_topology_relationships, \
print_spatio_temporal_topology_relationships, SpatioTemporalTopologyBuilder, \
create_temporal_relation_sql_where_statement
-from .datetime_math import increment_datetime_by_string
+from .datetime_math import increment_datetime_by_string, string_to_datetime
###############################################################################
@@ -2377,13 +2377,9 @@
tstring = row[0]
# Convert the unicode string into the datetime format
if self.is_time_absolute():
- if tstring.find(":") > 0:
- time_format = "%Y-%m-%d %H:%M:%S"
- else:
- time_format = "%Y-%m-%d"
-
- max_start_time = datetime.strptime(
- tstring, time_format)
+ max_start_time = string_to_datetime(tstring)
+ if max_start_time is None:
+ max_start_time = end_time
else:
max_start_time = row[0]
else:
Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py 2017-10-21 13:34:13 UTC (rev 71572)
+++ grass/trunk/lib/python/temporal/core.py 2017-10-21 15:01:49 UTC (rev 71573)
@@ -55,6 +55,7 @@
pass
import atexit
+from datetime import datetime
###############################################################################
@@ -1207,12 +1208,15 @@
elif isinstance(args[count], float):
statement = "%s%f%s" % (statement[0:pos], args[count],
statement[pos + 1:])
+ elif isinstance(args[count], datetime):
+ statement = "%s\'%s\'%s" % (statement[0:pos], str(args[count]),
+ statement[pos + 1:])
else:
# Default is a string, this works for datetime
# objects too
statement = "%s\'%s\'%s" % (statement[0:pos],
str(args[count]),
- statement[pos + 1:])
+ str(statement[pos + 1:]))
count += 1
return statement
Modified: grass/trunk/lib/python/temporal/datetime_math.py
===================================================================
--- grass/trunk/lib/python/temporal/datetime_math.py 2017-10-21 13:34:13 UTC (rev 71572)
+++ grass/trunk/lib/python/temporal/datetime_math.py 2017-10-21 15:01:49 UTC (rev 71573)
@@ -704,23 +704,65 @@
###############################################################################
-def check_datetime_string(time_string):
- """Check if a string can be converted into a datetime object
+def check_datetime_string(time_string, use_dateutil=True):
+ """Check if a string can be converted into a datetime object and return the object
- Supported ISO string formats are:
+ In case datutil is not installed the supported ISO string formats are:
- YYYY-mm-dd
- YYYY-mm-dd HH:MM:SS
+ - YYYY-mm-ddTHH:MM:SS
+ - YYYY-mm-dd HH:MM:SS.s
+ - YYYY-mm-ddTHH:MM:SS.s
Time zones are not supported
+ If dateutil is installed, all string formats of the dateutil module
+ are supported, as well as time zones
+ Time zones are not supported
+
:param time_string: The time string to be checked for conversion
+ :param use_dateutil: Use dateutil if available for datetime string parsing
:return: datetime: object or an error message string in case of an error
+
+ >>> s = "2000-01-01"
+ >>> check_datetime_string(s)
+ datetime.datetime(2000, 1, 1, 0, 0)
+ >>> s = "2000-01-01T10:00:00"
+ >>> check_datetime_string(s)
+ datetime.datetime(2000, 1, 1, 10, 0)
+ >>> s = "2000-01-01 10:00:00"
+ >>> check_datetime_string(s)
+ datetime.datetime(2000, 1, 1, 10, 0)
+ >>> s = "2000-01-01T10:00:00.000001"
+ >>> check_datetime_string(s)
+ datetime.datetime(2000, 1, 1, 10, 0, 0, 1)
+ >>> s = "2000-01-01 10:00:00.000001"
+ >>> check_datetime_string(s)
+ datetime.datetime(2000, 1, 1, 10, 0, 0, 1)
+
+ # using native implementation, ignoring dateutil
+ >>> s = "2000-01-01"
+ >>> check_datetime_string(s, False)
+ datetime.datetime(2000, 1, 1, 0, 0)
+ >>> s = "2000-01-01T10:00:00"
+ >>> check_datetime_string(s, False)
+ datetime.datetime(2000, 1, 1, 10, 0)
+ >>> s = "2000-01-01 10:00:00"
+ >>> check_datetime_string(s, False)
+ datetime.datetime(2000, 1, 1, 10, 0)
+ >>> s = "2000-01-01T10:00:00.000001"
+ >>> check_datetime_string(s, False)
+ datetime.datetime(2000, 1, 1, 10, 0, 0, 1)
+ >>> s = "2000-01-01 10:00:00.000001"
+ >>> check_datetime_string(s, False)
+ datetime.datetime(2000, 1, 1, 10, 0, 0, 1)
+
"""
global has_dateutil
- if has_dateutil:
+ if has_dateutil and use_dateutil is True:
# First check if there is only a single number, which specifies
# relative time. dateutil will interprete a single number as a valid
# time string, so we have to catch this case beforehand
@@ -737,15 +779,25 @@
return time_object
# BC is not supported
- if time_string.find("bc") > 0:
+ if "bc" in time_string > 0:
return _("Dates Before Christ (BC) are not supported")
# BC is not supported
- if time_string.find("+") > 0:
+ if "+" in time_string:
return _("Time zones are not supported")
- if time_string.find(":") > 0:
- time_format = "%Y-%m-%d %H:%M:%S"
+ if ":" in time_string or "T" in time_string:
+ # Check for microseconds
+ if "." in time_string:
+ if "T" in time_string:
+ time_format = "%Y-%m-%dT%H:%M:%S.%f"
+ else:
+ time_format = "%Y-%m-%d %H:%M:%S.%f"
+ else:
+ if "T" in time_string:
+ time_format = "%Y-%m-%dT%H:%M:%S"
+ else:
+ time_format = "%Y-%m-%d %H:%M:%S"
else:
time_format = "%Y-%m-%d"
@@ -764,8 +816,12 @@
- YYYY-mm-dd
- YYYY-mm-dd HH:MM:SS
- - Time zones are not supported
+ - YYYY-mm-ddTHH:MM:SS
+ - YYYY-mm-dd HH:MM:SS.s
+ - YYYY-mm-ddTHH:MM:SS.s
+ Time zones are not supported
+
If dateutil is installed, all string formats of the dateutil module
are supported, as well as time zones
Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py 2017-10-21 13:34:13 UTC (rev 71572)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py 2017-10-21 15:01:49 UTC (rev 71573)
@@ -119,7 +119,7 @@
>>> rmap.get_temporal_extent_as_tuple()
(datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
>>> rmap.get_name()
- u'strds_map_test_case'
+ 'strds_map_test_case'
>>> rmap.get_mapset() == mapset
True
>>> rmap.get_temporal_type()
@@ -452,7 +452,7 @@
>>> r3map.get_temporal_extent_as_tuple()
(datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
>>> r3map.get_name()
- u'str3ds_map_test_case'
+ 'str3ds_map_test_case'
>>> r3map.get_mapset() == mapset
True
>>> r3map.get_temporal_type()
@@ -797,7 +797,7 @@
>>> vmap.get_temporal_extent_as_tuple()
(datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
>>> vmap.get_name()
- u'stvds_map_test_case'
+ 'stvds_map_test_case'
>>> vmap.get_mapset() == mapset
True
>>> vmap.get_temporal_type()
Modified: grass/trunk/lib/python/temporal/temporal_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_algebra.py 2017-10-21 13:34:13 UTC (rev 71572)
+++ grass/trunk/lib/python/temporal/temporal_algebra.py 2017-10-21 15:01:49 UTC (rev 71573)
@@ -463,7 +463,7 @@
from .open_stds import open_new_stds, open_old_stds
from .temporal_operator import TemporalOperatorParser
from spatio_temporal_relationships import SpatioTemporalTopologyBuilder
-from .datetime_math import time_delta_to_relative_time
+from .datetime_math import time_delta_to_relative_time, string_to_datetime
from abstract_space_time_dataset import AbstractSpaceTimeDataset
##############################################################################
@@ -1965,18 +1965,11 @@
# Get value for function name from dictionary.
tfuncval = tfuncdict[tfunc]
# Check if value has to be transferred to datetime object for comparison.
- if tfunc in ["START_DATE", "END_DATE"]:
- timeobj = datetime.strptime(value.replace("\"",""), '%Y-%m-%d')
+ if tfunc in ["START_DATE", "END_DATE", "START_TIME", "END_TIME",
+ "START_DATETIME", "END_DATETIME"]:
+ timeobj = string_to_datetime(value.replace("\"",""))
value = timeobj.date()
boolname = self.eval_datetime_str(tfuncval, comp_op, value)
- elif tfunc in ["START_TIME", "END_TIME"]:
- timeobj = datetime.strptime(value.replace("\"",""), '%H:%M:%S')
- value = timeobj.time()
- boolname = self.eval_datetime_str(tfuncval, comp_op, value)
- elif tfunc in ["START_DATETIME", "END_DATETIME"]:
- timeobj = datetime.strptime(value.replace("\"",""), '%Y-%m-%d %H:%M:%S')
- value = timeobj
- boolname = self.eval_datetime_str(tfuncval, comp_op, value)
else:
boolname = eval(str(tfuncval) + comp_op + str(value))
# Add conditional boolean value to the map.
Modified: grass/trunk/lib/python/temporal/testsuite/test_doctests.py
===================================================================
--- grass/trunk/lib/python/temporal/testsuite/test_doctests.py 2017-10-21 13:34:13 UTC (rev 71572)
+++ grass/trunk/lib/python/temporal/testsuite/test_doctests.py 2017-10-21 15:01:49 UTC (rev 71573)
@@ -24,11 +24,10 @@
tests.addTests(doctest.DocTestSuite(grass.temporal.abstract_map_dataset))
tests.addTests(doctest.DocTestSuite(grass.temporal.abstract_space_time_dataset))
tests.addTests(doctest.DocTestSuite(grass.temporal.base))
- # Unexpected error here
tests.addTests(doctest.DocTestSuite(grass.temporal.core))
tests.addTests(doctest.DocTestSuite(grass.temporal.datetime_math))
# Unexpected error here
- ##tests.addTests(doctest.DocTestSuite(grass.temporal.list_stds))
+ #tests.addTests(doctest.DocTestSuite(grass.temporal.list_stds))
tests.addTests(doctest.DocTestSuite(grass.temporal.metadata))
tests.addTests(doctest.DocTestSuite(grass.temporal.register))
tests.addTests(doctest.DocTestSuite(grass.temporal.space_time_datasets))
More information about the grass-commit
mailing list