@@ -107,8 +107,9 @@ export const getFirstDayInMonth = (year: number, month: number): Date =>
107107 new Date ( year , month - 1 , 1 ) ;
108108
109109/**
110- * Gets the week number of the specified date.
111- * Week number according to the ISO-8601 standard, weeks starting on Monday.
110+ * Returns the ISO-8601 week number for the user's week containing the specified date.
111+ * ISO-8601 weeks always start on Monday. When the user's week starts on Sunday or Saturday,
112+ * the date is adjusted to find the corresponding ISO week (based on the Thursday rule).
112113 * The first week of a year is the week that contains the first Thursday of the year (='First 4-day week').
113114 * The highest week number in a year is either 52 or 53.
114115 *
@@ -117,17 +118,23 @@ export const getFirstDayInMonth = (year: number, month: number): Date =>
117118 * @returns The number of the Week
118119 */
119120export const getWeekOfYear = ( date : Date , weekStart : WeekStart ) : number => {
120- // Algorithm rewritten from C# example given at http://en.wikipedia.org/wiki/Talk:ISO_week_date
121- const dayOfWeek = getWeekDayOffset ( date , weekStart ) + 1 ;
122121 const nearestThu = new Date ( date ) ;
123- nearestThu . setDate ( date . getDate ( ) + ( UNITS . thursday - dayOfWeek ) ) ; // get nearest Thursday (-3..+3 days)
122+ nearestThu . setHours ( 0 , 0 , 0 , 0 ) ;
123+ const offset = weekStart === 'monday' ? 0 : weekStart === 'sunday' ? 1 : 2 ;
124+ nearestThu . setDate ( nearestThu . getDate ( ) + offset ) ;
125+ adjustToThursday ( nearestThu ) ;
124126 const year = nearestThu . getFullYear ( ) ;
125- const janfirst = getFirstDayInMonth ( year , 1 ) ;
126- const days = Math . floor ( ( ( nearestThu as any ) - ( janfirst as any ) ) / UNITS . millisecondsPerDay ) ;
127+ const weekOne = new Date ( year , 0 , 4 ) ;
128+ adjustToThursday ( weekOne ) ;
129+ const days = Math . round ( ( nearestThu . getTime ( ) - weekOne . getTime ( ) ) / UNITS . millisecondsPerDay ) ;
127130 const week = 1 + Math . floor ( days / UNITS . daysPerWeek ) ; // Count of Thursdays
128131 return week ;
129132} ;
130133
134+ const adjustToThursday = ( date : Date ) : void => {
135+ date . setDate ( date . getDate ( ) + 3 - ( ( date . getDay ( ) + 6 ) % 7 ) ) ;
136+ } ;
137+
131138export const getWeekDayOffset = ( date : Date , weekStart : WeekStart ) : number => {
132139 const offset = WEEK_START_OFFSET [ weekStart ?? 'monday' ] ;
133140 return ( date . getDay ( ) + 6 - offset ) % 7 ;
0 commit comments