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

283 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-30 06:11 +0000

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 first_day_of_month = self.replace(day=1) 

78 

79 return self.week_of_year - first_day_of_month.week_of_year + 1 

80 

81 @property 

82 def age(self) -> int: 

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

84 

85 @property 

86 def quarter(self) -> int: 

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

88 

89 # String Formatting 

90 

91 def to_date_string(self) -> str: 

92 """ 

93 Format the instance as date. 

94 

95 :rtype: str 

96 """ 

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

98 

99 def to_formatted_date_string(self) -> str: 

100 """ 

101 Format the instance as a readable date. 

102 

103 :rtype: str 

104 """ 

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

106 

107 def __repr__(self) -> str: 

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

109 

110 # COMPARISONS 

111 

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

113 """ 

114 Get the closest date from the instance. 

115 """ 

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

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

118 

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

120 return dt1 

121 

122 return dt2 

123 

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

125 """ 

126 Get the farthest date from the instance. 

127 """ 

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

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

130 

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

132 return dt1 

133 

134 return dt2 

135 

136 def is_future(self) -> bool: 

137 """ 

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

139 """ 

140 return self > self.today() 

141 

142 def is_past(self) -> bool: 

143 """ 

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

145 """ 

146 return self < self.today() 

147 

148 def is_leap_year(self) -> bool: 

149 """ 

150 Determines if the instance is a leap year. 

151 """ 

152 return calendar.isleap(self.year) 

153 

154 def is_long_year(self) -> bool: 

155 """ 

156 Determines if the instance is a long year 

157 

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

159 """ 

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

161 

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

163 """ 

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

165 """ 

166 return self == dt 

167 

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

169 """ 

170 Check if it's the anniversary. 

171 

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

173 """ 

174 if dt is None: 

175 dt = self.__class__.today() 

176 

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

178 

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

180 

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

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

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

184 # one of the future versions 

185 is_birthday = is_anniversary 

186 

187 # ADDITIONS AND SUBTRACTIONS 

188 

189 def add( 

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

191 ) -> Self: 

192 """ 

193 Add duration to the instance. 

194 

195 :param years: The number of years 

196 :param months: The number of months 

197 :param weeks: The number of weeks 

198 :param days: The number of days 

199 """ 

200 dt = add_duration( 

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

202 years=years, 

203 months=months, 

204 weeks=weeks, 

205 days=days, 

206 ) 

207 

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

209 

210 def subtract( 

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

212 ) -> Self: 

213 """ 

214 Remove duration from the instance. 

215 

216 :param years: The number of years 

217 :param months: The number of months 

218 :param weeks: The number of weeks 

219 :param days: The number of days 

220 """ 

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

222 

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

224 """ 

225 Add timedelta duration to the instance. 

226 

227 :param delta: The timedelta instance 

228 """ 

229 if isinstance(delta, pendulum.Duration): 

230 return self.add( 

231 years=delta.years, 

232 months=delta.months, 

233 weeks=delta.weeks, 

234 days=delta.remaining_days, 

235 ) 

236 

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

238 

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

240 """ 

241 Remove timedelta duration from the instance. 

242 

243 :param delta: The timedelta instance 

244 """ 

245 if isinstance(delta, pendulum.Duration): 

246 return self.subtract( 

247 years=delta.years, 

248 months=delta.months, 

249 weeks=delta.weeks, 

250 days=delta.remaining_days, 

251 ) 

252 

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

254 

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

256 if not isinstance(other, timedelta): 

257 return NotImplemented 

258 

259 return self._add_timedelta(other) 

260 

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

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

263 ... 

264 

265 @overload 

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

267 ... 

268 

269 @overload 

270 def __sub__(self, __dt: Self) -> Interval: 

271 ... 

272 

273 def __sub__(self, other: timedelta | date) -> Self | Interval: 

274 if isinstance(other, timedelta): 

275 return self._subtract_timedelta(other) 

276 

277 if not isinstance(other, date): 

278 return NotImplemented 

279 

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

281 

282 return dt.diff(self, False) 

283 

