Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pendulum/date.py: 36%

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

280 statements  

1# The following is only needed because of Python 3.7 

2# mypy: no-warn-unused-ignores 

3from __future__ import annotations 

4 

5import calendar 

6import math 

7 

8from datetime import date 

9from datetime import datetime 

10from datetime import timedelta 

11from typing import TYPE_CHECKING 

12from typing import ClassVar 

13from typing import NoReturn 

14from typing import cast 

15from typing import overload 

16 

17import pendulum 

18 

19from pendulum.constants import MONTHS_PER_YEAR 

20from pendulum.constants import YEARS_PER_CENTURY 

21from pendulum.constants import YEARS_PER_DECADE 

22from pendulum.day import WeekDay 

23from pendulum.exceptions import PendulumException 

24from pendulum.helpers import add_duration 

25from pendulum.interval import Interval 

26from pendulum.mixins.default import FormattableMixin 

27 

28 

29if TYPE_CHECKING: 

30 from typing_extensions import Self 

31 from typing_extensions import SupportsIndex 

32 

33 

34class Date(FormattableMixin, date): 

35 _MODIFIERS_VALID_UNITS: ClassVar[list[str]] = [ 

36 "day", 

37 "week", 

38 "month", 

39 "year", 

40 "decade", 

41 "century", 

42 ] 

43 

44 # Getters/Setters 

45 

46 def set( 

47 self, year: int | None = None, month: int | None = None, day: int | None = None 

48 ) -> Self: 

49 return self.replace(year=year, month=month, day=day) 

50 

51 @property 

52 def day_of_week(self) -> WeekDay: 

53 """ 

54 Returns the day of the week (0-6). 

55 """ 

56 return WeekDay(self.weekday()) 

57 

58 @property 

59 def day_of_year(self) -> int: 

60 """ 

61 Returns the day of the year (1-366). 

62 """ 

63 k = 1 if self.is_leap_year() else 2 

64 

65 return (275 * self.month) // 9 - k * ((self.month + 9) // 12) + self.day - 30 

66 

67 @property 

68 def week_of_year(self) -> int: 

69 return self.isocalendar()[1] 

70 

71 @property 

72 def days_in_month(self) -> int: 

73 return calendar.monthrange(self.year, self.month)[1] 

74 

75 @property 

76 def week_of_month(self) -> int: 

77 return math.ceil((self.day + self.first_of("month").isoweekday() - 1) / 7) 

78 

79 @property 

80 def age(self) -> int: 

81 return self.diff(abs=False).in_years() 

82 

83 @property 

84 def quarter(self) -> int: 

85 return math.ceil(self.month / 3) 

86 

87 # String Formatting 

88 

89 def to_date_string(self) -> str: 

90 """ 

91 Format the instance as date. 

92 

93 :rtype: str 

94 """ 

95 return self.strftime("%Y-%m-%d") 

96 

97 def to_formatted_date_string(self) -> str: 

98 """ 

99 Format the instance as a readable date. 

100 

101 :rtype: str 

102 """ 

103 return self.strftime("%b %d, %Y") 

104 

105 def __repr__(self) -> str: 

106 return f"{self.__class__.__name__}({self.year}, {self.month}, {self.day})" 

107 

108 # COMPARISONS 

109 

110 def closest(self, dt1: date, dt2: date) -> Self: 

111 """ 

112 Get the closest date from the instance. 

113 """ 

114 dt1 = self.__class__(dt1.year, dt1.month, dt1.day) 

115 dt2 = self.__class__(dt2.year, dt2.month, dt2.day) 

116 

117 if self.diff(dt1).in_seconds() < self.diff(dt2).in_seconds(): 

118 return dt1 

119 

120 return dt2 

121 

122 def farthest(self, dt1: date, dt2: date) -> Self: 

123 """ 

124 Get the farthest date from the instance. 

125 """ 

126 dt1 = self.__class__(dt1.year, dt1.month, dt1.day) 

127 dt2 = self.__class__(dt2.year, dt2.month, dt2.day) 

128 

129 if self.diff(dt1).in_seconds() > self.diff(dt2).in_seconds(): 

130 return dt1 

131 

132 return dt2 

133 

134 def is_future(self) -> bool: 

