diff --git a/src/plugin/isoWeek/index.js b/src/plugin/isoWeek/index.js new file mode 100644 index 000000000..79e6fab33 --- /dev/null +++ b/src/plugin/isoWeek/index.js @@ -0,0 +1,51 @@ +import { D, W, Y } from '../../constant' + +const isoWeekPrettyUnit = 'isoweek' + +export default (o, c, d) => { + const getYearFirstThursday = (year) => { + const yearFirstDay = d().year(year).startOf(Y) + let addDiffDays = 4 - yearFirstDay.isoWeekday() + if (yearFirstDay.isoWeekday() > 4) { + addDiffDays += 7 + } + return yearFirstDay.add(addDiffDays, D) + } + + const getCurrentWeekThursday = ins => ins.add((4 - ins.isoWeekday()), D) + + const proto = c.prototype + + proto.isoWeekYear = function () { + const nowWeekThursday = getCurrentWeekThursday(this) + return nowWeekThursday.year() + } + + proto.isoWeek = function (week) { + if (!this.$utils().u(week)) { + return this.add((week - this.isoWeek()) * 7, D) + } + const nowWeekThursday = getCurrentWeekThursday(this) + const diffWeekThursday = getYearFirstThursday(this.isoWeekYear()) + return nowWeekThursday.diff(diffWeekThursday, W) + 1 + } + + proto.isoWeekday = function (week) { + if (!this.$utils().u(week)) { + return this.day(this.day() % 7 ? week : week - 7) + } + return this.day() || 7 + } + + const oldStartOf = proto.startOf + proto.startOf = function (units, startOf) { + const utils = this.$utils() + const isStartOf = !utils.u(startOf) ? startOf : true + const unit = utils.p(units) + if (unit === isoWeekPrettyUnit) { + return isStartOf ? this.date(this.date() - (this.isoWeekday() - 1)).startOf('day') : + this.date((this.date() - 1 - (this.isoWeekday() - 1)) + 7).endOf('day') + } + return oldStartOf.bind(this)(units, startOf) + } +} diff --git a/src/plugin/isoWeekOfYear/index.js b/src/plugin/isoWeekOfYear/index.js deleted file mode 100644 index 480064189..000000000 --- a/src/plugin/isoWeekOfYear/index.js +++ /dev/null @@ -1,32 +0,0 @@ -export default (o, c, d) => { - const days = function (day) { - const weekDay = day.day() - return weekDay === 0 ? 7 : weekDay - } - - const getYearFirstThursday = function (year) { - const yearFirstDay = d().year(year).startOf('year') - let addDiffDays = 4 - days(yearFirstDay) - if (days(yearFirstDay) > 4) { - addDiffDays += 7 - } - return yearFirstDay.add(addDiffDays, 'day') - } - - const proto = c.prototype - - proto.isoWeekYear = function () { - const nowWeekThursday = d(this).add((4 - days(this)), 'day') - return nowWeekThursday.year() - } - - proto.isoWeek = function (isoWeek = null) { - if (isoWeek !== null) { - return this.add((isoWeek - this.isoWeek()) * 7, 'day') - } - - const nowWeekThursday = d(this).add((4 - days(this)), 'day') - const diffWeekThursday = getYearFirstThursday(this.isoWeekYear()) - return nowWeekThursday.diff(diffWeekThursday, 'week') + 1 - } -} diff --git a/test/plugin/isoWeekOfYear.test.js b/test/plugin/isoWeek.test.js similarity index 77% rename from test/plugin/isoWeekOfYear.test.js rename to test/plugin/isoWeek.test.js index ebca13e06..8c2157f2f 100644 --- a/test/plugin/isoWeekOfYear.test.js +++ b/test/plugin/isoWeek.test.js @@ -1,8 +1,9 @@ import MockDate from 'mockdate' +import moment from 'moment' import dayjs from '../../src' -import isoWeekOfYear from '../../src/plugin/isoWeekOfYear' +import isoWeek from '../../src/plugin/isoWeek' -dayjs.extend(isoWeekOfYear) +dayjs.extend(isoWeek) beforeEach(() => { MockDate.set(new Date()) @@ -12,6 +13,34 @@ afterEach(() => { MockDate.reset() }) +it('get isoWeek', () => { + expect(dayjs().isoWeek()).toBe(moment().isoWeek()) +}) + +it('set isoWeek', () => { + expect(dayjs().isoWeek(1).valueOf()).toBe(moment().isoWeek(1).valueOf()) + expect(dayjs().isoWeek(52).valueOf()).toBe(moment().isoWeek(52).valueOf()) +}) + +it('get isoWeekYear', () => { + expect(dayjs().isoWeekYear()).toBe(moment().isoWeekYear()) +}) + +it('startOf/endOf isoWeek', () => { + const ISOWEEK = 'isoWeek' + expect(dayjs().startOf(ISOWEEK).valueOf()).toBe(moment().startOf(ISOWEEK).valueOf()) + expect(dayjs().endOf(ISOWEEK).valueOf()).toBe(moment().endOf(ISOWEEK).valueOf()) +}) + +it('isoWeekday', () => { + expect(dayjs().isoWeekday()).toBe(moment().isoWeekday()) + expect(dayjs('20200301').isoWeekday(1).valueOf()).toBe(moment('20200301').isoWeekday(1).valueOf()) // Sunday this.day() -> 0 + for (let i = 0; i < 7; i += 1) { + expect(dayjs().add(i, 'day').isoWeekday()).toBe(moment().add(i, 'day').isoWeekday()) + expect(dayjs().isoWeekday(i).valueOf()).toBe(moment().isoWeekday(i).valueOf()) + } +}) + it('isoWeek of year', () => { expect(dayjs().isoWeek(1).isoWeek()).toBe(1) expect(dayjs().isoWeek(27).isoWeek()).toBe(27) diff --git a/types/plugin/isoWeek.d.ts b/types/plugin/isoWeek.d.ts new file mode 100644 index 000000000..f60cf95f3 --- /dev/null +++ b/types/plugin/isoWeek.d.ts @@ -0,0 +1,27 @@ +import { PluginFunc, QUnitType, ConfigType } from 'dayjs' + +declare const plugin: PluginFunc +export = plugin + +type ISOUnitType = UnitType | 'isoWeek'; + +declare module 'dayjs' { + interface Dayjs { + isoWeekYear(): number + isoWeek(): number + isoWeek(value: number): Dayjs + + isoWeekday(): number + isoWeekday(value: number): Dayjs + + startOf(unit: ISOUnitType): Dayjs + + endOf(unit: ISOUnitType): Dayjs + + isSame(date: ConfigType, unit?: ISOUnitType): boolean + + isBefore(date: ConfigType, unit?: ISOUnitType): boolean + + isAfter(date: ConfigType, unit?: ISOUnitType): boolean + } +} diff --git a/types/plugin/isoWeekOfYear.d.ts b/types/plugin/isoWeekOfYear.d.ts deleted file mode 100644 index 1ab61f585..000000000 --- a/types/plugin/isoWeekOfYear.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { PluginFunc } from 'dayjs' - -declare const plugin: PluginFunc -export = plugin - -declare module 'dayjs' { - interface Dayjs { - isoWeekYear(): number - isoWeek(): number - - isoWeek(value: number): Dayjs - } -}