From 9631e8d9d3fd6e5e71113e97387c224e6c1eca64 Mon Sep 17 00:00:00 2001 From: Krists Ozols Date: Mon, 16 Nov 2020 19:14:50 +0200 Subject: [PATCH 1/2] Add weekOfYear function --- .../duet-date-picker/date-utils.spec.ts | 13 +++++++++++++ src/components/duet-date-picker/date-utils.ts | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/components/duet-date-picker/date-utils.spec.ts b/src/components/duet-date-picker/date-utils.spec.ts index 594fe9f..c01c100 100644 --- a/src/components/duet-date-picker/date-utils.spec.ts +++ b/src/components/duet-date-picker/date-utils.spec.ts @@ -15,6 +15,7 @@ import { parseISODate, printISODate, DaysOfWeek, + weekOfYear, } from "./date-utils" describe("duet-date-picker/date-utils", () => { @@ -341,4 +342,16 @@ describe("duet-date-picker/date-utils", () => { assertMonth(getViewOfMonth(new Date(2020, 11, 10)), [30, ...range(1, 31), ...range(1, 3)]) }) }) + + describe("weekOfYear", () => { + it("returns the week number of given date", () => { + expect(weekOfYear(new Date(2019, 11, 24))).toEqual(52) + expect(weekOfYear(new Date(2019, 11, 31))).toEqual(1) + expect(weekOfYear(new Date(2020, 0, 1))).toEqual(1) + expect(weekOfYear(new Date(2020, 11, 24))).toEqual(52) + expect(weekOfYear(new Date(2020, 11, 31))).toEqual(53) + expect(weekOfYear(new Date(2021, 0, 3))).toEqual(53) + expect(weekOfYear(new Date(2021, 0, 4))).toEqual(1) + }) + }) }) diff --git a/src/components/duet-date-picker/date-utils.ts b/src/components/duet-date-picker/date-utils.ts index d113014..08ec005 100644 --- a/src/components/duet-date-picker/date-utils.ts +++ b/src/components/duet-date-picker/date-utils.ts @@ -1,4 +1,5 @@ const ISO_DATE_FORMAT = /^(\d{4})-(\d{2})-(\d{2})$/ +const MILLISECONDS_IN_WEEK = 604800000 export enum DaysOfWeek { Sunday = 0, @@ -209,3 +210,21 @@ export function chr4() { export function createIdentifier(prefix) { return `${prefix}-${chr4()}${chr4()}-${chr4()}-${chr4()}-${chr4()}-${chr4()}${chr4()}${chr4()}` } + +export function weekOfYear(date: Date): number { + const givenYear = date.getFullYear() + const fourthOfJanuaryOfGivenYear = startOfWeek(new Date(givenYear, 0, 4)) + const fourthOfJanuaryOfNextYear = startOfWeek(new Date(givenYear + 1, 0, 4)) + let startYear + if (date.getTime() >= fourthOfJanuaryOfNextYear.getTime()) { + startYear = givenYear + 1 + } else if (date.getTime() >= fourthOfJanuaryOfGivenYear.getTime()) { + startYear = givenYear + } else { + startYear = givenYear - 1 + } + const start = startOfWeek(new Date(startYear, 0, 4)) + const end = startOfWeek(date) + const diff = end.getTime() - start.getTime() + return Math.round(diff / MILLISECONDS_IN_WEEK) + 1 +} From 2e7054b230da2430ff50b7d0b4dd692ad4cab821 Mon Sep 17 00:00:00 2001 From: Krists Ozols Date: Mon, 16 Nov 2020 20:12:45 +0200 Subject: [PATCH 2/2] WIP: Add component option to display week numbers --- src/components/duet-date-picker/date-localization.ts | 4 ++++ src/components/duet-date-picker/date-picker-month.tsx | 11 ++++++++++- src/components/duet-date-picker/duet-date-picker.scss | 7 +++++++ src/components/duet-date-picker/duet-date-picker.tsx | 6 ++++++ src/index.html | 7 +++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/components/duet-date-picker/date-localization.ts b/src/components/duet-date-picker/date-localization.ts index c5916f8..89a1d6a 100644 --- a/src/components/duet-date-picker/date-localization.ts +++ b/src/components/duet-date-picker/date-localization.ts @@ -15,6 +15,8 @@ export type DuetLocalizedText = { dayNames: DayNames monthNames: MonthsNames monthNamesShort: MonthsNames + weekNumber: string + weekNumberShort: string } const localization: DuetLocalizedText = { @@ -44,6 +46,8 @@ const localization: DuetLocalizedText = { "December", ], monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + weekNumber: "Week", + weekNumberShort: "#", } export default localization diff --git a/src/components/duet-date-picker/date-picker-month.tsx b/src/components/duet-date-picker/date-picker-month.tsx index 22eafa3..1c83a7f 100644 --- a/src/components/duet-date-picker/date-picker-month.tsx +++ b/src/components/duet-date-picker/date-picker-month.tsx @@ -2,7 +2,7 @@ import { h, FunctionalComponent } from "@stencil/core" import { DuetDateFormatter } from "./date-adapter" import { DuetLocalizedText } from "./date-localization" import { DatePickerDay, DatePickerDayProps } from "./date-picker-day" -import { getViewOfMonth, inRange, DaysOfWeek, isEqual } from "./date-utils" +import { getViewOfMonth, inRange, DaysOfWeek, isEqual, weekOfYear } from "./date-utils" function chunk(array: T[], chunkSize: number): T[][] { const result = [] @@ -35,6 +35,7 @@ type DatePickerMonthProps = { focusedDayRef: (element: HTMLButtonElement) => void onFocusIn?: (e: FocusEvent) => void onMouseDown?: (e: MouseEvent) => void + weekNumbers?: boolean } export const DatePickerMonth: FunctionalComponent = ({ @@ -51,6 +52,7 @@ export const DatePickerMonth: FunctionalComponent = ({ focusedDayRef, onMouseDown, onFocusIn, + weekNumbers, }) => { const today = new Date() const days = getViewOfMonth(focusedDate, firstDayOfWeek) @@ -66,6 +68,12 @@ export const DatePickerMonth: FunctionalComponent = ({ > + {weekNumbers && ( + + + {localization.weekNumber} + + )} {mapWithOffset(localization.dayNames, firstDayOfWeek, dayName => ( @@ -77,6 +85,7 @@ export const DatePickerMonth: FunctionalComponent = ({ {chunk(days, 7).map(week => ( + {weekNumbers && {weekOfYear(week[0])}} {week.map(day => ( diff --git a/src/index.html b/src/index.html index 5211aae..eec77c5 100644 --- a/src/index.html +++ b/src/index.html @@ -514,6 +514,13 @@

Required atrribute

alert("Submitted") }) </script> +
+

Week numbers

+ + +
<label for="date">Choose a date</label>
+<duet-date-picker weeks identifier="date"></duet-date-picker>
+

© 2020 LocalTapiola Services Ltd /