Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from __future__ import absolute_import 

2 

3import datetime as _datetime 

4 

5from typing import Optional 

6from typing import Union 

7 

8from .__version__ import __version__ 

9from .constants import DAYS_PER_WEEK 

10from .constants import FRIDAY 

11from .constants import HOURS_PER_DAY 

12from .constants import MINUTES_PER_HOUR 

13from .constants import MONDAY 

14from .constants import MONTHS_PER_YEAR 

15from .constants import SATURDAY 

16from .constants import SECONDS_PER_DAY 

17from .constants import SECONDS_PER_HOUR 

18from .constants import SECONDS_PER_MINUTE 

19from .constants import SUNDAY 

20from .constants import THURSDAY 

21from .constants import TUESDAY 

22from .constants import WEDNESDAY 

23from .constants import WEEKS_PER_YEAR 

24from .constants import YEARS_PER_CENTURY 

25from .constants import YEARS_PER_DECADE 

26from .date import Date 

27from .datetime import DateTime 

28from .duration import Duration 

29from .formatting import Formatter 

30from .helpers import format_diff 

31from .helpers import get_locale 

32from .helpers import get_test_now 

33from .helpers import has_test_now 

34from .helpers import locale 

35from .helpers import set_locale 

36from .helpers import set_test_now 

37from .helpers import test 

38from .helpers import week_ends_at 

39from .helpers import week_starts_at 

40from .parser import parse 

41from .period import Period 

42from .time import Time 

43from .tz import POST_TRANSITION 

44from .tz import PRE_TRANSITION 

45from .tz import TRANSITION_ERROR 

46from .tz import UTC 

47from .tz import local_timezone 

48from .tz import set_local_timezone 

49from .tz import test_local_timezone 

50from .tz import timezone 

51from .tz import timezones 

52from .tz.timezone import Timezone as _Timezone 

53from .utils._compat import _HAS_FOLD 

54 

55 

56_TEST_NOW = None # type: Optional[DateTime] 

57_LOCALE = "en" 

58_WEEK_STARTS_AT = MONDAY 

59_WEEK_ENDS_AT = SUNDAY 

60 

61_formatter = Formatter() 

62 

63 

64def _safe_timezone(obj): 

65 # type: (Optional[Union[str, float, _datetime.tzinfo, _Timezone]]) -> _Timezone 

66 """ 

67 Creates a timezone instance 

68 from a string, Timezone, TimezoneInfo or integer offset. 

69 """ 

70 if isinstance(obj, _Timezone): 

71 return obj 

72 

73 if obj is None or obj == "local": 

74 return local_timezone() 

75 

76 if isinstance(obj, (int, float)): 

77 obj = int(obj * 60 * 60) 

78 elif isinstance(obj, _datetime.tzinfo): 

79 # pytz 

80 if hasattr(obj, "localize"): 

81 obj = obj.zone 

82 elif obj.tzname(None) == "UTC": 

83 return UTC 

84 else: 

85 offset = obj.utcoffset(None) 

86 

87 if offset is None: 

88 offset = _datetime.timedelta(0) 

89 

90 obj = int(offset.total_seconds()) 

91 

92 return timezone(obj) 

93 

94 

95# Public API 

96def datetime( 

97 year, # type: int 

98 month, # type: int 

99 day, # type: int 

100 hour=0, # type: int 

101 minute=0, # type: int 

102 second=0, # type: int 

103 microsecond=0, # type: int 

104 tz=UTC, # type: Optional[Union[str, float, _Timezone]] 

105 dst_rule=POST_TRANSITION, # type: str 

106): # type: (...) -> DateTime 

107 """ 

108 Creates a new DateTime instance from a specific date and time. 

109 """ 

110 if tz is not None: 

111 tz = _safe_timezone(tz) 

112 

113 if not _HAS_FOLD: 

114 dt = naive(year, month, day, hour, minute, second, microsecond) 

115 else: 

116 dt = _datetime.datetime(year, month, day, hour, minute, second, microsecond) 

117 if tz is not None: 

118 dt = tz.convert(dt, dst_rule=dst_rule) 

119 

120 return DateTime( 

121 dt.year, 

122 dt.month, 

123 dt.day, 

124 dt.hour, 

125 dt.minute, 

126 dt.second, 

127 dt.microsecond, 

128 tzinfo=dt.tzinfo, 

129 fold=dt.fold, 

130 ) 

131 

132 

133def local( 

134 year, month, day, hour=0, minute=0, second=0, microsecond=0 

135): # type: (int, int, int, int, int, int, int) -> DateTime 

136 """ 

137 Return a DateTime in the local timezone. 

138 """ 

139 return datetime( 

140 year, month, day, hour, minute, second, microsecond, tz=local_timezone() 

141 ) 

142 

143 

144def naive( 

145 year, month, day, hour=0, minute=0, second=0, microsecond=0 

146): # type: (int, int, int, int, int, int, int) -> DateTime 

147 """ 

148 Return a naive DateTime. 

149 """ 

