diff --git a/docs/en/I18n.md b/docs/en/I18n.md index 401063aa..f1100da0 100644 --- a/docs/en/I18n.md +++ b/docs/en/I18n.md @@ -92,6 +92,7 @@ const localeObject = { weekdaysShort: 'Sun_M'.split('_'), // OPTIONAL, short weekdays Array, use first three letters if not provided weekdaysMin: 'Su_Mo'.split('_'), // OPTIONAL, min weekdays Array, use first two letters if not provided weekStart: 1, // OPTIONAL, set the start of a week. If the value is 1, Monday will be the start of week instead of Sunday。 + yearStart: 4, // OPTIONAL, the week that contains Jan 4th is the first week of the year. months: 'Enero_Febrero ... '.split('_'), // months Array monthsShort: 'Jan_F'.split('_'), // OPTIONAL, short months Array, use first three letters if not provided ordinal: n => `${n}º`, // ordinal Function (number) => return number + output diff --git a/docs/es-es/I18n.md b/docs/es-es/I18n.md index 98926970..839fb266 100644 --- a/docs/es-es/I18n.md +++ b/docs/es-es/I18n.md @@ -95,6 +95,8 @@ const localeObject = { weekdays: 'Domingo_Lunes ...'.split('_'), // weekdays Array weekdaysShort: 'Sun_M'.split('_'), // OPTIONAL, short weekdays Array, use first three letters if not provided weekdaysMin: 'Su_Mo'.split('_'), // OPTIONAL, min weekdays Array, use first two letters if not provided + weekStart: 1, // OPTIONAL, set the start of a week. If the value is 1, Monday will be the start of week instead of Sunday。 + yearStart: 4, // OPTIONAL, the week that contains Jan 4th is the first week of the year. months: 'Enero_Febrero ... '.split('_'), // months Array monthsShort: 'Jan_F'.split('_'), // OPTIONAL, short months Array, use first three letters if not provided ordinal: n => `${n}º`, // ordinal Function (number) => return number + output diff --git a/docs/ja/I18n.md b/docs/ja/I18n.md index a0dab94f..1fb090b7 100644 --- a/docs/ja/I18n.md +++ b/docs/ja/I18n.md @@ -92,6 +92,7 @@ const localeObject = { weekdaysShort: 'Sun_M'.split('_'), // OPTIONAL, short weekdays Array, use first three letters if not provided weekdaysMin: 'Su_Mo'.split('_'), // OPTIONAL, min weekdays Array, use first two letters if not provided weekStart: 1, // OPTIONAL, 最初の曜日を指定する。0は日曜日です。1は月曜日です。 + yearStart: 4, // OPTIONAL, the week that contains Jan 4th is the first week of the year. months: 'Enero_Febrero ... '.split('_'), // 月の配列 monthsShort: 'Jan_F'.split('_'), // OPTIONAL, short months Array, use first three letters if not provided ordinal: n => `${n}º`, // 序数 Function (number) => return number + output diff --git a/docs/ko/I18n.md b/docs/ko/I18n.md index 5df968cd..e7d73320 100644 --- a/docs/ko/I18n.md +++ b/docs/ko/I18n.md @@ -92,6 +92,7 @@ const localeObject = { weekdaysShort: 'Sun_M'.split('_'), // OPTIONAL, short weekdays Array, use first three letters if not provided weekdaysMin: 'Su_Mo'.split('_'), // OPTIONAL, min weekdays Array, use first two letters if not provided weekStart: 1, // OPTIONAL, set the start of a week. If the value is 1, Monday will be the start of week instead of Sunday。 + yearStart: 4, // OPTIONAL, the week that contains Jan 4th is the first week of the year. months: 'Enero_Febrero ... '.split('_'), // months Array monthsShort: 'Jan_F'.split('_'), // OPTIONAL, short months Array, use first three letters if not provided ordinal: n => `${n}º`, // ordinal Function (number) => return number + output diff --git a/docs/pt-br/I18n.md b/docs/pt-br/I18n.md index 4a383ecf..18fef9b5 100644 --- a/docs/pt-br/I18n.md +++ b/docs/pt-br/I18n.md @@ -92,6 +92,7 @@ const objetoLocale = { weekdaysShort: 'Sun_M'.split('_'), // OPCIONAL, dias da semana com nome curto: Array, utiliza as três primeiras letras se nenhuma for especificada weekdaysMin: 'Su_Mo'.split('_'), // OPCIONAL, dias da semana com nome mínimo: Array, utiliza as duas primeiras letras se nenhuma for especificada weekStart: 1, // OPCIONAL, define o início da semana. Se o valor for 1, Segunda-feira será o início da semana ao invés de Domingo。 + yearStart: 4, // OPTIONAL, the week that contains Jan 4th is the first week of the year. months: 'Enero_Febrero ... '.split('_'), // meses: Array monthsShort: 'Jan_F'.split('_'), // OPCIONAL, meses com nome curto: Array, utiliza as três primeiras letras se nenhuma for especificada ordinal: n => `${n}º`, // ordinal: Function (number) => retorna number + saída diff --git a/docs/zh-cn/I18n.md b/docs/zh-cn/I18n.md index 55b4aa10..29e1875b 100644 --- a/docs/zh-cn/I18n.md +++ b/docs/zh-cn/I18n.md @@ -92,6 +92,7 @@ const localeObject = { weekdaysShort: 'Sun_M'.split('_'), // 可选, 短的星期 Array, 如果没提供则使用前三个字符 weekdaysMin: 'Su_Mo'.split('_'), // 可选, 最短的星期 Array, 如果没提供则使用前两个字符 weekStart: 1, // 可选,指定一周的第一天。默认为0,即周日。如果为1,则周一为一周得第一天。 + yearStart: 4, // 可选,包含1月4日的周为一年的第一周 months: 'Enero_Febrero ... '.split('_'), // 月份 Array monthsShort: 'Jan_F'.split('_'), // 可选, 短的月份 Array, 如果没提供则使用前三个字符 ordinal: n => `${n}º`, // 序号生成工厂函数 Function (number) => return number + output diff --git a/src/locale/en-gb.js b/src/locale/en-gb.js index dfa84d2c..d8cf7e10 100644 --- a/src/locale/en-gb.js +++ b/src/locale/en-gb.js @@ -8,6 +8,7 @@ const locale = { months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), weekStart: 1, + yearStart: 4, relativeTime: { future: 'in %s', past: '%s ago', diff --git a/src/locale/zh-cn.js b/src/locale/zh-cn.js index f1595175..774c6304 100644 --- a/src/locale/zh-cn.js +++ b/src/locale/zh-cn.js @@ -16,6 +16,7 @@ const locale = { } }, weekStart: 1, + yearStart: 4, formats: { LT: 'HH:mm', LTS: 'HH:mm:ss', diff --git a/src/plugin/weekOfYear/index.js b/src/plugin/weekOfYear/index.js index 7251d5af..f0c6088d 100644 --- a/src/plugin/weekOfYear/index.js +++ b/src/plugin/weekOfYear/index.js @@ -1,17 +1,26 @@ import { MS, Y, D, W } from '../../constant' -export default (o, c, d) => { +export default (o, c) => { const proto = c.prototype proto.week = function (week = null) { if (week !== null) { - return this.add((week - this.week()) * 7, 'day') + return this.add((week - this.week()) * 7, D) } - const weekStart = this.$locale().weekStart || 0 - const startOfYear = d(this).startOf(Y) - const compareDay = startOfYear.subtract(startOfYear.day() - weekStart, D).subtract(1, MS) - const diffInWeek = this.diff(compareDay, W, true) - const result = Math.ceil(diffInWeek) - return result > 52 ? 1 : result + const yearStart = this.$locale().yearStart || 1 + if (this.month() === 11 && this.date() > 25) { + const nextYearStartDay = this.startOf(Y).add(1, Y).date(yearStart) + const thisEndOfWeek = this.endOf(W) + if (nextYearStartDay.isBefore(thisEndOfWeek)) { + return 1 + } + } + const yearStartDay = this.startOf(Y).date(yearStart) + const yearStartWeek = yearStartDay.startOf(W).subtract(1, MS) + const diffInWeek = this.diff(yearStartWeek, W, true) + if (diffInWeek < 0) { + return this.startOf('week').week() + } + return Math.ceil(diffInWeek) } proto.weeks = function (week = null) { diff --git a/test/locale/keys.test.js b/test/locale/keys.test.js index a06960a3..5def0014 100644 --- a/test/locale/keys.test.js +++ b/test/locale/keys.test.js @@ -28,6 +28,7 @@ Locale.forEach((locale) => { monthsShort, weekdaysMin, weekStart, + yearStart, meridiem } = locale.content @@ -37,6 +38,7 @@ Locale.forEach((locale) => { if (weekdaysShort) expect(weekdaysShort).toEqual(expect.any(Array)) if (weekdaysMin) expect(weekdaysMin).toEqual(expect.any(Array)) if (weekStart) expect(weekStart).toEqual(expect.any(Number)) + if (yearStart) expect(yearStart).toEqual(expect.any(Number)) // months could be a function or array if (Array.isArray(months)) { diff --git a/test/plugin/weekOfYear.test.js b/test/plugin/weekOfYear.test.js index 980b4bc7..576b0c78 100644 --- a/test/plugin/weekOfYear.test.js +++ b/test/plugin/weekOfYear.test.js @@ -33,14 +33,25 @@ it('Week of year', () => { it('Week of year with locale', () => { dayjs.locale('en-gb') moment.locale('en-gb') - const day = '2019-07-28' expect(dayjs(day).week()).toBe(moment(day).week()) +}) - // Edges - expect(dayjs('2018-12-30').week()).toBe(moment('2018-12-30').week()) - expect(dayjs('2019-12-29').week()).toBe(moment('2019-12-29').week()) - expect(dayjs('2019-12-30').week()).toBe(moment('2019-12-30').week()) +describe('Week of year with locale edges', () => { + const testCases = [ + '2018-12-30', + '2018-12-31', + '2019-12-29', + '2019-12-30', + '2016-01-01', + '2016-01-04' + ] + testCases.forEach((t) => { + it(`Edges ${t}`, () => { + expect(dayjs(t).week()) + .toBe(moment(t).week()) + }) + }) }) it('Format w ww wo', () => { diff --git a/test/plugin/weekday.test.js b/test/plugin/weekday.test.js index 703f3ec8..52b7a938 100644 --- a/test/plugin/weekday.test.js +++ b/test/plugin/weekday.test.js @@ -31,6 +31,10 @@ it('Monday is the first day of the week', () => { expect(dayjs().weekday(0).date()).toBe(moment().weekday(0).date()) expect(dayjs().weekday(-7).format()).toBe(moment().weekday(-7).format()) expect(dayjs().weekday(7).format()).toBe(moment().weekday(7).format()) + const d1 = '2020-01-05' + expect(dayjs(d1).weekday()).toBe(moment(d1).weekday()) + const d2 = '2020-01-07' + expect(dayjs(d2).weekday()).toBe(moment(d2).weekday()) }) it('Saturday is the first day of the week', () => {