135 """ 

136 Determines if the instance is in the future, ie. greater than now. 

137 """ 

138 return self > self.today() 

139 

140 def is_past(self) -> bool: 

141 """ 

142 Determines if the instance is in the past, ie. less than now. 

143 """ 

144 return self < self.today() 

145 

146 def is_leap_year(self) -> bool: 

147 """ 

148 Determines if the instance is a leap year. 

149 """ 

150 return calendar.isleap(self.year) 

151 

152 def is_long_year(self) -> bool: 

153 """ 

154 Determines if the instance is a long year 

155 

156 See link `<https://en.wikipedia.org/wiki/ISO_8601#Week_dates>`_ 

157 """ 

158 return Date(self.year, 12, 28).isocalendar()[1] == 53 

159 

160 def is_same_day(self, dt: date) -> bool: 

161 """ 

162 Checks if the passed in date is the same day as the instance current day. 

163 """ 

164 return self == dt 

165 

166 def is_anniversary(self, dt: date | None = None) -> bool: 

167 """ 

168 Check if it's the anniversary. 

169 

170 Compares the date/month values of the two dates. 

171 """ 

172 if dt is None: 

173 dt = self.__class__.today() 

174 

175 instance = self.__class__(dt.year, dt.month, dt.day) 

176 

177 return (self.month, self.day) == (instance.month, instance.day) 

178 

179 # the additional method for checking if today is the anniversary day 

180 # the alias is provided to start using a new name and keep the backward 

181 # compatibility the old name can be completely replaced with the new in 

182 # one of the future versions 

183 is_birthday = is_anniversary 

184 

185 # ADDITIONS AND SUBTRACTIONS 

186 

187 def add( 

188 self, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0 

189 ) -> Self: 

190 """ 

191 Add duration to the instance. 

192 

193 :param years: The number of years 

194 :param months: The number of months 

195 :param weeks: The number of weeks 

196 :param days: The number of days 

197 """ 

198 dt = add_duration( 

199 date(self.year, self.month, self.day), 

200 years=years, 

201 months=months, 

202 weeks=weeks, 

203 days=days, 

204 ) 

205 

206 return self.__class__(dt.year, dt.month, dt.day) 

207 

208 def subtract( 

209 self, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0 

210 ) -> Self: 

211 """ 

212 Remove duration from the instance. 

213 

214 :param years: The number of years 

215 :param months: The number of months 

216 :param weeks: The number of weeks 

217 :param days: The number of days 

218 """ 

219 return self.add(years=-years, months=-months, weeks=-weeks, days=-days) 

220 

221 def _add_timedelta(self, delta: timedelta) -> Self: 

222 """ 

223 Add timedelta duration to the instance. 

224 

225 :param delta: The timedelta instance 

226 """ 

227 if isinstance(delta, pendulum.Duration): 

228 return self.add( 

229 years=delta.years, 

230 months=delta.months, 

231 weeks=delta.weeks, 

232 days=delta.remaining_days, 

233 ) 

234 

235 return self.add(days=delta.days) 

236 

237 def _subtract_timedelta(self, delta: timedelta) -> Self: 

238 """ 

239 Remove timedelta duration from the instance. 

240 

241 :param delta: The timedelta instance 

242 """ 

243 if isinstance(delta, pendulum.Duration): 

244 return self.subtract( 

245 years=delta.years, 

246 months=delta.months, 

247 weeks=delta.weeks, 

248 days=delta.remaining_days, 

249 ) 

250 

251 return self.subtract(days=delta.days) 

252 

253 def __add__(self, other: timedelta) -> Self: 

254 if not isinstance(other, timedelta): 

255 return NotImplemented 

256 

257 return self._add_timedelta(other) 

258 

259 @overload # type: ignore[override] # this is only needed because of Python 3.7 

260 def __sub__(self, __delta: timedelta) -> Self: ... 

261 

262 @overload 

263 def __sub__(self, __dt: datetime) -> NoReturn: ... 

264 

265 @overload 

266 def __sub__(self, __dt: Self) -> Interval[Date]: ... 

267 

268 def __sub__(self, other: timedelta | date) -> Self | Interval[Date]: 

269 if isinstance(other, timedelta): 

