diff --git a/std/datetime/README.md b/std/datetime/README.md index ae6b6f133e..e9142f48ad 100644 --- a/std/datetime/README.md +++ b/std/datetime/README.md @@ -40,7 +40,7 @@ currentDayOfYear(); // output: ** depends on when you run it :) ** ### weekOfYear -- `weekOfYear(date: Date)` - Returns the week number of the provided date (1-53) +Returns the ISO week number of the provided date (1-53) ```ts import { weekOfYear } from "https://deno.land/std/datetime/mod.ts"; diff --git a/std/datetime/mod.ts b/std/datetime/mod.ts index 4264645646..9665a92b29 100644 --- a/std/datetime/mod.ts +++ b/std/datetime/mod.ts @@ -8,6 +8,17 @@ export const MINUTE = SECOND * 60; export const HOUR = MINUTE * 60; export const DAY = HOUR * 24; export const WEEK = DAY * 7; +const DAYS_PER_WEEK = 7; + +enum Day { + Sun, + Mon, + Tue, + Wed, + Thu, + Fri, + Sat, +} function execForce(reg: RegExp, pat: string): RegExpExecArray { const v = reg.exec(pat); @@ -110,6 +121,14 @@ export function dayOfYear(date: Date): number { return Math.floor(diff / DAY); } +/** + * Get number of current day in year + * @return Number of current day in year + */ +export function currentDayOfYear(): number { + return dayOfYear(new Date()); +} + /** * Get number of the week in the year (ISO-8601) * @return Number of the week in year @@ -119,27 +138,20 @@ export function weekOfYear(date: Date): number { Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) ); - // Set to nearest Thursday: current date + 4 - current day number - // Make Sunday's day number 7 - workingDate.setUTCDate( - workingDate.getUTCDate() + 4 - (workingDate.getUTCDay() || 7) - ); + const day = workingDate.getUTCDay(); + + const nearestThursday = + workingDate.getUTCDate() + + Day.Thu - + (day === Day.Sun ? DAYS_PER_WEEK : day); + + workingDate.setUTCDate(nearestThursday); // Get first day of year const yearStart = new Date(Date.UTC(workingDate.getUTCFullYear(), 0, 1)); // return the calculated full weeks to nearest Thursday - return Math.ceil( - ((workingDate.valueOf() - yearStart.valueOf()) / 86400000 + 1) / 7 - ); -} - -/** - * Get number of current day in year - * @return Number of current day in year - */ -export function currentDayOfYear(): number { - return dayOfYear(new Date()); + return Math.ceil((workingDate.getTime() - yearStart.getTime() + DAY) / WEEK); } /** diff --git a/std/datetime/test.ts b/std/datetime/test.ts index ef4b5dd58e..a223abce22 100644 --- a/std/datetime/test.ts +++ b/std/datetime/test.ts @@ -79,7 +79,7 @@ Deno.test({ }); Deno.test({ - name: "[std/datetime] DayOfYear", + name: "[std/datetime] dayOfYear", fn: () => { assertEquals(datetime.dayOfYear(new Date("2019-01-01T03:24:00")), 1); assertEquals(datetime.dayOfYear(new Date("2019-03-11T03:24:00")), 70); @@ -95,11 +95,65 @@ Deno.test({ }); Deno.test({ - name: "[std/datetime] WeekOfYear", + name: "[std/datetime] weekOfYear", fn: () => { assertEquals(datetime.weekOfYear(new Date("2020-01-05T03:24:00")), 1); assertEquals(datetime.weekOfYear(new Date("2020-12-28T03:24:00")), 53); // 53 weeks in 2020 assertEquals(datetime.weekOfYear(new Date("2020-06-28T03:24:00")), 26); + + // iso weeks year starting sunday + assertEquals(datetime.weekOfYear(new Date(2012, 0, 1)), 52); + assertEquals(datetime.weekOfYear(new Date(2012, 0, 2)), 1); + assertEquals(datetime.weekOfYear(new Date(2012, 0, 8)), 1); + assertEquals(datetime.weekOfYear(new Date(2012, 0, 9)), 2); + assertEquals(datetime.weekOfYear(new Date(2012, 0, 15)), 2); + + // iso weeks year starting monday + assertEquals(datetime.weekOfYear(new Date(2007, 0, 1)), 1); + assertEquals(datetime.weekOfYear(new Date(2007, 0, 7)), 1); + assertEquals(datetime.weekOfYear(new Date(2007, 0, 8)), 2); + assertEquals(datetime.weekOfYear(new Date(2007, 0, 14)), 2); + assertEquals(datetime.weekOfYear(new Date(2007, 0, 15)), 3); + + // iso weeks year starting tuesday + assertEquals(datetime.weekOfYear(new Date(2007, 11, 31)), 1); + assertEquals(datetime.weekOfYear(new Date(2008, 0, 1)), 1); + assertEquals(datetime.weekOfYear(new Date(2008, 0, 6)), 1); + assertEquals(datetime.weekOfYear(new Date(2008, 0, 7)), 2); + assertEquals(datetime.weekOfYear(new Date(2008, 0, 13)), 2); + assertEquals(datetime.weekOfYear(new Date(2008, 0, 14)), 3); + + // iso weeks year starting wednesday + assertEquals(datetime.weekOfYear(new Date(2002, 11, 30)), 1); + assertEquals(datetime.weekOfYear(new Date(2003, 0, 1)), 1); + assertEquals(datetime.weekOfYear(new Date(2003, 0, 5)), 1); + assertEquals(datetime.weekOfYear(new Date(2003, 0, 6)), 2); + assertEquals(datetime.weekOfYear(new Date(2003, 0, 12)), 2); + assertEquals(datetime.weekOfYear(new Date(2003, 0, 13)), 3); + + // iso weeks year starting thursday + assertEquals(datetime.weekOfYear(new Date(2008, 11, 29)), 1); + assertEquals(datetime.weekOfYear(new Date(2009, 0, 1)), 1); + assertEquals(datetime.weekOfYear(new Date(2009, 0, 4)), 1); + assertEquals(datetime.weekOfYear(new Date(2009, 0, 5)), 2); + assertEquals(datetime.weekOfYear(new Date(2009, 0, 11)), 2); + assertEquals(datetime.weekOfYear(new Date(2009, 0, 13)), 3); + + // iso weeks year starting friday + assertEquals(datetime.weekOfYear(new Date(2009, 11, 28)), 53); + assertEquals(datetime.weekOfYear(new Date(2010, 0, 1)), 53); + assertEquals(datetime.weekOfYear(new Date(2010, 0, 3)), 53); + assertEquals(datetime.weekOfYear(new Date(2010, 0, 4)), 1); + assertEquals(datetime.weekOfYear(new Date(2010, 0, 10)), 1); + assertEquals(datetime.weekOfYear(new Date(2010, 0, 11)), 2); + + // iso weeks year starting saturday + assertEquals(datetime.weekOfYear(new Date(2010, 11, 27)), 52); + assertEquals(datetime.weekOfYear(new Date(2011, 0, 1)), 52); + assertEquals(datetime.weekOfYear(new Date(2011, 0, 2)), 52); + assertEquals(datetime.weekOfYear(new Date(2011, 0, 3)), 1); + assertEquals(datetime.weekOfYear(new Date(2011, 0, 9)), 1); + assertEquals(datetime.weekOfYear(new Date(2011, 0, 10)), 2); }, });