Skip to content

Commit

Permalink
convert getWeekOfMonth to TypeScript (date-fns#2598)
Browse files Browse the repository at this point in the history
  • Loading branch information
fturmel authored Dec 21, 2021
1 parent 3188709 commit f1d3dc1
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 47 deletions.
52 changes: 20 additions & 32 deletions src/getWeekOfMonth/index.js → src/getWeekOfMonth/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import getDate from '../getDate/index'
import getDay from '../getDay/index'
import startOfMonth from '../startOfMonth/index'
import toInteger from '../_lib/toInteger/index'
import type { LocaleOptions, WeekStartOptions } from '../types'
import requiredArgs from '../_lib/requiredArgs/index'
import toInteger from '../_lib/toInteger/index'

/**
* @name getWeekOfMonth
Expand All @@ -22,51 +23,38 @@ import requiredArgs from '../_lib/requiredArgs/index'
* @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Number} the week of month
* @throws {TypeError} 1 argument required
* @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
* @throws {RangeError} `options.weekStartsOn` must be between 0 and 6 inclusively
*
* @example
* // Which week of the month is 9 November 2017?
* var result = getWeekOfMonth(new Date(2017, 10, 9))
* const result = getWeekOfMonth(new Date(2017, 10, 9))
* //=> 2
*/
export default function getWeekOfMonth(date, dirtyOptions) {
export default function getWeekOfMonth(
date: Date | number,
options?: LocaleOptions & WeekStartOptions
): number {
requiredArgs(1, arguments)

var options = dirtyOptions || {}
var locale = options.locale
var localeWeekStartsOn =
locale && locale.options && locale.options.weekStartsOn
var defaultWeekStartsOn =
localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn)
var weekStartsOn =
options.weekStartsOn == null
? defaultWeekStartsOn
const defaultWeekStartsOn = options?.locale?.options?.weekStartsOn || 0

const weekStartsOn =
options?.weekStartsOn == null
? toInteger(defaultWeekStartsOn)
: toInteger(options.weekStartsOn)

// Test if weekStartsOn is between 0 and 6 _and_ is not NaN
if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
throw new RangeError('weekStartsOn must be between 0 and 6 inclusively')
}

var currentDayOfMonth = getDate(date)
if (isNaN(currentDayOfMonth)) {
return currentDayOfMonth
}
const currentDayOfMonth = getDate(date)
if (isNaN(currentDayOfMonth)) return NaN

var startWeekDay = getDay(startOfMonth(date))
var lastDayOfFirstWeek = 0
const startWeekDay = getDay(startOfMonth(date))

if (startWeekDay >= weekStartsOn) {
lastDayOfFirstWeek = weekStartsOn + 7 - startWeekDay
} else {
lastDayOfFirstWeek = weekStartsOn - startWeekDay
}

var weekNumber = 1
let lastDayOfFirstWeek = weekStartsOn - startWeekDay
if (lastDayOfFirstWeek <= 0) lastDayOfFirstWeek += 7

if (currentDayOfMonth > lastDayOfFirstWeek) {
var remainingDaysAfterFirstWeek = currentDayOfMonth - lastDayOfFirstWeek
weekNumber = weekNumber + Math.ceil(remainingDaysAfterFirstWeek / 7)
}
return weekNumber
const remainingDaysAfterFirstWeek = currentDayOfMonth - lastDayOfFirstWeek
return Math.ceil(remainingDaysAfterFirstWeek / 7) + 1
}
43 changes: 28 additions & 15 deletions src/getWeekOfMonth/test.js → src/getWeekOfMonth/test.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
// @flow
/* eslint-env mocha */

import assert from 'power-assert'
import assert from 'assert'
import getWeekOfMonth from '.'

describe('getWeekOfMonth', function () {
it('returns the week of the month of the given date', function () {
var result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 15))
const result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 15))
assert(result === 3)
})

describe('edge cases', function () {
describe('when the given day is the first of a month', function () {
it('returns the week of the month of the given date', function () {
var result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 1))
const result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 1))
assert(result === 1)
})
})

describe('when the given day is the last of a month #1', function () {
it('returns the week of the month of the given date', function () {
var result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 30))
const result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 30))
assert(result === 5)
})
})

describe('when the given day is the last of a month #2', function () {
it('returns the week of the month of the given date', function () {
var result = getWeekOfMonth(new Date(2017, 9 /* Oct */, 31))
const result = getWeekOfMonth(new Date(2017, 9 /* Oct */, 31))
assert(result === 5)
})
})
})

it('allows to specify which day is the first day of the week', function () {
var result = getWeekOfMonth(new Date(2017, 9 /* Oct */, 1), {
const result = getWeekOfMonth(new Date(2017, 9 /* Oct */, 1), {
weekStartsOn: 1,
})
assert(result === 1)
})

it('allows to specify which day is the first day of the week in locale', function () {
var result = getWeekOfMonth(new Date(2017, 9 /* Oct */, 31), {
// $ExpectedMistake
const result = getWeekOfMonth(new Date(2017, 9 /* Oct */, 31), {
// @ts-expect-error
locale: {
options: { weekStartsOn: 1 },
},
Expand All @@ -51,9 +50,9 @@ describe('getWeekOfMonth', function () {
})

it('`options.weekStartsOn` overwrites the first day of the week specified in locale', function () {
var result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 13), {
const result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 13), {
weekStartsOn: 1,
// $ExpectedMistake
// @ts-expect-error
locale: {
options: { weekStartsOn: 0 },
},
Expand All @@ -62,29 +61,43 @@ describe('getWeekOfMonth', function () {
})

it('accepts a timestamp', function () {
var result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 1).getTime())
const result = getWeekOfMonth(new Date(2017, 10 /* Nov */, 1).getTime())
assert(result === 1)
})

it('throws RangeError exception if `weekStartsOn` is out of bound', function () {
assert.throws(
// @ts-expect-error
getWeekOfMonth.bind(null, new Date(2019, 4 /* May */, 5), {
weekStartsOn: 7,
}),
RangeError
)
})

it('returns NaN if the given date is invalid', function () {
var result = getWeekOfMonth(new Date(NaN))
const result = getWeekOfMonth(new Date(NaN))
assert(isNaN(result))
})

it('throws TypeError exception if passed less than 1 argument', function () {
// @ts-expect-error
assert.throws(getWeekOfMonth.bind(null), TypeError)
})

it('throws RangeError exception weekStartsOn is NaN', function () {
try {
getWeekOfMonth(new Date(2017, 10 /* Nov */, 1), { weekStartsOn: NaN })
getWeekOfMonth(new Date(2017, 10 /* Nov */, 1), {
// @ts-expect-error
weekStartsOn: NaN,
})
} catch (e) {
assert(e instanceof RangeError)
}
})

it('returns the week of the month of the given date, when the given date is sunday', function () {
var result = getWeekOfMonth(new Date(2019, 4 /* May */, 5), {
const result = getWeekOfMonth(new Date(2019, 4 /* May */, 5), {
weekStartsOn: 1,
})
assert(result === 1)
Expand Down

0 comments on commit f1d3dc1

Please sign in to comment.