270 return self._subtract_timedelta(other) 

271 

272 if not isinstance(other, date): 

273 return NotImplemented 

274 

275 dt = self.__class__(other.year, other.month, other.day) 

276 

277 return dt.diff(self, False) 

278 

279 # DIFFERENCES 

280 

281 def diff(self, dt: date | None = None, abs: bool = True) -> Interval[Date]: 

282 """ 

283 Returns the difference between two Date objects as an Interval. 

284 

285 :param dt: The date to compare to (defaults to today) 

286 :param abs: Whether to return an absolute interval or not 

287 """ 

288 if dt is None: 

289 dt = self.today() 

290 

291 return Interval(self, Date(dt.year, dt.month, dt.day), absolute=abs) 

292 

293 def diff_for_humans( 

294 self, 

295 other: date | None = None, 

296 absolute: bool = False, 

297 locale: str | None = None, 

298 ) -> str: 

299 """ 

300 Get the difference in a human readable format in the current locale. 

301 

302 When comparing a value in the past to default now: 

303 1 day ago 

304 5 months ago 

305 

306 When comparing a value in the future to default now: 

307 1 day from now 

308 5 months from now 

309 

310 When comparing a value in the past to another value: 

311 1 day before 

312 5 months before 

313 

314 When comparing a value in the future to another value: 

315 1 day after 

316 5 months after 

317 

318 :param other: The date to compare to (defaults to today) 

319 :param absolute: removes time difference modifiers ago, after, etc 

320 :param locale: The locale to use for localization 

321 """ 

322 is_now = other is None 

323 

324 if is_now: 

325 other = self.today() 

326 

327 diff = self.diff(other) 

328 

329 return pendulum.format_diff(diff, is_now, absolute, locale) 

330 

331 # MODIFIERS 

332 

333 def start_of(self, unit: str) -> Self: 

334 """ 

335 Returns a copy of the instance with the time reset 

336 with the following rules: 

337 

338 * day: time to 00:00:00 

339 * week: date to first day of the week and time to 00:00:00 

340 * month: date to first day of the month and time to 00:00:00 

341 * year: date to first day of the year and time to 00:00:00 

342 * decade: date to first day of the decade and time to 00:00:00 

343 * century: date to first day of century and time to 00:00:00 

344 

345 :param unit: The unit to reset to 

346 """ 

347 if unit not in self._MODIFIERS_VALID_UNITS: 

348 raise ValueError(f'Invalid unit "{unit}" for start_of()') 

349 

350 return cast("Self", getattr(self, f"_start_of_{unit}")()) 

351 

352 def end_of(self, unit: str) -> Self: 

353 """ 

354 Returns a copy of the instance with the time reset 

355 with the following rules: 

356 

357 * week: date to last day of the week 

358 * month: date to last day of the month 

359 * year: date to last day of the year 

360 * decade: date to last day of the decade 

361 * century: date to last day of century 

362 

363 :param unit: The unit to reset to 

364 """ 

365 if unit not in self._MODIFIERS_VALID_UNITS: 

366 raise ValueError(f'Invalid unit "{unit}" for end_of()') 

367 

368 return cast("Self", getattr(self, f"_end_of_{unit}")()) 

369 

370 def _start_of_day(self) -> Self: 

371 """ 

372 Compatibility method. 

373 """ 

374 return self 

375 

376 def _end_of_day(self) -> Self: 

377 """ 

378 Compatibility method 

379 """ 

380 return self 

381 

382 def _start_of_month(self) -> Self: 

383 """ 

384 Reset the date to the first day of the month. 

385 """ 

386 return self.set(self.year, self.month, 1) 

387 

388 def _end_of_month(self) -> Self: 

389 """ 

390 Reset the date to the last day of the month. 

391 """ 

392 return self.set(self.year, self.month, self.days_in_month) 

393 

394 def _start_of_year(self) -> Self: 

395 """ 

396 Reset the date to the first day of the year. 

397 """ 

398 return self.set(self.year, 1, 1) 

399 

400 def _end_of_year(self) -> Self: 

401 """ 

402 Reset the date to the last day of the year. 

403 """ 

404 return self.set(self.year, 12, 31) 

405 

