Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/arrow/factory.py: 29%

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

89 statements  

1""" 

2Implements the :class:`ArrowFactory <arrow.factory.ArrowFactory>` class, 

3providing factory methods for common :class:`Arrow <arrow.arrow.Arrow>` 

4construction scenarios. 

5 

6""" 

7 

8import calendar 

9from datetime import date, datetime, timezone 

10from datetime import tzinfo as dt_tzinfo 

11from decimal import Decimal 

12from time import struct_time 

13from typing import Any, List, Optional, Tuple, Type, Union, overload 

14 

15from arrow import parser 

16from arrow.arrow import TZ_EXPR, Arrow 

17from arrow.constants import DEFAULT_LOCALE 

18from arrow.util import is_timestamp, iso_to_gregorian 

19 

20 

21class ArrowFactory: 

22 """A factory for generating :class:`Arrow <arrow.arrow.Arrow>` objects. 

23 

24 :param type: (optional) the :class:`Arrow <arrow.arrow.Arrow>`-based class to construct from. 

25 Defaults to :class:`Arrow <arrow.arrow.Arrow>`. 

26 

27 """ 

28 

29 type: Type[Arrow] 

30 

31 def __init__(self, type: Type[Arrow] = Arrow) -> None: 

32 self.type = type 

33 

34 @overload 

35 def get( 

36 self, 

37 *, 

38 locale: str = DEFAULT_LOCALE, 

39 tzinfo: Optional[TZ_EXPR] = None, 

40 normalize_whitespace: bool = False, 

41 ) -> Arrow: 

42 ... # pragma: no cover 

43 

44 @overload 

45 def get( 

46 self, 

47 __obj: Union[ 

48 Arrow, 

49 datetime, 

50 date, 

51 struct_time, 

52 dt_tzinfo, 

53 int, 

54 float, 

55 str, 

56 Tuple[int, int, int], 

57 ], 

58 *, 

59 locale: str = DEFAULT_LOCALE, 

60 tzinfo: Optional[TZ_EXPR] = None, 

61 normalize_whitespace: bool = False, 

62 ) -> Arrow: 

63 ... # pragma: no cover 

64 

65 @overload 

66 def get( 

67 self, 

68 __arg1: Union[datetime, date], 

69 __arg2: TZ_EXPR, 

70 *, 

71 locale: str = DEFAULT_LOCALE, 

72 tzinfo: Optional[TZ_EXPR] = None, 

73 normalize_whitespace: bool = False, 

74 ) -> Arrow: 

75 ... # pragma: no cover 

76 

77 @overload 

78 def get( 

79 self, 

80 __arg1: str, 

81 __arg2: Union[str, List[str]], 

82 *, 

83 locale: str = DEFAULT_LOCALE, 

84 tzinfo: Optional[TZ_EXPR] = None, 

85 normalize_whitespace: bool = False, 

86 ) -> Arrow: 

87 ... # pragma: no cover 

88 

89 def get(self, *args: Any, **kwargs: Any) -> Arrow: 

90 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object based on flexible inputs. 

91 

92 :param locale: (optional) a ``str`` specifying a locale for the parser. Defaults to 'en-us'. 

93 :param tzinfo: (optional) a :ref:`timezone expression <tz-expr>` or tzinfo object. 

94 Replaces the timezone unless using an input form that is explicitly UTC or specifies 

95 the timezone in a positional argument. Defaults to UTC. 

96 :param normalize_whitespace: (optional) a ``bool`` specifying whether or not to normalize 

97 redundant whitespace (spaces, tabs, and newlines) in a datetime string before parsing. 

98 Defaults to false. 

99 

100 Usage:: 

101 

102 >>> import arrow 

103 

104 **No inputs** to get current UTC time:: 

105 

106 >>> arrow.get() 

107 <Arrow [2013-05-08T05:51:43.316458+00:00]> 

108 

109 **One** :class:`Arrow <arrow.arrow.Arrow>` object, to get a copy. 

110 

111 >>> arw = arrow.utcnow() 

112 >>> arrow.get(arw) 

113 <Arrow [2013-10-23T15:21:54.354846+00:00]> 

114 

115 **One** ``float`` or ``int``, convertible to a floating-point timestamp, to get 

116 that timestamp in UTC:: 

117 

118 >>> arrow.get(1367992474.293378) 

119 <Arrow [2013-05-08T05:54:34.293378+00:00]> 

120 

121 >>> arrow.get(1367992474) 

122 <Arrow [2013-05-08T05:54:34+00:00]> 