284 # DIFFERENCES 

285 

286 def diff(self, dt: date | None = None, abs: bool = True) -> Interval: 

287 """ 

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

289 

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

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

292 """ 

293 if dt is None: 

294 dt = self.today() 

295 

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

297 

298 def diff_for_humans( 

299 self, 

300 other: date | None = None, 

301 absolute: bool = False, 

302 locale: str | None = None, 

303 ) -> str: 

304 """ 

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

306 

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

308 1 day ago 

309 5 months ago 

310 

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

312 1 day from now 

313 5 months from now 

314 

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

316 1 day before 

317 5 months before 

318 

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

320 1 day after 

321 5 months after 

322 

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

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

325 :param locale: The locale to use for localization 

326 """ 

327 is_now = other is None 

328 

329 if is_now: 

330 other = self.today() 

331 

332 diff = self.diff(other) 

333 

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

335 

336 # MODIFIERS 

337 

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

339 """ 

340 Returns a copy of the instance with the time reset 

341 with the following rules: 

342 

343 * day: time to 00:00:00 

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

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

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

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

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

349 

350 :param unit: The unit to reset to 

351 """ 

352 if unit not in self._MODIFIERS_VALID_UNITS: 

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

354 

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

356 

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

358 """ 

359 Returns a copy of the instance with the time reset 

360 with the following rules: 

361 

362 * week: date to last day of the week 

363 * month: date to last day of the month 

364 * year: date to last day of the year 

365 * decade: date to last day of the decade 

366 * century: date to last day of century 

367 

368 :param unit: The unit to reset to 

369 """ 

370 if unit not in self._MODIFIERS_VALID_UNITS: 

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

372 

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

374 

375 def _start_of_day(self) -> Self: 

376 """ 

377 Compatibility method. 

378 """ 

379 return self 

380 

381 def _end_of_day(self) -> Self: 

382 """ 

383 Compatibility method 

384 """ 

385 return self 

386 

387 def _start_of_month(self) -> Self: 

388 """ 

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

390 """ 

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

392 

393 def _end_of_month(self) -> Self: 

394 """ 

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

396 """ 

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

398 

399 def _start_of_year(self) -> Self: 

400 """ 

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

402 """ 

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

404 

405 def _end_of_year(self) -> Self: 

406 """ 

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

408 """ 

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

410 

411 def _start_of_decade(self) -> Self: 

412 """ 

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

414 """ 

415 year = self.year - self.year % YEARS_PER_DECADE 

416 

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

418 

419 def _end_of_decade(self) -> Self: 

420 """ 

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

422 """ 

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

424 

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

426 

427 def _start_of_century(self) -> Self: 

428 """ 

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

430 """ 

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

432 

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

434 

435 def _end_of_century(self) -> Self: 

436 """ 

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

438 """ 

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

440 

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

442 

443 def _start_of_week(self) -> Self: 

444 """ 

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

446 """ 

447 dt = self 

448 

449 if self.day_of_week != pendulum._WEEK_STARTS_AT: 

450 dt = self.previous(pendulum._WEEK_STARTS_AT) 

451 

452 return dt.start_of("day") 

453 

454 def _end_of_week(self) -> Self: 

455 """ 

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

457 """ 

458 dt = self 

459 

460 if self.day_of_week != pendulum._WEEK_ENDS_AT: 

461 dt = self.next(pendulum._WEEK_ENDS_AT) 

462 

463 return dt.end_of("day") 

464 

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

466 """ 

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

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

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

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

471 

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

473 """ 

474 if day_of_week is None: 

475 day_of_week = self.day_of_week 

476 

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

478 raise ValueError("Invalid day of week") 

479 

480 dt = self.add(days=1) 

481 while dt.day_of_week != day_of_week: 

482 dt = dt.add(days=1) 

483 

484 return dt 

485 

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

487 """ 

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

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

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

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

492 

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

494 """ 

495 if day_of_week is None: 

496 day_of_week = self.day_of_week 

497 

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

499 raise ValueError("Invalid day of week") 

500 