406 def _start_of_decade(self) -> Self: 

407 """ 

408 Reset the date to the first day of the decade. 

409 """ 

410 year = self.year - self.year % YEARS_PER_DECADE 

411 

412 return self.set(year, 1, 1) 

413 

414 def _end_of_decade(self) -> Self: 

415 """ 

416 Reset the date to the last day of the decade. 

417 """ 

418 year = self.year - self.year % YEARS_PER_DECADE + YEARS_PER_DECADE - 1 

419 

420 return self.set(year, 12, 31) 

421 

422 def _start_of_century(self) -> Self: 

423 """ 

424 Reset the date to the first day of the century. 

425 """ 

426 year = self.year - 1 - (self.year - 1) % YEARS_PER_CENTURY + 1 

427 

428 return self.set(year, 1, 1) 

429 

430 def _end_of_century(self) -> Self: 

431 """ 

432 Reset the date to the last day of the century. 

433 """ 

434 year = self.year - 1 - (self.year - 1) % YEARS_PER_CENTURY + YEARS_PER_CENTURY 

435 

436 return self.set(year, 12, 31) 

437 

438 def _start_of_week(self) -> Self: 

439 """ 

440 Reset the date to the first day of the week. 

441 """ 

442 dt = self 

443 

444 if self.day_of_week != pendulum._WEEK_STARTS_AT: 

445 dt = self.previous(pendulum._WEEK_STARTS_AT) 

446 

447 return dt.start_of("day") 

448 

449 def _end_of_week(self) -> Self: 

450 """ 

451 Reset the date to the last day of the week. 

452 """ 

453 dt = self 

454 

455 if self.day_of_week != pendulum._WEEK_ENDS_AT: 

456 dt = self.next(pendulum._WEEK_ENDS_AT) 

457 

458 return dt.end_of("day") 

459 

460 def next(self, day_of_week: WeekDay | None = None) -> Self: 

461 """ 

462 Modify to the next occurrence of a given day of the week. 

463 If no day_of_week is provided, modify to the next occurrence 

464 of the current day of the week. Use the supplied consts 

465 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

466 

467 :param day_of_week: The next day of week to reset to. 

468 """ 

469 if day_of_week is None: 

470 day_of_week = self.day_of_week 

471 

472 if day_of_week < WeekDay.MONDAY or day_of_week > WeekDay.SUNDAY: 

473 raise ValueError("Invalid day of week") 

474 

475 dt = self.add(days=1) 

476 while dt.day_of_week != day_of_week: 

477 dt = dt.add(days=1) 

478 

479 return dt 

480 

481 def previous(self, day_of_week: WeekDay | None = None) -> Self: 

482 """ 

483 Modify to the previous occurrence of a given day of the week. 

484 If no day_of_week is provided, modify to the previous occurrence 

485 of the current day of the week. Use the supplied consts 

486 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

487 

488 :param day_of_week: The previous day of week to reset to. 

489 """ 

490 if day_of_week is None: 

491 day_of_week = self.day_of_week 

492 

493 if day_of_week < WeekDay.MONDAY or day_of_week > WeekDay.SUNDAY: 

494 raise ValueError("Invalid day of week") 

495 

496 dt = self.subtract(days=1) 

497 while dt.day_of_week != day_of_week: 

498 dt = dt.subtract(days=1) 

499 

500 return dt 

501 

502 def first_of(self, unit: str, day_of_week: WeekDay | None = None) -> Self: 

503 """ 

504 Returns an instance set to the first occurrence 

505 of a given day of the week in the current unit. 

506 If no day_of_week is provided, modify to the first day of the unit. 

507 Use the supplied consts to indicate the desired day_of_week, 

508 ex. pendulum.MONDAY. 

509 

510 Supported units are month, quarter and year. 

511 

512 :param unit: The unit to use 

513 :param day_of_week: The day of week to reset to. 

514 """ 

515 if unit not in ["month", "quarter", "year"]: 

516 raise ValueError(f'Invalid unit "{unit}" for first_of()') 

517 

518 return cast("Self", getattr(self, f"_first_of_{unit}")(day_of_week)) 

519 

520 def last_of(self, unit: str, day_of_week: WeekDay | None = None) -> Self: 