123 

124 **One** ISO 8601-formatted ``str``, to parse it:: 

125 

126 >>> arrow.get('2013-09-29T01:26:43.830580') 

127 <Arrow [2013-09-29T01:26:43.830580+00:00]> 

128 

129 **One** ISO 8601-formatted ``str``, in basic format, to parse it:: 

130 

131 >>> arrow.get('20160413T133656.456289') 

132 <Arrow [2016-04-13T13:36:56.456289+00:00]> 

133 

134 **One** ``tzinfo``, to get the current time **converted** to that timezone:: 

135 

136 >>> arrow.get(tz.tzlocal()) 

137 <Arrow [2013-05-07T22:57:28.484717-07:00]> 

138 

139 **One** naive ``datetime``, to get that datetime in UTC:: 

140 

141 >>> arrow.get(datetime(2013, 5, 5)) 

142 <Arrow [2013-05-05T00:00:00+00:00]> 

143 

144 **One** aware ``datetime``, to get that datetime:: 

145 

146 >>> arrow.get(datetime(2013, 5, 5, tzinfo=tz.tzlocal())) 

147 <Arrow [2013-05-05T00:00:00-07:00]> 

148 

149 **One** naive ``date``, to get that date in UTC:: 

150 

151 >>> arrow.get(date(2013, 5, 5)) 

152 <Arrow [2013-05-05T00:00:00+00:00]> 

153 

154 **One** time.struct time:: 

155 

156 >>> arrow.get(gmtime(0)) 

157 <Arrow [1970-01-01T00:00:00+00:00]> 

158 

159 **One** iso calendar ``tuple``, to get that week date in UTC:: 

160 

161 >>> arrow.get((2013, 18, 7)) 

162 <Arrow [2013-05-05T00:00:00+00:00]> 

163 

164 **Two** arguments, a naive or aware ``datetime``, and a replacement 

165 :ref:`timezone expression <tz-expr>`:: 

166 

167 >>> arrow.get(datetime(2013, 5, 5), 'US/Pacific') 

168 <Arrow [2013-05-05T00:00:00-07:00]> 

169 

170 **Two** arguments, a naive ``date``, and a replacement 

171 :ref:`timezone expression <tz-expr>`:: 

172 

173 >>> arrow.get(date(2013, 5, 5), 'US/Pacific') 

174 <Arrow [2013-05-05T00:00:00-07:00]> 

175 

176 **Two** arguments, both ``str``, to parse the first according to the format of the second:: 

177 

178 >>> arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ') 

179 <Arrow [2013-05-05T12:30:45-05:00]> 

180 

181 **Two** arguments, first a ``str`` to parse and second a ``list`` of formats to try:: 

182 

183 >>> arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss']) 

184 <Arrow [2013-05-05T12:30:45+00:00]> 

185 

186 **Three or more** arguments, as for the direct constructor of an ``Arrow`` object:: 

187 

188 >>> arrow.get(2013, 5, 5, 12, 30, 45) 

189 <Arrow [2013-05-05T12:30:45+00:00]> 

190 

