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

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

90 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 

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 dateutil import tz as dateutil_tz 

16 

17from arrow import parser 

18from arrow.arrow import TZ_EXPR, Arrow 

19from arrow.constants import DEFAULT_LOCALE 

20from arrow.util import is_timestamp, iso_to_gregorian 

21 

22 

23class ArrowFactory: 

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

25 

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

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

28 

29 """ 

30 

31 type: Type[Arrow] 

32 

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

34 self.type = type 

35 

36 @overload 

37 def get( 

38 self, 

39 *, 

40 locale: str = DEFAULT_LOCALE, 

41 tzinfo: Optional[TZ_EXPR] = None, 

42 normalize_whitespace: bool = False, 

43 ) -> Arrow: 

44 ... # pragma: no cover 

45 

46 @overload 

47 def get( 

48 self, 

49 __obj: Union[ 

50 Arrow, 

51 datetime, 

52 date, 

53 struct_time, 

54 dt_tzinfo, 

55 int, 

56 float, 

57 str, 

58 Tuple[int, int, int], 

59 ], 

60 *, 

61 locale: str = DEFAULT_LOCALE, 

62 tzinfo: Optional[TZ_EXPR] = None, 

63 normalize_whitespace: bool = False, 

64 ) -> Arrow: 

65 ... # pragma: no cover 

66 

67 @overload 

68 def get( 

69 self, 

70 __arg1: Union[datetime, date], 

71 __arg2: TZ_EXPR, 

72 *, 

73 locale: str = DEFAULT_LOCALE, 

74 tzinfo: Optional[TZ_EXPR] = None, 

75 normalize_whitespace: bool = False, 

76 ) -> Arrow: 

77 ... # pragma: no cover 

78 

79 @overload 

80 def get( 

81 self, 

82 __arg1: str, 

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

84 *, 

85 locale: str = DEFAULT_LOCALE, 

86 tzinfo: Optional[TZ_EXPR] = None, 

87 normalize_whitespace: bool = False, 

88 ) -> Arrow: 

89 ... # pragma: no cover 

90 

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

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

93 

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

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

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

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

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

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

100 Defaults to false. 

101 

102 Usage:: 

103 

104 >>> import arrow 

105 

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

107 

108 >>> arrow.get() 

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

110 

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

112 

113 >>> arw = arrow.utcnow() 

114 >>> arrow.get(arw) 

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

116 

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

118 that timestamp in UTC:: 

119 

120 >>> arrow.get(1367992474.293378) 

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

122 

123 >>> arrow.get(1367992474) 

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

125 

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

127 

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

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

130 

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

132 

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

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

135 

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

137 

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

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

140 

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

142 

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

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

145 

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

147 

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

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

150 

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

152 

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

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

155 

156 **One** time.struct time:: 

157 

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

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

160 

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

162 

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

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

165 

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

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

168 

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

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

171 

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

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

174 

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

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

177 

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

179 

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

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

182 

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

184 

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

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

187 

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

189 

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

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

192 

193 """ 

194 

195 arg_count = len(args) 

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

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

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

199 

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

201 if len(kwargs) > 1: 

202 arg_count = 3 

203 

204 # tzinfo kwarg is not provided 

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

206 arg_count = 3 

207 

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

209 if arg_count == 0: 

210 if isinstance(tz, str): 

211 tz = parser.TzinfoParser.parse(tz) 

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

213 

214 if isinstance(tz, dt_tzinfo): 

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

216 

217 return self.type.utcnow() 

218 

219 if arg_count == 1: 

220 arg = args[0] 

221 if isinstance(arg, Decimal): 

222 arg = float(arg) 

223 

224 # (None) -> raises an exception 

225 if arg is None: 

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

227 

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

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

230 if tz is None: 

231 # set to UTC by default 

232 tz = dateutil_tz.tzutc() 

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

234 

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

236 elif isinstance(arg, Arrow): 

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

238 

239 # (datetime) -> from datetime @ tzinfo 

240 elif isinstance(arg, datetime): 

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

242 

243 # (date) -> from date @ tzinfo 

244 elif isinstance(arg, date): 

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

246 

247 # (tzinfo) -> now @ tzinfo 

248 elif isinstance(arg, dt_tzinfo): 

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

250 

251 # (str) -> parse @ tzinfo 

252 elif isinstance(arg, str): 

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

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

255 

256 # (struct_time) -> from struct_time 

257 elif isinstance(arg, struct_time): 

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

259 

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

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

262 d = iso_to_gregorian(*arg) 

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

264 

265 else: 

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

267 

268 elif arg_count == 2: 

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

270 

271 if isinstance(arg_1, datetime): 

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

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

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

275 else: 

276 raise TypeError( 

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

278 ) 

279 

280 elif isinstance(arg_1, date): 

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

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

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

284 else: 

285 raise TypeError( 

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

287 ) 

288 

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

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

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

292 args[0], args[1], normalize_whitespace 

293 ) 

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

295 

296 else: 

297 raise TypeError( 

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

299 ) 

300 

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

302 else: 

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

304 

305 def utcnow(self) -> Arrow: 

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

307 

308 Usage:: 

309 

310 >>> import arrow 

311 >>> arrow.utcnow() 

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

313 """ 

314 

315 return self.type.utcnow() 

316 

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

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

319 timezone. 

320 

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

322 

323 Usage:: 

324 

325 >>> import arrow 

326 >>> arrow.now() 

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

328 

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

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

331 

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

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

334 

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

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

337 """ 

338 

339 if tz is None: 

340 tz = dateutil_tz.tzlocal() 

341 elif not isinstance(tz, dt_tzinfo): 

342 tz = parser.TzinfoParser.parse(tz) 

343 

344 return self.type.now(tz)