examples.28_date_parsing
Demonstrates parsing date strings in multiple formats and validating that the resulting date is within an acceptable range.
This example shows:
- How to accept multiple common date formats (ISO, European, etc.).
- How to convert strings into
datetime.dateobjects via a transformation pipeline.- How to use
RangeValueto validate that a parsed date lies within a specified valid range.
Supported formats:
"%Y-%m-%d"→ ISO format (e.g.,"2000-01-31")"%d/%m/%Y"→ European format (e.g.,"31/01/2000")"%d-%b-%Y"→ Month abbreviation (e.g.,"31-Jan-2000")
Run directly:
python examples/28_date_parsing.py
Expected output:
parsed: OK 2000-01-31 in-range: OK
1"""Demonstrates parsing date strings in multiple formats and validating that the 2resulting date is within an acceptable range. 3 4This example shows: 5 * How to accept multiple common date formats (ISO, European, etc.). 6 * How to convert strings into `datetime.date` objects via a transformation pipeline. 7 * How to use :class:`RangeValue` to validate that a parsed date lies within 8 a specified valid range. 9 10Supported formats: 11 * `"%Y-%m-%d"` → ISO format (e.g., `"2000-01-31"`) 12 * `"%d/%m/%Y"` → European format (e.g., `"31/01/2000"`) 13 * `"%d-%b-%Y"` → Month abbreviation (e.g., `"31-Jan-2000"`) 14 15Run directly: 16 17 python examples/28_date_parsing.py 18 19Expected output: 20 21 parsed: OK 2000-01-31 22 in-range: OK 23""" 24 25import sys 26import pathlib 27from datetime import date, datetime 28from typing import List 29 30# --------------------------------------------------------------------------- 31# Make repo root importable when running this file directly 32# --------------------------------------------------------------------------- 33sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1])) 34 35from constrained_values import Response, Status, TypeValidationStrategy, RangeValue 36from constrained_values.value import TransformationStrategy, ConstrainedValue, PipeLineStrategy 37 38 39FORMATS = ["%Y-%m-%d", "%d/%m/%Y", "%d-%b-%Y"] 40 41 42class ToDate(TransformationStrategy[str, date]): 43 """Transform a string into a `datetime.date` object using multiple formats.""" 44 45 def transform(self, value: str) -> Response[date]: 46 """Attempt to parse a date from the input string using known formats. 47 48 Args: 49 value: The input date string. 50 51 Returns: 52 Response[date]: 53 * `status = Status.OK` and the parsed date if successful. 54 * `status = Status.EXCEPTION` and an error message if all formats fail. 55 """ 56 v = value.strip() 57 for fmt in FORMATS: 58 try: 59 parsed = datetime.strptime(v, fmt).date() 60 except ValueError: 61 continue # Try the next format 62 else: 63 return Response(Status.OK, fmt, parsed) 64 return Response(Status.EXCEPTION, f"no matching formats for {v!r}; tried {FORMATS}", None) 65 66 67class BirthDate(ConstrainedValue[date]): 68 """A constrained value that parses and validates date strings.""" 69 70 def get_strategies(self) -> List[PipeLineStrategy]: 71 """Return the transformation pipeline (string → date).""" 72 return [TypeValidationStrategy(str), ToDate()] 73 74 75def main() -> None: 76 """Run the date parsing and range validation demonstration. 77 78 Steps: 79 1. Parse a valid date string using `BirthDate`. 80 2. Validate the parsed date against a valid range using `RangeValue`. 81 82 Prints: 83 * `"parsed: OK 2000-01-31"` 84 * `"in-range: OK"` 85 """ 86 d = BirthDate("2000-01-31") 87 print("parsed:", d.status.name, d.value) 88 r = RangeValue(d.value, date(1900, 1, 1), date(2100, 1, 1)) 89 print("in-range:", r.status.name) 90 91 92if __name__ == "__main__": 93 main()
FORMATS =
['%Y-%m-%d', '%d/%m/%Y', '%d-%b-%Y']
class
ToDate(constrained_values.value.TransformationStrategy[str, datetime.date]):
43class ToDate(TransformationStrategy[str, date]): 44 """Transform a string into a `datetime.date` object using multiple formats.""" 45 46 def transform(self, value: str) -> Response[date]: 47 """Attempt to parse a date from the input string using known formats. 48 49 Args: 50 value: The input date string. 51 52 Returns: 53 Response[date]: 54 * `status = Status.OK` and the parsed date if successful. 55 * `status = Status.EXCEPTION` and an error message if all formats fail. 56 """ 57 v = value.strip() 58 for fmt in FORMATS: 59 try: 60 parsed = datetime.strptime(v, fmt).date() 61 except ValueError: 62 continue # Try the next format 63 else: 64 return Response(Status.OK, fmt, parsed) 65 return Response(Status.EXCEPTION, f"no matching formats for {v!r}; tried {FORMATS}", None)
Transform a string into a datetime.date object using multiple formats.
46 def transform(self, value: str) -> Response[date]: 47 """Attempt to parse a date from the input string using known formats. 48 49 Args: 50 value: The input date string. 51 52 Returns: 53 Response[date]: 54 * `status = Status.OK` and the parsed date if successful. 55 * `status = Status.EXCEPTION` and an error message if all formats fail. 56 """ 57 v = value.strip() 58 for fmt in FORMATS: 59 try: 60 parsed = datetime.strptime(v, fmt).date() 61 except ValueError: 62 continue # Try the next format 63 else: 64 return Response(Status.OK, fmt, parsed) 65 return Response(Status.EXCEPTION, f"no matching formats for {v!r}; tried {FORMATS}", None)
Attempt to parse a date from the input string using known formats.
Arguments:
- value: The input date string.
Returns:
Response[date]: *
status = Status.OKand the parsed date if successful. *status = Status.EXCEPTIONand an error message if all formats fail.
class
BirthDate(constrained_values.value.ConstrainedValue[datetime.date]):
68class BirthDate(ConstrainedValue[date]): 69 """A constrained value that parses and validates date strings.""" 70 71 def get_strategies(self) -> List[PipeLineStrategy]: 72 """Return the transformation pipeline (string → date).""" 73 return [TypeValidationStrategy(str), ToDate()]
A constrained value that parses and validates date strings.
def
get_strategies(self) -> List[constrained_values.value.PipeLineStrategy]:
71 def get_strategies(self) -> List[PipeLineStrategy]: 72 """Return the transformation pipeline (string → date).""" 73 return [TypeValidationStrategy(str), ToDate()]
Return the transformation pipeline (string → date).
Inherited Members
- constrained_values.value.ConstrainedValue
- ConstrainedValue
- status
- details
- value
- unwrap
- ok
def
main() -> None:
76def main() -> None: 77 """Run the date parsing and range validation demonstration. 78 79 Steps: 80 1. Parse a valid date string using `BirthDate`. 81 2. Validate the parsed date against a valid range using `RangeValue`. 82 83 Prints: 84 * `"parsed: OK 2000-01-31"` 85 * `"in-range: OK"` 86 """ 87 d = BirthDate("2000-01-31") 88 print("parsed:", d.status.name, d.value) 89 r = RangeValue(d.value, date(1900, 1, 1), date(2100, 1, 1)) 90 print("in-range:", r.status.name)
Run the date parsing and range validation demonstration.
Steps:
- Parse a valid date string using
BirthDate.- Validate the parsed date against a valid range using
RangeValue.
Prints:
"parsed: OK 2000-01-31""in-range: OK"