191 """ 

192 

193 arg_count = len(args) 

194 locale = kwargs.pop("locale", DEFAULT_LOCALE) 

195 tz = kwargs.get("tzinfo", None) 

196 normalize_whitespace = kwargs.pop("normalize_whitespace", False) 

197 

198 # if kwargs given, send to constructor unless only tzinfo provided 

199 if len(kwargs) > 1: 

200 arg_count = 3 

201 

202 # tzinfo kwarg is not provided 

203 if len(kwargs) == 1 and tz is None: 

204 arg_count = 3 

205 

206 # () -> now, @ tzinfo or utc 

207 if arg_count == 0: 

208 if isinstance(tz, str): 

209 tz = parser.TzinfoParser.parse(tz) 

210 return self.type.now(tzinfo=tz) 

211 

212 if isinstance(tz, dt_tzinfo): 

213 return self.type.now(tzinfo=tz) 

214 

215 return self.type.utcnow() 

216 

217 if arg_count == 1: 

218 arg = args[0] 

219 if isinstance(arg, Decimal): 

220 arg = float(arg) 

221 

222 # (None) -> raises an exception 

223 if arg is None: 

224 raise TypeError("Cannot parse argument of type None.") 

225 

226 # try (int, float) -> from timestamp @ tzinfo 

227 elif not isinstance(arg, str) and is_timestamp(arg): 

228 if tz is None: 

229 # set to UTC by default 

230 tz = timezone.utc 

231 return self.type.fromtimestamp(arg, tzinfo=tz) 

232 

233 # (Arrow) -> from the object's datetime @ tzinfo 

234 elif isinstance(arg, Arrow): 

235 return self.type.fromdatetime(arg.datetime, tzinfo=tz) 

236 

237 # (datetime) -> from datetime @ tzinfo 

238 elif isinstance(arg, datetime): 

239 return self.type.fromdatetime(arg, tzinfo=tz) 

240 

241 # (date) -> from date @ tzinfo 

242 elif isinstance(arg, date): 

243 return self.type.fromdate(arg, tzinfo=tz) 

244 

245 # (tzinfo) -> now @ tzinfo 

246 elif isinstance(arg, dt_tzinfo): 

247 return self.type.now(tzinfo=arg) 

248 

249 # (str) -> parse @ tzinfo 

250 elif isinstance(arg, str): 

251 dt = parser.DateTimeParser(locale).parse_iso(arg, normalize_whitespace) 

252 return self.type.fromdatetime(dt, tzinfo=tz) 

253 

254 # (struct_time) -> from struct_time 

255 elif isinstance(arg, struct_time): 

256 return self.type.utcfromtimestamp(calendar.timegm(arg)) 

257 

258 # (iso calendar) -> convert then from date @ tzinfo 

259 elif isinstance(arg, tuple) and len(arg) == 3: 

260 d = iso_to_gregorian(*arg) 

261 return self.type.fromdate(d, tzinfo=tz) 

262 

263 else: 

264 raise TypeError(f"Cannot parse single argument of type {type(arg)!r}.") 

265 

266 elif arg_count == 2: 

267 arg_1, arg_2 = args[0], args[1] 

268 

269 if isinstance(arg_1, datetime): 

270 # (datetime, tzinfo/str) -> fromdatetime @ tzinfo 

271 if isinstance(arg_2, (dt_tzinfo, str)): 

272 return self.type.fromdatetime(arg_1, tzinfo=arg_2) 

273 else: 

274 raise TypeError( 

275 f"Cannot parse two arguments of types 'datetime', {type(arg_2)!r}." 

276 ) 

277 

278 elif isinstance(arg_1, date): 

279 # (date, tzinfo/str) -> fromdate @ tzinfo 

280 if isinstance(arg_2, (dt_tzinfo, str)): 

281 return self.type.fromdate(arg_1, tzinfo=arg_2) 

282 else: 

283 raise TypeError( 

284 f"Cannot parse two arguments of types 'date', {type(arg_2)!r}." 

285 ) 

286 

287 # (str, format) -> parse @ tzinfo 

288 elif isinstance(arg_1, str) and isinstance(arg_2, (str, list)): 

289 dt = parser.DateTimeParser(locale).parse( 

290 args[0], args[1], normalize_whitespace 

291 ) 

292 return self.type.fromdatetime(dt, tzinfo=tz) 

293 

294 else: 

295 raise TypeError( 

296 f"Cannot parse two arguments of types {type(arg_1)!r} and {type(arg_2)!r}." 

297 ) 

298 

299 # 3+ args -> datetime-like via constructor 

300 else: 

301 return self.type(*args, **kwargs) 

302 

303 def utcnow(self) -> Arrow: 

304 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC time. 

305 

306 Usage:: 

307 

308 >>> import arrow 

309 >>> arrow.utcnow() 

310 <Arrow [2013-05-08T05:19:07.018993+00:00]> 

311 """ 

312 

313 return self.type.utcnow() 

314 

315 def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow: 

316 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in the given 

317 timezone. 

318 

319 :param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to local time. 

320 

321 Usage:: 

322 

323 >>> import arrow 

324 >>> arrow.now() 

325 <Arrow [2013-05-07T22:19:11.363410-07:00]> 

326 

327 >>> arrow.now('US/Pacific') 

328 <Arrow [2013-05-07T22:19:15.251821-07:00]> 

329 

330 >>> arrow.now('+02:00') 

331 <Arrow [2013-05-08T07:19:25.618646+02:00]> 

332 

333 >>> arrow.now('local') 

334 <Arrow [2013-05-07T22:19:39.130059-07:00]> 

335 """ 

336 

337 if tz is None: 

338 tz = datetime.now().astimezone().tzinfo 

339 elif not isinstance(tz, dt_tzinfo): 

340 tz = parser.TzinfoParser.parse(tz) 

341 

342 return self.type.now(tz)