cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

week-calendar-utils.js (2107B)


      1import { daysInYear } from './year';
      2import { createUTCDate } from '../create/date-from-array';
      3
      4// start-of-first-week - start-of-year
      5function firstWeekOffset(year, dow, doy) {
      6    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
      7        fwd = 7 + dow - doy,
      8        // first-week day local weekday -- which local weekday is fwd
      9        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
     10
     11    return -fwdlw + fwd - 1;
     12}
     13
     14// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
     15export function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
     16    var localWeekday = (7 + weekday - dow) % 7,
     17        weekOffset = firstWeekOffset(year, dow, doy),
     18        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
     19        resYear,
     20        resDayOfYear;
     21
     22    if (dayOfYear <= 0) {
     23        resYear = year - 1;
     24        resDayOfYear = daysInYear(resYear) + dayOfYear;
     25    } else if (dayOfYear > daysInYear(year)) {
     26        resYear = year + 1;
     27        resDayOfYear = dayOfYear - daysInYear(year);
     28    } else {
     29        resYear = year;
     30        resDayOfYear = dayOfYear;
     31    }
     32
     33    return {
     34        year: resYear,
     35        dayOfYear: resDayOfYear,
     36    };
     37}
     38
     39export function weekOfYear(mom, dow, doy) {
     40    var weekOffset = firstWeekOffset(mom.year(), dow, doy),
     41        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
     42        resWeek,
     43        resYear;
     44
     45    if (week < 1) {
     46        resYear = mom.year() - 1;
     47        resWeek = week + weeksInYear(resYear, dow, doy);
     48    } else if (week > weeksInYear(mom.year(), dow, doy)) {
     49        resWeek = week - weeksInYear(mom.year(), dow, doy);
     50        resYear = mom.year() + 1;
     51    } else {
     52        resYear = mom.year();
     53        resWeek = week;
     54    }
     55
     56    return {
     57        week: resWeek,
     58        year: resYear,
     59    };
     60}
     61
     62export function weeksInYear(year, dow, doy) {
     63    var weekOffset = firstWeekOffset(year, dow, doy),
     64        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
     65    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
     66}