comparison sat/tools/datetime.py @ 3878:32087d7c25d4

tools (datetime, utils): fix incorrect use of naive object: `tools.datetime.format_datetime` was expecting aware datetime objects while `tools.utils.xmpp_date` was returning naive datetime objects. A check has been added to the former one, and latter one has been modified to return aware datetime objects.
author Goffi <goffi@goffi.org>
date Wed, 31 Aug 2022 13:11:26 +0200
parents 00212260f659
children
comparison
equal deleted inserted replaced
3877:00212260f659 3878:32087d7c25d4
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 # Type-check with `mypy --strict` 19 # Type-check with `mypy --strict`
20 # Lint with `pylint` 20 # Lint with `pylint`
21 21
22 from sat.core import exceptions
22 from datetime import date, datetime, time, timezone 23 from datetime import date, datetime, time, timezone
23 import re 24 import re
24 from typing import Optional, Tuple 25 from typing import Optional, Tuple
25 26
26 27
93 value: Optional[datetime] = None, 94 value: Optional[datetime] = None,
94 include_microsecond: bool = False 95 include_microsecond: bool = False
95 ) -> str: 96 ) -> str:
96 """ 97 """
97 @param value: The datetime to format. Defaults to the current datetime. 98 @param value: The datetime to format. Defaults to the current datetime.
99 must be an aware datetime object (timezone must be specified)
98 @param include_microsecond: Include the microsecond of the datetime in the output. 100 @param include_microsecond: Include the microsecond of the datetime in the output.
99 @return: The datetime formatted according to the DateTime profile specified in 101 @return: The datetime formatted according to the DateTime profile specified in
100 XEP-0082. The datetime is always converted to UTC before formatting to avoid 102 XEP-0082. The datetime is always converted to UTC before formatting to avoid
101 leaking geographical information of the sender. 103 leaking geographical information of the sender.
102 """ 104 """
103 # CCYY-MM-DDThh:mm:ss[.sss]TZD 105 # CCYY-MM-DDThh:mm:ss[.sss]TZD
104 106
105 # We format the time in UTC, since the %z formatter of strftime doesn't include colons 107 # We format the time in UTC, since the %z formatter of strftime doesn't include colons
106 # to separate hours and minutes which is required by XEP-0082. UTC allows us to put a 108 # to separate hours and minutes which is required by XEP-0082. UTC allows us to put a
107 # simple letter 'Z' as the time zone definition. 109 # simple letter 'Z' as the time zone definition.
108 value = ( 110 if value is not None:
109 datetime.now(timezone.utc) 111 if value.tzinfo is None:
110 if value is None 112 raise exceptions.InternalError(
111 else value.astimezone(timezone.utc) # pylint: disable=no-member 113 "an aware datetime object must be used, but a naive one has been provided"
112 ) 114 )
115 value = value.astimezone(timezone.utc) # pylint: disable=no-member
116 else:
117 value = datetime.now(timezone.utc)
113 118
114 if include_microsecond: 119 if include_microsecond:
115 return value.strftime("%Y-%m-%dT%H:%M:%S.%fZ") 120 return value.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
116 121
117 return value.strftime("%Y-%m-%dT%H:%M:%SZ") 122 return value.strftime("%Y-%m-%dT%H:%M:%SZ")