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

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

282 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 

263 @overload 

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

265 ... 

266 

267 @overload 

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

269 ... 

270 

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

272 if isinstance(other, timedelta): 

273 return self._subtract_timedelta(other) 

274 

275 if not isinstance(other, date): 

276 return NotImplemented 

277 

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

279 

280 return dt.diff(self, False) 

281 

282 # DIFFERENCES 

283 

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

285 """ 

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

287 

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

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

290 """ 

291 if dt is None: 

292 dt = self.today() 

293 

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

295 

296 def diff_for_humans( 

297 self, 

298 other: date | None = None, 

299 absolute: bool = False, 

300 locale: str | None = None, 

301 ) -> str: 

302 """ 

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

304 

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

306 1 day ago 

307 5 months ago 

308 

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

310 1 day from now 

311 5 months from now 

312 

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

314 1 day before 

315 5 months before 

316 

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

318 1 day after 

319 5 months after 

320 

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

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

323 :param locale: The locale to use for localization 

324 """ 

325 is_now = other is None 

326 

327 if is_now: 

328 other = self.today() 

329 

330 diff = self.diff(other) 

331 

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

333 

334 # MODIFIERS 

335 

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

337 """ 

338 Returns a copy of the instance with the time reset 

339 with the following rules: 

340 

341 * day: time to 00:00:00 

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

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

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

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

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

347 

348 :param unit: The unit to reset to 

349 """ 

350 if unit not in self._MODIFIERS_VALID_UNITS: 

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

352 

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

354 

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

356 """ 

357 Returns a copy of the instance with the time reset 

358 with the following rules: 

359 

360 * week: date to last day of the week 

361 * month: date to last day of the month 

362 * year: date to last day of the year 

363 * decade: date to last day of the decade 

364 * century: date to last day of century 

365 

366 :param unit: The unit to reset to 

367 """ 

368 if unit not in self._MODIFIERS_VALID_UNITS: 

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

370 

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

372 

373 def _start_of_day(self) -> Self: 

374 """ 

375 Compatibility method. 

376 """ 

377 return self 

378 

379 def _end_of_day(self) -> Self: 

380 """ 

381 Compatibility method 

382 """ 

383 return self 

384 

385 def _start_of_month(self) -> Self: 

386 """ 

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

388 """ 

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

390 

391 def _end_of_month(self) -> Self: 

392 """ 

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

394 """ 

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

396 

397 def _start_of_year(self) -> Self: 

398 """ 

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

400 """ 

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

402 

403 def _end_of_year(self) -> Self: 

404 """ 

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

406 """ 

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

408 

409 def _start_of_decade(self) -> Self: 

410 """ 

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

412 """ 

413 year = self.year - self.year % YEARS_PER_DECADE 

414 

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

416 

417 def _end_of_decade(self) -> Self: 

418 """ 

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

420 """ 

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

422 

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

424 

425 def _start_of_century(self) -> Self: 

426 """ 

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

428 """ 

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

430 

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

432 

433 def _end_of_century(self) -> Self: 

434 """ 

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

436 """ 

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

438 

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

440 

441 def _start_of_week(self) -> Self: 

442 """ 

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

444 """ 

445 dt = self 

446 

447 if self.day_of_week != pendulum._WEEK_STARTS_AT: 

448 dt = self.previous(pendulum._WEEK_STARTS_AT) 

449 

450 return dt.start_of("day") 

451 

452 def _end_of_week(self) -> Self: 

453 """ 

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

455 """ 

456 dt = self 

457 

458 if self.day_of_week != pendulum._WEEK_ENDS_AT: 

459 dt = self.next(pendulum._WEEK_ENDS_AT) 

460 

461 return dt.end_of("day") 

462 

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

464 """ 

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

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

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

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

469 

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

471 """ 

472 if day_of_week is None: 

473 day_of_week = self.day_of_week 

474 

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

476 raise ValueError("Invalid day of week") 

477 

478 dt = self.add(days=1) 

479 while dt.day_of_week != day_of_week: 

480 dt = dt.add(days=1) 

481 

482 return dt 

483 

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

485 """ 

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

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

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

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

490 

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

492 """ 

493 if day_of_week is None: 