521 """ 

522 Returns an instance set to the last occurrence 

523 of a given day of the week in the current unit. 

524 If no day_of_week is provided, modify to the last day of the unit. 

525 Use the supplied consts to indicate the desired day_of_week, 

526 ex. pendulum.MONDAY. 

527 

528 Supported units are month, quarter and year. 

529 

530 :param unit: The unit to use 

531 :param day_of_week: The day of week to reset to. 

532 """ 

533 if unit not in ["month", "quarter", "year"]: 

534 raise ValueError(f'Invalid unit "{unit}" for first_of()') 

535 

536 return cast("Self", getattr(self, f"_last_of_{unit}")(day_of_week)) 

537 

538 def nth_of(self, unit: str, nth: int, day_of_week: WeekDay) -> Self: 

539 """ 

540 Returns a new instance set to the given occurrence 

541 of a given day of the week in the current unit. 

542 If the calculated occurrence is outside the scope of the current unit, 

543 then raise an error. Use the supplied consts 

544 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

545 

546 Supported units are month, quarter and year. 

547 

548 :param unit: The unit to use 

549 :param nth: The occurrence to use 

550 :param day_of_week: The day of week to set to. 

551 """ 

552 if unit not in ["month", "quarter", "year"]: 

553 raise ValueError(f'Invalid unit "{unit}" for first_of()') 

554 

555 dt = cast("Self", getattr(self, f"_nth_of_{unit}")(nth, day_of_week)) 

556 if not dt: 

557 raise PendulumException( 

558 f"Unable to find occurrence {nth}" 

559 f" of {WeekDay(day_of_week).name.capitalize()} in {unit}" 

560 ) 

561 

562 return dt 

563 

564 def _first_of_month(self, day_of_week: WeekDay) -> Self: 

565 """ 

566 Modify to the first occurrence of a given day of the week 

567 in the current month. If no day_of_week is provided, 

568 modify to the first day of the month. Use the supplied consts 

569 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

570 

571 :param day_of_week: The day of week to set to. 

572 """ 

573 dt = self 

574 

575 if day_of_week is None: 

576 return dt.set(day=1) 

577 

578 month = calendar.monthcalendar(dt.year, dt.month) 

579 

580 calendar_day = day_of_week 

581 

582 if month[0][calendar_day] > 0: 

583 day_of_month = month[0][calendar_day] 

584 else: 

585 day_of_month = month[1][calendar_day] 

586 

587 return dt.set(day=day_of_month) 

588 

589 def _last_of_month(self, day_of_week: WeekDay | None = None) -> Self: 

590 """ 

591 Modify to the last occurrence of a given day of the week 

592 in the current month. If no day_of_week is provided, 

593 modify to the last day of the month. Use the supplied consts 

594 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

595 

596 :param day_of_week: The day of week to set to. 

597 """ 

598 dt = self 

599 

600 if day_of_week is None: 

601 return dt.set(day=self.days_in_month) 

602 

603 month = calendar.monthcalendar(dt.year, dt.month) 

604 

605 calendar_day = day_of_week 

606 

607 if month[-1][calendar_day] > 0: 

608 day_of_month = month[-1][calendar_day] 

609 else: 

610 day_of_month = month[-2][calendar_day] 

611 

612 return dt.set(day=day_of_month) 

613 

614 def _nth_of_month(self, nth: int, day_of_week: WeekDay) -> Self | None: 

615 """ 

616 Modify to the given occurrence of a given day of the week 

617 in the current month. If the calculated occurrence is outside, 

618 the scope of the current month, then return False and no 

619 modifications are made. Use the supplied consts 

620 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

621 """ 

622 if nth == 1: 

623 return self.first_of("month", day_of_week) 

624 

625 dt = self.first_of("month") 

626 check = dt.format("YYYY-MM") 

627 for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): 

628 dt = dt.next(day_of_week) 

629 

630 if dt.format("YYYY-MM") == check: 

631 return self.set(day=dt.day) 

632 

633 return None 

634 

635 def _first_of_quarter(self, day_of_week: WeekDay | None = None) -> Self: 

636 """ 

637 Modify to the first occurrence of a given day of the week 

638 in the current quarter. If no day_of_week is provided, 

639 modify to the first day of the quarter. Use the supplied consts 

640 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

641 """ 