150 return DateTime(year, month, day, hour, minute, second, microsecond) 

151 

152 

153def date(year, month, day): # type: (int, int, int) -> Date 

154 """ 

155 Create a new Date instance. 

156 """ 

157 return Date(year, month, day) 

158 

159 

160def time(hour, minute=0, second=0, microsecond=0): # type: (int, int, int, int) -> Time 

161 """ 

162 Create a new Time instance. 

163 """ 

164 return Time(hour, minute, second, microsecond) 

165 

166 

167def instance( 

168 dt, tz=UTC 

169): # type: (_datetime.datetime, Optional[Union[str, _Timezone]]) -> DateTime 

170 """ 

171 Create a DateTime instance from a datetime one. 

172 """ 

173 if not isinstance(dt, _datetime.datetime): 

174 raise ValueError("instance() only accepts datetime objects.") 

175 

176 if isinstance(dt, DateTime): 

177 return dt 

178 

179 tz = dt.tzinfo or tz 

180 

181 # Checking for pytz/tzinfo 

182 if isinstance(tz, _datetime.tzinfo) and not isinstance(tz, _Timezone): 

183 # pytz 

184 if hasattr(tz, "localize") and tz.zone: 

185 tz = tz.zone 

186 else: 

187 # We have no sure way to figure out 

188 # the timezone name, we fallback 

189 # on a fixed offset 

190 tz = tz.utcoffset(dt).total_seconds() / 3600 

191 

192 return datetime( 

193 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, tz=tz 

194 ) 

195 

196 

197def now(tz=None): # type: (Optional[Union[str, _Timezone]]) -> DateTime 

198 """ 

199 Get a DateTime instance for the current date and time. 

200 """ 

201 if has_test_now(): 

202 test_instance = get_test_now() 

203 _tz = _safe_timezone(tz) 

204 

205 if tz is not None and _tz != test_instance.timezone: 

206 test_instance = test_instance.in_tz(_tz) 

207 

208 return test_instance 

209 

210 if tz is None or tz == "local": 

211 dt = _datetime.datetime.now(local_timezone()) 

212 elif tz is UTC or tz == "UTC": 

213 dt = _datetime.datetime.now(UTC) 

214 else: 

215 dt = _datetime.datetime.now(UTC) 

216 tz = _safe_timezone(tz) 

217 dt = tz.convert(dt) 

218 

219 return instance(dt, tz) 

220 

221 

222def today(tz="local"): # type: (Union[str, _Timezone]) -> DateTime 

223 """ 

224 Create a DateTime instance for today. 

225 """ 

226 return now(tz).start_of("day") 

227 

228 

229def tomorrow(tz="local"): # type: (Union[str, _Timezone]) -> DateTime 

230 """ 

231 Create a DateTime instance for today. 

232 """ 

233 return today(tz).add(days=1) 

234 

235 

236def yesterday(tz="local"): # type: (Union[str, _Timezone]) -> DateTime 

237 """ 

238 Create a DateTime instance for today. 

239 """ 

240 return today(tz).subtract(days=1) 

241 

242 

243def from_format( 

244 string, fmt, tz=UTC, locale=None, # noqa 

245): # type: (str, str, Union[str, _Timezone], Optional[str]) -> DateTime 

246 """ 

247 Creates a DateTime instance from a specific format. 

248 """ 

249 parts = _formatter.parse(string, fmt, now(), locale=locale) 

250 if parts["tz"] is None: 

251 parts["tz"] = tz 

252 

253 return datetime(**parts) 

254 

255 

256def from_timestamp( 

257 timestamp, tz=UTC 

258): # type: (Union[int, float], Union[str, _Timezone]) -> DateTime 

259 """ 

260 Create a DateTime instance from a timestamp. 

261 """ 

262 dt = _datetime.datetime.utcfromtimestamp(timestamp) 

263 

264 dt = datetime( 

265 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond 

266 ) 

267 

268 if tz is not UTC or tz != "UTC": 

269 dt = dt.in_timezone(tz) 

270 

271 return dt 

272 

273 

274def duration( 

275 days=0, # type: float 

276 seconds=0, # type: float 

277 microseconds=0, # type: float 

278 milliseconds=0, # type: float 

279 minutes=0, # type: float 

280 hours=0, # type: float 

281 weeks=0, # type: float 

282 years=0, # type: float 

283 months=0, # type: float 

284): # type: (...) -> Duration 

285 """ 

286 Create a Duration instance. 

287 """ 

288 return Duration( 

289 days=days, 

290 seconds=seconds, 

291 microseconds=microseconds, 

292 milliseconds=milliseconds, 

293 minutes=minutes, 

294 hours=hours, 

295 weeks=weeks, 

296 years=years, 

297 months=months, 

298 ) 

299 

300 

301def period(start, end, absolute=False): # type: (DateTime, DateTime, bool) -> Period 

302 """ 

303 Create a Period instance. 

304 """ 

305 return Period(start, end, absolute=absolute)