Skip to content

Commit

Permalink
fix: Fix weekOfYear plugin to support yearStart locale for better wee…
Browse files Browse the repository at this point in the history
…k number result (#769)
  • Loading branch information
iamkun authored Jan 11, 2020
1 parent 731b947 commit f00db36
Show file tree
Hide file tree
Showing 12 changed files with 48 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/en/I18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions docs/es-es/I18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/ja/I18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/ko/I18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/pt-br/I18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/zh-cn/I18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/locale/en-gb.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/locale/zh-cn.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const locale = {
}
},
weekStart: 1,
yearStart: 4,
formats: {
LT: 'HH:mm',
LTS: 'HH:mm:ss',
Expand Down
25 changes: 17 additions & 8 deletions src/plugin/weekOfYear/index.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions test/locale/keys.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Locale.forEach((locale) => {
monthsShort,
weekdaysMin,
weekStart,
yearStart,
meridiem
} = locale.content

Expand All @@ -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)) {
Expand Down
21 changes: 16 additions & 5 deletions test/plugin/weekOfYear.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
4 changes: 4 additions & 0 deletions test/plugin/weekday.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down

0 comments on commit f00db36

Please sign in to comment.