Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/prop/dt/date.py: 73%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

45 statements  

1"""DATE property type from :rfc:`5545`.""" 

2 

3from datetime import date, datetime 

4from typing import Any, ClassVar 

5 

6from icalendar.compatibility import Self 

7from icalendar.error import JCalParsingError 

8from icalendar.parser import Parameters 

9 

10from .base import TimeBase 

11 

12 

13class vDate(TimeBase): 

14 """Date 

15 

16 Value Name: 

17 DATE 

18 

19 Purpose: 

20 This value type is used to identify values that contain a 

21 calendar date. 

22 

23 Format Definition: 

24 This value type is defined by the following notation: 

25 

26 .. code-block:: text 

27 

28 date = date-value 

29 

30 date-value = date-fullyear date-month date-mday 

31 date-fullyear = 4DIGIT 

32 date-month = 2DIGIT ;01-12 

33 date-mday = 2DIGIT ;01-28, 01-29, 01-30, 01-31 

34 ;based on month/year 

35 

36 Description: 

37 If the property permits, multiple "date" values are 

38 specified as a COMMA-separated list of values. The format for the 

39 value type is based on the [ISO.8601.2004] complete 

40 representation, basic format for a calendar date. The textual 

41 format specifies a four-digit year, two-digit month, and two-digit 

42 day of the month. There are no separator characters between the 

43 year, month, and day component text. 

44 

45 Example: 

46 The following represents July 14, 1997: 

47 

48 .. code-block:: text 

49 

50 19970714 

51 

52 .. code-block:: pycon 

53 

54 >>> from icalendar.prop import vDate 

55 >>> date = vDate.from_ical('19970714') 

56 >>> date.year 

57 1997 

58 >>> date.month 

59 7 

60 >>> date.day 

61 14 

62 """ 

63 

64 default_value: ClassVar[str] = "DATE" 

65 params: Parameters 

66 

67 def __init__(self, dt, params: dict[str, Any] | None = None): 

68 if not isinstance(dt, date): 

69 raise TypeError("Value MUST be a date instance") 

70 self.dt = dt 

71 self.params = Parameters(params or {}) 

72 

73 def to_ical(self): 

74 s = f"{self.dt.year:04}{self.dt.month:02}{self.dt.day:02}" 

75 return s.encode("utf-8") 

76 

77 @staticmethod 

78 def from_ical(ical): 

79 try: 

80 timetuple = ( 

81 int(ical[:4]), # year 

82 int(ical[4:6]), # month 

83 int(ical[6:8]), # day 

84 ) 

85 return date(*timetuple) 

86 except Exception as e: 

87 raise ValueError(f"Wrong date format {ical}") from e 

88 

89 @classmethod 

90 def examples(cls) -> list[Self]: 

91 """Examples of vDate.""" 

92 return [cls(date(2025, 11, 10))] 

93 

94 from icalendar.param import VALUE 

95 

96 def to_jcal(self, name: str) -> list: 

97 """The jCal representation of this property according to :rfc:`7265`.""" 

98 return [ 

99 name, 

100 self.params.to_jcal(), 

101 self.VALUE.lower(), 

102 self.dt.strftime("%Y-%m-%d"), 

103 ] 

104 

105 @classmethod 

106 def parse_jcal_value(cls, jcal: str) -> date: 

107 """Parse a jCal string to a :py:class:`datetime.date`. 

108 

109 Raises: 

110 ~error.JCalParsingError: If it can't parse a date. 

111 """ 

112 JCalParsingError.validate_value_type(jcal, str, cls) 

113 try: 

114 return datetime.strptime(jcal, "%Y-%m-%d").date() 

115 except ValueError as e: 

116 raise JCalParsingError("Cannot parse date.", cls, value=jcal) from e 

117 

118 @classmethod 

119 def from_jcal(cls, jcal_property: list) -> Self: 

120 """Parse jCal from :rfc:`7265`. 

121 

122 Parameters: 

123 jcal_property: The jCal property to parse. 

124 

125 Raises: 

126 ~error.JCalParsingError: If the provided jCal is invalid. 

127 """ 

128 JCalParsingError.validate_property(jcal_property, cls) 

129 with JCalParsingError.reraise_with_path_added(3): 

130 value = cls.parse_jcal_value(jcal_property[3]) 

131 return cls( 

132 value, 

133 params=Parameters.from_jcal_property(jcal_property), 

134 ) 

135 

136 

137__all__ = ["vDate"]