642 return self.set(self.year, self.quarter * 3 - 2, 1).first_of( 

643 "month", day_of_week 

644 ) 

645 

646 def _last_of_quarter(self, day_of_week: WeekDay | None = None) -> Self: 

647 """ 

648 Modify to the last occurrence of a given day of the week 

649 in the current quarter. If no day_of_week is provided, 

650 modify to the last day of the quarter. Use the supplied consts 

651 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

652 """ 

653 return self.set(self.year, self.quarter * 3, 1).last_of("month", day_of_week) 

654 

655 def _nth_of_quarter(self, nth: int, day_of_week: WeekDay) -> Self | None: 

656 """ 

657 Modify to the given occurrence of a given day of the week 

658 in the current quarter. If the calculated occurrence is outside, 

659 the scope of the current quarter, then return False and no 

660 modifications are made. Use the supplied consts 

661 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

662 """ 

663 if nth == 1: 

664 return self.first_of("quarter", day_of_week) 

665 

666 dt = self.replace(self.year, self.quarter * 3, 1) 

667 last_month = dt.month 

668 year = dt.year 

669 dt = dt.first_of("quarter") 

670 for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): 

671 dt = dt.next(day_of_week) 

672 

673 if last_month < dt.month or year != dt.year: 

674 return None 

675 

676 return self.set(self.year, dt.month, dt.day) 

677 

678 def _first_of_year(self, day_of_week: WeekDay | None = None) -> Self: 

679 """ 

680 Modify to the first occurrence of a given day of the week 

681 in the current year. If no day_of_week is provided, 

682 modify to the first day of the year. Use the supplied consts 

683 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

684 """ 

685 return self.set(month=1).first_of("month", day_of_week) 

686 

687 def _last_of_year(self, day_of_week: WeekDay | None = None) -> Self: 

688 """ 

689 Modify to the last occurrence of a given day of the week 

690 in the current year. If no day_of_week is provided, 

691 modify to the last day of the year. Use the supplied consts 

692 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

693 """ 

694 return self.set(month=MONTHS_PER_YEAR).last_of("month", day_of_week) 

695 

696 def _nth_of_year(self, nth: int, day_of_week: WeekDay) -> Self | None: 

697 """ 

698 Modify to the given occurrence of a given day of the week 

699 in the current year. If the calculated occurrence is outside, 

700 the scope of the current year, then return False and no 

701 modifications are made. Use the supplied consts 

702 to indicate the desired day_of_week, ex. pendulum.MONDAY. 

703 """ 

704 if nth == 1: 

705 return self.first_of("year", day_of_week) 

706 

707 dt = self.first_of("year") 

708 year = dt.year 

709 for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): 

710 dt = dt.next(day_of_week) 

711 

712 if year != dt.year: 

713 return None 

714 

715 return self.set(self.year, dt.month, dt.day) 

716 

717 def average(self, dt: date | None = None) -> Self: 

718 """ 

719 Modify the current instance to the average 

720 of a given instance (default now) and the current instance. 

721 """ 

722 if dt is None: 

723 dt = Date.today() 

724 

725 return self.add(days=int(self.diff(dt, False).in_days() / 2)) 

726 

727 # Native methods override 

728 

729 @classmethod 

730 def today(cls) -> Self: 

731 dt = date.today() 

732 

733 return cls(dt.year, dt.month, dt.day) 

734 

735 @classmethod 

736 def fromtimestamp(cls, t: float) -> Self: 

737 dt = super().fromtimestamp(t) 

738 

739 return cls(dt.year, dt.month, dt.day) 

740 

741 @classmethod 

742 def fromordinal(cls, n: int) -> Self: 

743 dt = super().fromordinal(n) 

744 

745 return cls(dt.year, dt.month, dt.day) 

746 

747 def replace( 

748 self, 

749 year: SupportsIndex | None = None, 

750 month: SupportsIndex | None = None, 

751 day: SupportsIndex | None = None, 

752 ) -> Self: 

753 year = year if year is not None else self.year 

754 month = month if month is not None else self.month 

755 day = day if day is not None else self.day 

756 

757 return self.__class__(year, month, day)