datetime.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. """Immutable datetime and date vars."""
  2. from __future__ import annotations
  3. import dataclasses
  4. import sys
  5. from datetime import date, datetime
  6. from typing import TypeVar, Union
  7. from .base import (
  8. CustomVarOperationReturn,
  9. LiteralVar,
  10. Var,
  11. VarData,
  12. var_operation,
  13. var_operation_return,
  14. )
  15. DATETIME_T = TypeVar("DATETIME_T", datetime, date)
  16. datetime_types = Union[datetime, date]
  17. def date_compare_operation(
  18. lhs: Var[datetime_types],
  19. rhs: Var[datetime_types],
  20. strict: bool = False,
  21. ) -> CustomVarOperationReturn[bool]:
  22. """Check if the value is less than the other value.
  23. Args:
  24. lhs: The left-hand side of the operation.
  25. rhs: The right-hand side of the operation.
  26. strict: Whether to use strict comparison.
  27. Returns:
  28. The result of the operation.
  29. """
  30. return var_operation_return(
  31. f"({lhs} { '<' if strict else '<='} {rhs})",
  32. bool,
  33. )
  34. @var_operation
  35. def date_gt_operation(
  36. lhs: Var[datetime_types],
  37. rhs: Var[datetime_types],
  38. ) -> CustomVarOperationReturn:
  39. """Greater than comparison.
  40. Args:
  41. lhs: The left-hand side of the operation.
  42. rhs: The right-hand side of the operation.
  43. Returns:
  44. The result of the operation.
  45. """
  46. return date_compare_operation(rhs, lhs, strict=True)
  47. @var_operation
  48. def date_lt_operation(
  49. lhs: Var[datetime_types],
  50. rhs: Var[datetime_types],
  51. ) -> CustomVarOperationReturn:
  52. """Less than comparison.
  53. Args:
  54. lhs: The left-hand side of the operation.
  55. rhs: The right-hand side of the operation.
  56. Returns:
  57. The result of the operation.
  58. """
  59. return date_compare_operation(lhs, rhs, strict=True)
  60. @var_operation
  61. def date_le_operation(
  62. lhs: Var[datetime_types], rhs: Var[datetime_types]
  63. ) -> CustomVarOperationReturn:
  64. """Less than or equal comparison.
  65. Args:
  66. lhs: The left-hand side of the operation.
  67. rhs: The right-hand side of the operation.
  68. Returns:
  69. The result of the operation.
  70. """
  71. return date_compare_operation(lhs, rhs)
  72. @var_operation
  73. def date_ge_operation(
  74. lhs: Var[datetime_types], rhs: Var[datetime_types]
  75. ) -> CustomVarOperationReturn:
  76. """Greater than or equal comparison.
  77. Args:
  78. lhs: The left-hand side of the operation.
  79. rhs: The right-hand side of the operation.
  80. Returns:
  81. The result of the operation.
  82. """
  83. return date_compare_operation(rhs, lhs)
  84. class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
  85. """A variable that holds a datetime or date object."""
  86. __lt__ = date_lt_operation
  87. __le__ = date_le_operation
  88. __gt__ = date_gt_operation
  89. __ge__ = date_ge_operation
  90. @dataclasses.dataclass(
  91. eq=False,
  92. frozen=True,
  93. **{"slots": True} if sys.version_info >= (3, 10) else {},
  94. )
  95. class LiteralDatetimeVar(LiteralVar, DateTimeVar):
  96. """Base class for immutable datetime and date vars."""
  97. _var_value: datetime | date = dataclasses.field(default=datetime.now())
  98. @classmethod
  99. def create(cls, value: datetime | date, _var_data: VarData | None = None):
  100. """Create a new instance of the class.
  101. Args:
  102. value: The value to set.
  103. Returns:
  104. LiteralDatetimeVar: The new instance of the class.
  105. """
  106. js_expr = f'"{value!s}"'
  107. return cls(
  108. _js_expr=js_expr,
  109. _var_type=type(value),
  110. _var_value=value,
  111. _var_data=_var_data,
  112. )
  113. DATETIME_TYPES = (datetime, date, DateTimeVar)