From c03b4a3522990f077b65fee94fa3e49f85b1cacc Mon Sep 17 00:00:00 2001 From: David Linke Date: Thu, 9 Jan 2025 23:17:31 +0100 Subject: [PATCH] Update date parsing (partially use isodate pkg) isodate is already installed since it is a rdflib dependency --- linkml_runtime/utils/metamodelcore.py | 56 ++++++++++++++------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/linkml_runtime/utils/metamodelcore.py b/linkml_runtime/utils/metamodelcore.py index f46b8d4a..f7a4cab2 100644 --- a/linkml_runtime/utils/metamodelcore.py +++ b/linkml_runtime/utils/metamodelcore.py @@ -6,6 +6,7 @@ from typing import Union, Optional, Tuple from urllib.parse import urlparse +import isodate from rdflib import Literal, BNode, URIRef from rdflib.namespace import is_ncname from rdflib.term import Identifier as rdflib_Identifier @@ -230,13 +231,10 @@ def __new__(cls, value: Union[str, datetime.time, datetime.datetime, Literal]) - if not isinstance(value, datetime.time): value = datetime.time.fromisoformat(value) return datetime.time.fromisoformat(str(value)).isoformat() - except TypeError as e: - pass - except ValueError as e: - pass - if not is_strict(): - return str(value) - raise e + except (TypeError, ValueError) as e: + if is_strict(): + raise e + return str(value) @classmethod def is_valid(cls, value: Union[str, datetime.time, datetime.datetime, Literal]) -> bool: @@ -260,15 +258,13 @@ def __new__(cls, value: Union[str, datetime.date, Literal]) -> str: value = value.value try: if not isinstance(value, datetime.date): - value = datetime.date.fromisoformat(str(value)) + # value = datetime.date.fromisoformat(str(value)) + value = isodate.parse_date(value) return value.isoformat() - except TypeError as e: - pass - except ValueError as e: - pass - if not is_strict(): - return str(value) - raise e + except (TypeError, ValueError) as e: + if is_strict(): + raise e + return str(value) @classmethod def is_valid(cls, value: Union[str, datetime.date, Literal]) -> bool: @@ -279,7 +275,8 @@ def is_valid(cls, value: Union[str, datetime.date, Literal]) -> bool: if not re.match(r'^\d{4}-\d{2}-\d{2}$', value): return False try: - datetime.date.fromisoformat(str(value)) + # datetime.date.fromisoformat(str(value)) + value = isodate.parse_date(value) except ValueError: return False return True @@ -294,15 +291,16 @@ def __new__(cls, value: Union[str, datetime.datetime, Literal]) -> str: value = value.value try: if not isinstance(value, datetime.datetime): - value = datetime.datetime.fromisoformat(value) # Note that this handles non 'T' format as well + # value = datetime.datetime.fromisoformat(value) # Note that this handles non 'T' format as well + if "T" in str(value): + value = isodate.parse_datetime(value) + else: + value = isodate.parse_datetime("T".join(value.strip().split(' ', 1))) return value.isoformat() - except TypeError as e: - pass - except ValueError as e: - pass - if not is_strict(): - return str(value) - raise e + except (TypeError, ValueError) as e: + if is_strict(): + raise e + return str(value) @classmethod def is_valid(cls, value: Union[str, datetime.datetime, Literal]) -> bool: @@ -311,8 +309,14 @@ def is_valid(cls, value: Union[str, datetime.datetime, Literal]) -> bool: if isinstance(value, datetime.datetime): value = value.isoformat() try: - datetime.datetime.fromisoformat(value) - except ValueError: + # datetime.datetime.fromisoformat(value) + if "T" in str(value): + isodate.parse_datetime(value) + elif " " in value.strip(): + isodate.parse_datetime("T".join(value.strip().split(' ', 1))) + else: + datetime.datetime.fromisoformat(value) + except (ValueError, TypeError): return False return True