small date utilities
0

Configure Feed

Select the types of activity you want to include in your feed.

pkg-date-fns / lib / mod.ts
22 kB 804 lines
1/** 2 * represents a day of the week as a numeric value (0 = Sunday, 6 = Saturday). 3 */ 4export type DayOfWeek = 0 | 1 | 2 | 3 | 4 | 5 | 6; 5 6/** 7 * returns the Unix timestamp in milliseconds for a given date. 8 * @param date the date to convert. 9 * @returns the Unix timestamp in milliseconds. 10 */ 11/*#__NO_SIDE_EFFECTS__*/ 12export const toUnixMilliseconds = (date: Date): number => { 13 return date.getTime(); 14}; 15 16/** 17 * returns the Unix timestamp in seconds for a given date 18 * @param date the date to convert. 19 * @returns the Unix timestamp in seconds. 20 */ 21/*#__NO_SIDE_EFFECTS__*/ 22export const toUnixSeconds = (date: Date): number => { 23 return Math.floor(toUnixMilliseconds(date) / 1_000); 24}; 25 26/** 27 * converts a date to an ISO 8601 date string (YYYY-MM-DD) in local timezone 28 * @param date the date to format 29 * @returns the formatted date string 30 */ 31/*#__NO_SIDE_EFFECTS__*/ 32export const toISODateString = (date: Date): string => { 33 return date.toLocaleDateString('sv-SE'); 34}; 35 36/** 37 * converts a date to an ISO 8601 datetime string (YYYY-MM-DDTHH:mm:ss.sss) in local timezone 38 * @param date the date to format 39 * @returns the formatted datetime string 40 */ 41/*#__NO_SIDE_EFFECTS__*/ 42export const toISODateTimeString = (date: Date): string => { 43 return date.toLocaleString('sv-SE').replace(' ', 'T') + '.' + ('' + getMilliseconds(date)).padStart(3, '0'); 44}; 45 46/** 47 * returns the milliseconds portion of a given date. 48 * @param date the date to extract from. 49 * @returns the milliseconds portion of the date. 50 */ 51/*#__NO_SIDE_EFFECTS__*/ 52export const getMilliseconds = (date: Date): number => { 53 return date.getMilliseconds(); 54}; 55 56/** 57 * returns the milliseconds portion of a given date in UTC. 58 * @param date the date to extract from. 59 * @returns the milliseconds portion of the date. 60 */ 61/*#__NO_SIDE_EFFECTS__*/ 62export const getUtcMilliseconds = (date: Date): number => { 63 return date.getUTCMilliseconds(); 64}; 65 66/** 67 * returns the seconds portion of a given date. 68 * @param date the date to extract from. 69 * @returns the seconds portion of the date. 70 */ 71/*#__NO_SIDE_EFFECTS__*/ 72export const getSeconds = (date: Date): number => { 73 return date.getSeconds(); 74}; 75 76/** 77 * returns the seconds portion of a given date in UTC. 78 * @param date the date to extract from. 79 * @returns the seconds portion of the date. 80 */ 81/*#__NO_SIDE_EFFECTS__*/ 82export const getUtcSeconds = (date: Date): number => { 83 return date.getUTCSeconds(); 84}; 85 86/** 87 * returns the minutes portion of a given date. 88 * @param date the date to extract from. 89 * @returns the minutes portion of the date. 90 */ 91/*#__NO_SIDE_EFFECTS__*/ 92export const getMinutes = (date: Date): number => { 93 return date.getMinutes(); 94}; 95 96/** 97 * returns the minutes portion of a given date in UTC. 98 * @param date the date to extract from. 99 * @returns the minutes portion of the date. 100 */ 101/*#__NO_SIDE_EFFECTS__*/ 102export const getUtcMinutes = (date: Date): number => { 103 return date.getUTCMinutes(); 104}; 105 106/** 107 * returns the hours portion of a given date. 108 * @param date the date to extract from. 109 * @returns the hours portion of the date. 110 */ 111/*#__NO_SIDE_EFFECTS__*/ 112export const getHours = (date: Date): number => { 113 return date.getHours(); 114}; 115 116/** 117 * returns the hours portion of a given date in UTC. 118 * @param date the date to extract from. 119 * @returns the hours portion of the date. 120 */ 121/*#__NO_SIDE_EFFECTS__*/ 122export const getUtcHours = (date: Date): number => { 123 return date.getUTCHours(); 124}; 125 126/** 127 * returns the day of the week for a given date (0 = Sunday, 6 = Saturday). 128 * @param date the date to extract from. 129 * @returns the day of the week as a number. 130 */ 131/*#__NO_SIDE_EFFECTS__*/ 132export const getDayOfWeek = (date: Date): DayOfWeek => { 133 return date.getDay() as DayOfWeek; 134}; 135 136/** 137 * returns the day of the week for a given date in UTC (0 = Sunday, 6 = Saturday). 138 * @param date the date to extract from. 139 * @returns the day of the week as a number. 140 */ 141/*#__NO_SIDE_EFFECTS__*/ 142export const getUtcDayOfWeek = (date: Date): DayOfWeek => { 143 return date.getUTCDay() as DayOfWeek; 144}; 145 146/** 147 * returns the day of the month for a given date. 148 * @param date the date to extract from. 149 * @returns the day of the month as a number. 150 */ 151/*#__NO_SIDE_EFFECTS__*/ 152export const getDayOfMonth = (date: Date): number => { 153 return date.getDate(); 154}; 155 156/** 157 * returns the day of the month for a given date in UTC. 158 * @param date the date to extract from. 159 * @returns the day of the month as a number. 160 */ 161/*#__NO_SIDE_EFFECTS__*/ 162export const getUtcDayOfMonth = (date: Date): number => { 163 return date.getUTCDate(); 164}; 165 166/** 167 * returns the month portion of a given date (0 = January, 11 = December). 168 * @param date the date to extract from. 169 * @returns the month as a number. 170 */ 171/*#__NO_SIDE_EFFECTS__*/ 172export const getMonth = (date: Date): number => { 173 return date.getMonth(); 174}; 175 176/** 177 * returns the month portion of a given date in UTC (0 = January, 11 = December). 178 * @param date the date to extract from. 179 * @returns the month as a number. 180 */ 181/*#__NO_SIDE_EFFECTS__*/ 182export const getUtcMonth = (date: Date): number => { 183 return date.getUTCMonth(); 184}; 185 186/** 187 * returns the year portion of a given date. 188 * @param date the date to extract from. 189 * @returns the year as a number. 190 */ 191/*#__NO_SIDE_EFFECTS__*/ 192export const getYear = (date: Date): number => { 193 return date.getFullYear(); 194}; 195 196/** 197 * returns the year portion of a given date in UTC. 198 * @param date the date to extract from. 199 * @returns the year as a number. 200 */ 201/*#__NO_SIDE_EFFECTS__*/ 202export const getUtcYear = (date: Date): number => { 203 return date.getUTCFullYear(); 204}; 205 206/** 207 * compares two dates and returns a number indicating their relative order, 208 * in UTC time. 209 * @template TDate 210 * @param a the first date to compare. 211 * @param b the second date to compare. 212 * @returns -1 if a is before b, 1 if a is after b, or 0 if they are equal. 213 */ 214/*#__NO_SIDE_EFFECTS__*/ 215export const compareUtcAsc = <TDate extends Date>(a: TDate, b: TDate): number => { 216 const aMs = toUnixMilliseconds(a); 217 const bMs = toUnixMilliseconds(b); 218 219 if (aMs < bMs) { 220 return -1; 221 } 222 if (aMs > bMs) { 223 return 1; 224 } 225 return 0; 226}; 227 228/** 229 * compares two dates and returns a number indicating their relative order, 230 * in local time. 231 * @template TDate 232 * @param a the first date to compare. 233 * @param b the second date to compare. 234 * @returns -1 if a is before b, 1 if a is after b, or 0 if they are equal. 235 */ 236/*#__NO_SIDE_EFFECTS__*/ 237export const compareLocalAsc = <TDate extends Date>(a: TDate, b: TDate): number => { 238 const diff = getMilliseconds(a) - getMilliseconds(b) || 239 getSeconds(a) - getSeconds(b) || 240 getMinutes(a) - getMinutes(b) || 241 getHours(a) - getHours(b) || 242 getDayOfMonth(a) - getDayOfMonth(b) || 243 getMonth(a) - getMonth(b) || 244 getYear(a) - getYear(b); 245 246 if (diff < 0) { 247 return -1; 248 } 249 if (diff > 0) { 250 return 1; 251 } 252 return 0; 253}; 254 255/** 256 * checks if a date is before another date. 257 * @template TDate 258 * @param a the date to compare. 259 * @param b the date to compare against. 260 * @returns true if first date is before the second, false otherwise. 261 */ 262/*#__NO_SIDE_EFFECTS__*/ 263export const isBeforeDate = <TDate extends Date>(a: TDate, b: TDate): boolean => { 264 return a !== b && toUnixMilliseconds(a) < toUnixMilliseconds(b); 265}; 266 267/** 268 * checks if a date is after another date. 269 * @template TDate 270 * @param a the date to compare. 271 * @param b the date to compare against. 272 * @returns true if the first date is after the second, false otherwise. 273 */ 274/*#__NO_SIDE_EFFECTS__*/ 275export const isAfterDate = <TDate extends Date>(a: TDate, b: TDate): boolean => { 276 return a !== b && toUnixMilliseconds(a) > toUnixMilliseconds(b); 277}; 278 279/** 280 * checks if two dates are exactly the same. 281 * @template TDate 282 * @param a the first date to compare. 283 * @param b the second date to compare. 284 * @returns true if the two dates are the same, false otherwise. 285 */ 286/*#__NO_SIDE_EFFECTS__*/ 287export const isSameDate = <TDate extends Date>(a: TDate, b: TDate): boolean => { 288 return a === b || toUnixMilliseconds(a) === toUnixMilliseconds(b); 289}; 290 291/** 292 * checks if two dates fall on the same calendar day. 293 * @template TDate 294 * @param a the first date to compare. 295 * @param b the second date to compare. 296 * @returns true if the two dates fall on the same calendar day, false otherwise. 297 */ 298/*#__NO_SIDE_EFFECTS__*/ 299export const isSameCalendarDate = <TDate extends Date>(a: TDate, b: TDate): boolean => { 300 if (a === b) { 301 return true; 302 } 303 return ( 304 getDayOfMonth(a) === getDayOfMonth(b) && 305 getMonth(a) === getMonth(b) && 306 getYear(a) === getYear(b) 307 ); 308}; 309 310/** 311 * checks if two dates fall in the same calendar month. 312 * @template TDate 313 * @param a the first date to compare. 314 * @param b the second date to compare. 315 * @returns true if the two dates are in the same month, false otherwise. 316 */ 317/*#__NO_SIDE_EFFECTS__*/ 318export const isSameCalendarMonth = <TDate extends Date>(a: TDate, b: TDate): boolean => { 319 if (a === b) { 320 return true; 321 } 322 return ( 323 getMonth(a) === getMonth(b) && 324 getYear(a) === getYear(b) 325 ); 326}; 327 328/** 329 * checks if two dates fall in the same calendar year. 330 * @template TDate 331 * @param a the first date to compare. 332 * @param b the second date to compare. 333 * @returns true if the two dates are in the same year, false otherwise. 334 */ 335/*#__NO_SIDE_EFFECTS__*/ 336export const isSameCalendarYear = <TDate extends Date>(a: TDate, b: TDate): boolean => { 337 if (a === b) { 338 return true; 339 } 340 return getYear(a) === getYear(b); 341}; 342 343/** 344 * returns the earlier of two dates. 345 * @template TDate 346 * @param a the first date to compare. 347 * @param b the second date to compare. 348 * @returns the earlier of the two dates. 349 */ 350/*#__NO_SIDE_EFFECTS__*/ 351export const min = <TDate extends Date>(a: TDate, b: TDate): TDate => { 352 return isBeforeDate(a, b) ? a : b; 353}; 354 355/** 356 * returns the later of two dates. 357 * @template TDate 358 * @param a the first date to compare. 359 * @param b the second date to compare. 360 * @returns the later of the two dates. 361 */ 362/*#__NO_SIDE_EFFECTS__*/ 363export const max = <TDate extends Date>(a: TDate, b: TDate): TDate => { 364 return isAfterDate(a, b) ? a : b; 365}; 366 367/** 368 * clamps a date between a minimum and maximum range. 369 * @template TDate 370 * @param date the date to clamp. 371 * @param min the minimum allowable date. 372 * @param max the maximum allowable date. 373 * @returns the clamped date. 374 */ 375/*#__NO_SIDE_EFFECTS__*/ 376export const clamp = <TDate extends Date>( 377 date: TDate, 378 min: TDate | undefined, 379 max: TDate | undefined, 380): TDate => { 381 if (min !== undefined && isBeforeDate(date, min)) { 382 return min; 383 } 384 385 if (max !== undefined && isAfterDate(date, max)) { 386 return max; 387 } 388 389 return date; 390}; 391 392/** 393 * calculates the difference in milliseconds between two dates. 394 * @template TDate 395 * @param a the first date. 396 * @param b the second date. 397 * @returns the difference in milliseconds. 398 */ 399/*#__NO_SIDE_EFFECTS__*/ 400export const differenceInMilliseconds = <TDate extends Date>(a: TDate, b: TDate): number => { 401 return toUnixMilliseconds(a) - toUnixMilliseconds(b); 402}; 403 404/** 405 * calculates the difference in seconds between two dates. 406 * @template TDate 407 * @param a the first date. 408 * @param b the second date. 409 * @returns the difference in seconds. 410 */ 411/*#__NO_SIDE_EFFECTS__*/ 412export const differenceInSeconds = <TDate extends Date>(a: TDate, b: TDate): number => { 413 return Math.trunc(differenceInMilliseconds(a, b) / 1_000); 414}; 415 416/** 417 * calculates the difference in minutes between two dates. 418 * @template TDate 419 * @param a the first date. 420 * @param b the second date. 421 * @returns the difference in minutes. 422 */ 423/*#__NO_SIDE_EFFECTS__*/ 424export const differenceInMinutes = <TDate extends Date>(a: TDate, b: TDate): number => { 425 return Math.trunc(differenceInMilliseconds(a, b) / 60_000); 426}; 427 428/** 429 * calculates the difference in hours between two dates. 430 * @template TDate 431 * @param a the first date. 432 * @param b the second date. 433 * @returns the difference in hours. 434 */ 435/*#__NO_SIDE_EFFECTS__*/ 436export const differenceInHours = <TDate extends Date>(a: TDate, b: TDate): number => { 437 return Math.trunc(differenceInMilliseconds(a, b) / 3_600_000); 438}; 439 440/** 441 * calculates the difference in days between two dates. 442 * @template TDate 443 * @param a the first date. 444 * @param b the second date. 445 * @returns the difference in days. 446 */ 447/*#__NO_SIDE_EFFECTS__*/ 448export const differenceInDays = <TDate extends Date>(a: TDate, b: TDate): number => { 449 return Math.trunc(differenceInMilliseconds(a, b) / 86_400_000); 450}; 451 452/** 453 * calculates the difference in calendar days between two dates. 454 * @template TDate 455 * @param a the first date. 456 * @param b the second date. 457 * @returns the difference in calendar days. 458 */ 459/*#__NO_SIDE_EFFECTS__*/ 460export const differenceInCalendarDays = <TDate extends Date>(a: TDate, b: TDate): number => { 461 return differenceInDays(startOfDay(a), startOfDay(b)); 462}; 463 464/** 465 * calculates the difference in weeks between two dates. 466 * @template TDate 467 * @param a the first date. 468 * @param b the second date. 469 * @returns the difference in weeks. 470 */ 471/*#__NO_SIDE_EFFECTS__*/ 472export const differenceInWeeks = <TDate extends Date>(a: TDate, b: TDate): number => { 473 return Math.trunc(differenceInDays(a, b) / 7); 474}; 475 476/** 477 * calculates the difference in calendar weeks between two dates. 478 * @template TDate 479 * @param a the first date. 480 * @param b the second date. 481 * @returns the difference in calendar weeks. 482 */ 483/*#__NO_SIDE_EFFECTS__*/ 484export const differenceInCalendarWeeks = <TDate extends Date>(a: TDate, b: TDate): number => { 485 return differenceInWeeks(startOfWeek(a), startOfWeek(b)); 486}; 487 488/** 489 * calculates the difference in months between two dates. 490 * @template TDate 491 * @param a the first date. 492 * @param b the second date. 493 * @returns the difference in months. 494 */ 495/*#__NO_SIDE_EFFECTS__*/ 496export const differenceInMonths = <TDate extends Date>(a: TDate, b: TDate): number => { 497 return (getYear(a) - getYear(b)) * 12 + (getMonth(a) - getMonth(b)); 498}; 499 500/** 501 * calculates the difference in calendar months between two dates. 502 * @template TDate 503 * @param a the first date. 504 * @param b the second date. 505 * @returns the difference in calendar months. 506 */ 507/*#__NO_SIDE_EFFECTS__*/ 508export const differenceInCalendarMonths = <TDate extends Date>(a: TDate, b: TDate): number => { 509 return differenceInMonths(startOfMonth(a), startOfMonth(b)); 510}; 511 512/** 513 * calculates the difference in years between two dates. 514 * @template TDate 515 * @param a the first date. 516 * @param b the second date. 517 * @returns the difference in years. 518 */ 519/*#__NO_SIDE_EFFECTS__*/ 520export const differenceInYears = <TDate extends Date>(a: TDate, b: TDate): number => { 521 return getYear(a) - getYear(b); 522}; 523 524/** 525 * calculates the difference in calendar years between two dates. 526 * @template TDate 527 * @param a the first date. 528 * @param b the second date. 529 * @returns the difference in calendar years. 530 */ 531/*#__NO_SIDE_EFFECTS__*/ 532export const differenceInCalendarYears = <TDate extends Date>(a: TDate, b: TDate): number => { 533 return differenceInYears(startOfYear(a), startOfYear(b)); 534}; 535 536type DateConstructor<TDate extends Date> = { new (value: number | string | TDate): TDate }; 537 538/** 539 * creates a copy of a given date. 540 * @template TDate 541 * @param date the date to clone. 542 * @returns a new date object with the same value as the input date. 543 */ 544/*#__NO_SIDE_EFFECTS__*/ 545export const cloneDate = <TDate extends Date>(date: TDate): TDate => { 546 return new (date.constructor as DateConstructor<TDate>)(date); 547}; 548 549/** 550 * returns the start of the day for a given date. 551 * @template TDate 552 * @param date the date to find the start of the day for. 553 * @returns a new date set to the start of the day. 554 */ 555/*#__NO_SIDE_EFFECTS__*/ 556export const startOfDay = <TDate extends Date>(date: TDate): TDate => { 557 const d = cloneDate(date); 558 559 d.setHours(0, 0, 0, 0); 560 return d; 561}; 562 563/** 564 * returns the end of the day for a given date. 565 * @template TDate 566 * @param date the date to find the end of the day for. 567 * @returns a new date set to the end of the day. 568 */ 569/*#__NO_SIDE_EFFECTS__*/ 570export const endOfDay = <TDate extends Date>(date: TDate): TDate => { 571 const d = cloneDate(date); 572 573 d.setHours(23, 59, 59, 999); 574 return d; 575}; 576 577/** 578 * returns the start of the week for a given date. 579 * @template TDate 580 * @param date the date to find the start of the week for. 581 * @returns a new date set to the start of the week. 582 */ 583/*#__NO_SIDE_EFFECTS__*/ 584export const startOfWeek = <TDate extends Date>(date: TDate): TDate => { 585 const d = cloneDate(date); 586 587 d.setDate(getDayOfMonth(d) - getDayOfWeek(d)); 588 d.setHours(0, 0, 0, 0); 589 return d; 590}; 591 592/** 593 * returns the end of the week for a given date. 594 * @template TDate 595 * @param date the date to find the end of the week for. 596 * @returns a new date set to the end of the week. 597 */ 598/*#__NO_SIDE_EFFECTS__*/ 599export const endOfWeek = <TDate extends Date>(date: TDate): TDate => { 600 const d = cloneDate(date); 601 602 d.setDate(getDayOfMonth(d) + (6 - getDayOfWeek(d))); 603 d.setHours(23, 59, 59, 999); 604 return d; 605}; 606 607/** 608 * returns the start of the month for a given date. 609 * @template TDate 610 * @param date the date to find the start of the month for. 611 * @returns a new date set to the start of the month. 612 */ 613/*#__NO_SIDE_EFFECTS__*/ 614export const startOfMonth = <TDate extends Date>(date: TDate): TDate => { 615 const d = cloneDate(date); 616 617 d.setDate(1); 618 d.setHours(0, 0, 0, 0); 619 return d; 620}; 621 622/** 623 * returns the end of the month for a given date. 624 * @template TDate 625 * @param date the date to find the end of the month for. 626 * @returns a new date set to the end of the month. 627 */ 628/*#__NO_SIDE_EFFECTS__*/ 629export const endOfMonth = <TDate extends Date>(date: TDate): TDate => { 630 const d = cloneDate(date); 631 632 d.setMonth(getMonth(d) + 1, 0); 633 d.setHours(23, 59, 59, 999); 634 return d; 635}; 636 637/** 638 * returns the start of the year for a given date. 639 * @template TDate 640 * @param date the date to find the start of the year for. 641 * @returns a new date set to the start of the year. 642 */ 643/*#__NO_SIDE_EFFECTS__*/ 644export const startOfYear = <TDate extends Date>(date: TDate): TDate => { 645 const d = cloneDate(date); 646 647 d.setMonth(0, 1); 648 d.setHours(0, 0, 0, 0); 649 return d; 650}; 651 652/** 653 * returns the end of the year for a given date. 654 * @template TDate 655 * @param date the date to find the end of the year for. 656 * @returns a new date set to the end of the year. 657 */ 658/*#__NO_SIDE_EFFECTS__*/ 659export const endOfYear = <TDate extends Date>(date: TDate): TDate => { 660 const d = cloneDate(date); 661 662 d.setMonth(11, 31); 663 d.setHours(23, 59, 59, 999); 664 return d; 665}; 666 667/** 668 * adds a specified number of milliseconds to a date. 669 * @template TDate 670 * @param date the date to add milliseconds to. 671 * @param milliseconds the number of milliseconds to add. 672 * @returns a new date with the added milliseconds. 673 */ 674/*#__NO_SIDE_EFFECTS__*/ 675export const addMilliseconds = <TDate extends Date>(date: TDate, milliseconds: number): TDate => { 676 const d = cloneDate(date); 677 678 d.setMilliseconds(getMilliseconds(d) + milliseconds); 679 return d; 680}; 681 682/** 683 * adds a specified number of seconds to a date. 684 * @template TDate 685 * @param date the date to add seconds to. 686 * @param seconds the number of seconds to add. 687 * @returns a new date with the added seconds. 688 */ 689/*#__NO_SIDE_EFFECTS__*/ 690export const addSeconds = <TDate extends Date>(date: TDate, seconds: number): TDate => { 691 const d = cloneDate(date); 692 693 d.setSeconds(getSeconds(d) + seconds); 694 return d; 695}; 696 697/** 698 * adds a specified number of minutes to a date. 699 * @template TDate 700 * @param date the date to add minutes to. 701 * @param minutes the number of minutes to add. 702 * @returns a new date with the added minutes. 703 */ 704/*#__NO_SIDE_EFFECTS__*/ 705export const addMinutes = <TDate extends Date>(date: TDate, minutes: number): TDate => { 706 const d = cloneDate(date); 707 708 d.setMinutes(getMinutes(d) + minutes); 709 return d; 710}; 711 712/** 713 * adds a specified number of hours to a date. 714 * @template TDate 715 * @param date the date to add hours to. 716 * @param hours the number of hours to add. 717 * @returns a new date with the added hours. 718 */ 719/*#__NO_SIDE_EFFECTS__*/ 720export const addHours = <TDate extends Date>(date: TDate, hours: number): TDate => { 721 const d = cloneDate(date); 722 723 d.setHours(getHours(d) + hours); 724 return d; 725}; 726 727/** 728 * adds a specified number of days to a date. 729 * @template TDate 730 * @param date the date to add days to. 731 * @param days the number of days to add. 732 * @returns a new date with the added days. 733 */ 734/*#__NO_SIDE_EFFECTS__*/ 735export const addDays = <TDate extends Date>(date: TDate, days: number): TDate => { 736 const d = cloneDate(date); 737 738 d.setDate(getDayOfMonth(d) + days); 739 return d; 740}; 741 742/** 743 * adds a specified number of months to a date. 744 * @template TDate 745 * @param date the date to add months to. 746 * @param months the number of months to add. 747 * @returns a new date with the added months. 748 */ 749/*#__NO_SIDE_EFFECTS__*/ 750export const addMonths = <TDate extends Date>(date: TDate, months: number): TDate => { 751 const d = cloneDate(date); 752 753 d.setMonth(getMonth(d) + months); 754 return d; 755}; 756 757/** 758 * adds a specified number of years to a date. 759 * @template TDate 760 * @param date the date to add years to. 761 * @param years the number of years to add. 762 * @returns a new date with the added years. 763 */ 764/*#__NO_SIDE_EFFECTS__*/ 765export const addYears = <TDate extends Date>(date: TDate, years: number): TDate => { 766 const d = cloneDate(date); 767 768 d.setFullYear(getYear(d) + years); 769 return d; 770}; 771 772/** 773 * returns the previous occurrence of a specific day of the week. 774 * @template TDate 775 * @param date the starting date. 776 * @param day the target day of the week. 777 * @returns a new date set to the previous occurrence of the specified day. 778 */ 779/*#__NO_SIDE_EFFECTS__*/ 780export const previousDay = <TDate extends Date>(date: TDate, day: DayOfWeek): TDate => { 781 let delta = day - getDayOfWeek(date); 782 if (delta >= 0) { 783 delta -= 7; 784 } 785 786 return addDays(date, delta); 787}; 788 789/** 790 * returns the next occurrence of a specific day of the week. 791 * @template TDate 792 * @param date the starting date. 793 * @param day the target day of the week. 794 * @returns a new date set to the next occurrence of the specified day. 795 */ 796/*#__NO_SIDE_EFFECTS__*/ 797export const nextDay = <TDate extends Date>(date: TDate, day: DayOfWeek): TDate => { 798 let delta = day - getDayOfWeek(date); 799 if (delta <= 0) { 800 delta += 7; 801 } 802 803 return addDays(date, delta); 804};