501 dt = self.subtract(days=1) 

502 while dt.day_of_week != day_of_week: 

503 dt = dt.subtract(days=1) 

504 

505 return dt 

506 

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

508 """ 

509 Returns an instance set to the first occurrence 

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

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

512 Use the supplied consts to indicate the desired day_of_week, 

513 ex. pendulum.MONDAY. 

514 

515 Supported units are month, quarter and year. 

516 

517 :param unit: The unit to use 

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

519 """ 

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

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

522 

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

524 

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

526 """ 

527 Returns an instance set to the last occurrence 

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

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

530 Use the supplied consts to indicate the desired day_of_week, 

531 ex. pendulum.MONDAY. 

532 

533 Supported units are month, quarter and year. 

534 

535 :param unit: The unit to use 

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

537 """ 

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

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

540 

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

542 

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

544 """ 

545 Returns a new instance set to the given occurrence 

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

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

548 then raise an error. Use the supplied consts 

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

550 

551 Supported units are month, quarter and year. 

552 

553 :param unit: The unit to use 

554 :param nth: The occurrence to use 

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

556 """ 

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

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

559 

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

561 if not dt: 

562 raise PendulumException( 

563 f"Unable to find occurrence {nth}" 

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

565 ) 

566 

567 return dt 

568 

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

570 """ 

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

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

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

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

575 

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

577 """ 

578 dt = self 

579 

580 if day_of_week is None: 

581 return dt.set(day=1) 

582 

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

584 

585 calendar_day = day_of_week 

586 

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

588 day_of_month = month[0][calendar_day] 

589 else: 

590 day_of_month = month[1][calendar_day] 

591 

592 return dt.set(day=day_of_month) 

593 

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

595 """ 

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

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

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

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

600 

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

602 """ 

603 dt = self 

604 

605 if day_of_week is None: 

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

607 

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

609 

610 calendar_day = day_of_week 

611 

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

613 day_of_month = month[-1][calendar_day] 

614 else: 

615 day_of_month = month[-2][calendar_day] 

616 

617 return dt.set(day=day_of_month) 

618 

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

620 """ 

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

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

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

624 modifications are made. Use the supplied consts 

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

626 """ 

627 if nth == 1: 

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

629 

630 dt = self.first_of("month") 

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

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

633 dt = dt.next(day_of_week) 

634 

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

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

637 

638 return None 

639 

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

641 """ 

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

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

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

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

646 """ 

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

648 "month", day_of_week 

649 ) 

650 

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

652 """ 

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

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

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

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

657 """ 

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

659 

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

661 """ 

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

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

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

665 modifications are made. Use the supplied consts 

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

667 """ 

668 if nth == 1: 

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

670 

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

672 last_month = dt.month 

673 year = dt.year 

674 dt = dt.first_of("quarter") 

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

676 dt = dt.next(day_of_week) 

677 

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

679 return None 

680 

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

682 

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

684 """ 

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

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

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

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

689 """ 

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

691 

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

693 """ 

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

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

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

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

698 """ 

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

700 

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

702 """ 

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

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

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

706 modifications are made. Use the supplied consts 

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

708 """ 

709 if nth == 1: 

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

711 

712 dt = self.first_of("year") 

713 year = dt.year 

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

715 dt = dt.next(day_of_week) 

716 

717 if year != dt.year: 

718 return None 

719 

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

721 

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

723 """ 

724 Modify the current instance to the average 

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

726 """ 

727 if dt is None: 

728 dt = Date.today() 

729 

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

731 

732 # Native methods override 

733 

734 @classmethod 

735 def today(cls) -> Self: 

736 dt = date.today() 

737 

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

739 

740 @classmethod 

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

742 dt = super().fromtimestamp(t) 

743 

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

745 

746 @classmethod 

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

748 dt = super().fromordinal(n) 

749 

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

751 

752 def replace( 

753 self, 

754 year: SupportsIndex | None = None, 

755 month: SupportsIndex | None = None, 

756 day: SupportsIndex | None = None, 

757 ) -> Self: 

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

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

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

761 

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