494 day_of_week = self.day_of_week 

495 

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

497 raise ValueError("Invalid day of week") 

498 

499 dt = self.subtract(days=1) 

500 while dt.day_of_week != day_of_week: 

501 dt = dt.subtract(days=1) 

502 

503 return dt 

504 

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

506 """ 

507 Returns an instance set to the first occurrence 

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

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

510 Use the supplied consts to indicate the desired day_of_week, 

511 ex. pendulum.MONDAY. 

512 

513 Supported units are month, quarter and year. 

514 

515 :param unit: The unit to use 

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

517 """ 

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

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

520 

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

522 

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

524 """ 

525 Returns an instance set to the last occurrence 

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

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

528 Use the supplied consts to indicate the desired day_of_week, 

529 ex. pendulum.MONDAY. 

530 

531 Supported units are month, quarter and year. 

532 

533 :param unit: The unit to use 

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

535 """ 

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

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

538 

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

540 

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

542 """ 

543 Returns a new instance set to the given occurrence 

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

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

546 then raise an error. Use the supplied consts 

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

548 

549 Supported units are month, quarter and year. 

550 

551 :param unit: The unit to use 

552 :param nth: The occurrence to use 

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

554 """ 

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

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

557 

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

559 if not dt: 

560 raise PendulumException( 

561 f"Unable to find occurrence {nth}" 

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

563 ) 

564 

565 return dt 

566 

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

568 """ 

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

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

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

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

573 

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

575 """ 

576 dt = self 

577 

578 if day_of_week is None: 

579 return dt.set(day=1) 

580 

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

582 

583 calendar_day = day_of_week 

584 

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

586 day_of_month = month[0][calendar_day] 

587 else: 

588 day_of_month = month[1][calendar_day] 

589 

590 return dt.set(day=day_of_month) 

591 

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

593 """ 

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

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

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

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

598 

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

600 """ 

601 dt = self 

602 

603 if day_of_week is None: 

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

605 

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

607 

608 calendar_day = day_of_week 

609 

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

611 day_of_month = month[-1][calendar_day] 

612 else: 

613 day_of_month = month[-2][calendar_day] 

614 

615 return dt.set(day=day_of_month) 

616 

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

618 """ 

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

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

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

622 modifications are made. Use the supplied consts 

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

624 """ 

625 if nth == 1: 

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

627 

628 dt = self.first_of("month") 

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

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

631 dt = dt.next(day_of_week) 

632 

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

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

635 

636 return None 

637 

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

639 """ 

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

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

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

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

644 """ 

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

646 "month", day_of_week 

647 ) 

648 

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

650 """ 

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

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

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

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

655 """ 

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

657 

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

659 """ 

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

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

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

663 modifications are made. Use the supplied consts 

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

665 """ 

666 if nth == 1: 

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

668 

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

670 last_month = dt.month 

671 year = dt.year 

672 dt = dt.first_of("quarter") 

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

674 dt = dt.next(day_of_week) 

675 

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

677 return None 

678 

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

680 

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

682 """ 

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

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

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

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

687 """ 

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

689 

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

691 """ 

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

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

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

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

696 """ 

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

698 

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

700 """ 

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

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

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

704 modifications are made. Use the supplied consts 

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

706 """ 

707 if nth == 1: 

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

709 

710 dt = self.first_of("year") 

711 year = dt.year 

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

713 dt = dt.next(day_of_week) 

714 

715 if year != dt.year: 

716 return None 

717 

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

719 

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

721 """ 

722 Modify the current instance to the average 

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

724 """ 

725 if dt is None: 

726 dt = Date.today() 

727 

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

729 

730 # Native methods override 

731 

732 @classmethod 

733 def today(cls) -> Self: 

734 dt = date.today() 

735 

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

737 

738 @classmethod 

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

740 dt = super().fromtimestamp(t) 

741 

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

743 

744 @classmethod 

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

746 dt = super().fromordinal(n) 

747 

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

749 

750 def replace( 

751 self, 

752 year: SupportsIndex | None = None, 

753 month: SupportsIndex | None = None, 

754 day: SupportsIndex | None = None, 

755 ) -> Self: 

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

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

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

759 

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