@beyonk/date-utils
Advanced tools
Comparing version 4.7.7 to 4.8.0
@@ -95,9 +95,16 @@ import dayjs from 'dayjs' | ||
function getMonthDays (displayedMonth) { | ||
function getMonthDays (displayedMonth, locale) { | ||
const now = localDate() | ||
const weekStartsOn = getFirstDayForLocale(locale) | ||
const requestedMonth = displayedMonth.startOf('month') | ||
const monthStart = requestedMonth.day() | ||
const monthStart = getDay(requestedMonth, { weekStartsOn }) | ||
const daysInMonth = requestedMonth.daysInMonth() | ||
const calendarStart = requestedMonth.subtract(monthStart, 'days') | ||
const tailDays = 7 - (daysInMonth + monthStart) % 7 | ||
const calendarStart = startOfWeek(requestedMonth, { weekStartsOn }) | ||
let tailDays = 7 - (daysInMonth + monthStart) % 7 | ||
if (tailDays >= 7) { | ||
tailDays = tailDays - 7 | ||
} | ||
const totalDays = monthStart + daysInMonth + tailDays | ||
@@ -151,2 +158,24 @@ | ||
function startOfWeek (date, opts = {}) { | ||
const { weekStartsOn = 0 } = opts | ||
const index = getDay(date, { weekStartsOn }) | ||
return date.subtract(index, 'days').startOf('day') | ||
} | ||
function getFirstDayForLocale (locale = 'en-US') { | ||
const chosenLocale = new Intl.Locale(locale) | ||
const weekInfo = (chosenLocale.getWeekInfo?.() || chosenLocale.weekInfo) | ||
return (weekInfo?.firstDay || 7) % 7 | ||
} | ||
function getDay (date, { weekStartsOn = 0 } = {}) { | ||
const days = [ 0, 1, 2, 3, 4, 5, 6 ] | ||
return [ | ||
...days.slice(weekStartsOn), | ||
...days.slice(0, weekStartsOn) | ||
].indexOf( | ||
date.day() | ||
) | ||
} | ||
export { | ||
@@ -167,3 +196,6 @@ localDate, | ||
getMonthDays, | ||
toHumanDuration | ||
toHumanDuration, | ||
startOfWeek, | ||
getFirstDayForLocale, | ||
getDay | ||
} |
@@ -1,2 +0,13 @@ | ||
import { repeatSchedule, utcDate, minsToTime, timeToMins, toHumanDuration, localDate } from './dates.js' | ||
import { | ||
repeatSchedule, | ||
utcDate, | ||
minsToTime, | ||
timeToMins, | ||
toHumanDuration, | ||
localDate, | ||
getMonthDays, | ||
startOfWeek, | ||
getFirstDayForLocale, | ||
getDay | ||
} from './dates.js' | ||
import { expect } from '@hapi/code' | ||
@@ -107,2 +118,258 @@ | ||
}) | ||
describe('#getFirstWeekdayIndexForLocale()', () => { | ||
it('returns correct index for en-GB', () => { | ||
expect( | ||
getFirstDayForLocale('en-GB') | ||
).to.equal(1) | ||
}) | ||
it('returns correct index for en-US', () => { | ||
expect( | ||
getFirstDayForLocale('en-US') | ||
).to.equal(0) | ||
}) | ||
it('returns correct index for ar', () => { | ||
expect( | ||
getFirstDayForLocale('ar') | ||
).to.equal(6) | ||
}) | ||
it('defaults to en-US if locale is undefined', () => { | ||
expect( | ||
getFirstDayForLocale() | ||
).to.equal(0) | ||
}) | ||
}) | ||
describe('#startOfWeek()', () => { | ||
context('when start of week is first week of the month', () => { | ||
const firstDayOfMonth = localDate('2024-09-01') | ||
it('returns correct info for en-GB', () => { | ||
const result = startOfWeek(firstDayOfMonth, { weekStartsOn: 1 }) | ||
expect(result).to.equal(localDate('2024-08-26').startOf('day')) | ||
}) | ||
it('returns correct info for en-US', () => { | ||
const result = startOfWeek(firstDayOfMonth, { weekStartsOn: 0 }) | ||
expect(result).to.equal(localDate('2024-09-01').startOf('day')) | ||
}) | ||
it('returns correct info for ar', () => { | ||
const result = startOfWeek(firstDayOfMonth, { weekStartsOn: 6 }) | ||
expect(result).to.equal(localDate('2024-08-31').startOf('day')) | ||
}) | ||
it('returns correct info when no options are passed - defaults to en-US', () => { | ||
const result = startOfWeek(firstDayOfMonth) | ||
expect(result).to.equal(localDate('2024-09-01').startOf('day')) | ||
}) | ||
}) | ||
context('when start of week is another week of the month', () => { | ||
const anotherDayOfMonth = localDate('2024-09-18') | ||
it('returns correct info for en-GB', () => { | ||
const result = startOfWeek(anotherDayOfMonth, { weekStartsOn: 1 }) | ||
expect(result).to.equal(localDate('2024-09-16').startOf('day')) | ||
}) | ||
it('returns correct info for en-US', () => { | ||
const result = startOfWeek(anotherDayOfMonth, { weekStartsOn: 0 }) | ||
expect(result).to.equal(localDate('2024-09-15').startOf('day')) | ||
}) | ||
it('returns correct info for ar', () => { | ||
const result = startOfWeek(anotherDayOfMonth, { weekStartsOn: 6 }) | ||
expect(result).to.equal(localDate('2024-09-14').startOf('day')) | ||
}) | ||
}) | ||
}) | ||
describe('#getDay()', () => { | ||
context('mid month', () => { | ||
const date = localDate('2024-05-09') | ||
it('returns correct info for en-GB', () => { | ||
const result = getDay(date, { weekStartsOn: 1 }) | ||
expect(result).to.equal(3) | ||
}) | ||
it('returns correct info for en-US', () => { | ||
const result = getDay(date, { weekStartsOn: 0 }) | ||
expect(result).to.equal(4) | ||
}) | ||
it('returns correct info for ar', () => { | ||
const result = getDay(date, { weekStartsOn: 6 }) | ||
expect(result).to.equal(5) | ||
}) | ||
it('returns correct info when no options passed - defaults to en-US', () => { | ||
const result = getDay(date) | ||
expect(result).to.equal(4) | ||
}) | ||
}) | ||
context('start of the month', () => { | ||
const anotherDayOfMonth = localDate('2024-04-01') | ||
it('returns correct info for en-GB', () => { | ||
const result = getDay(anotherDayOfMonth, { weekStartsOn: 1 }) | ||
expect(result).to.equal(0) | ||
}) | ||
it('returns correct info for en-US', () => { | ||
const result = getDay(anotherDayOfMonth, { weekStartsOn: 0 }) | ||
expect(result).to.equal(1) | ||
}) | ||
it('returns correct info for ar', () => { | ||
const result = getDay(anotherDayOfMonth, { weekStartsOn: 6 }) | ||
expect(result).to.equal(2) | ||
}) | ||
it('returns correct info when no options passed - defaults to en-US', () => { | ||
const result = getDay(anotherDayOfMonth) | ||
expect(result).to.equal(1) | ||
}) | ||
}) | ||
}) | ||
describe('#getMonthDays()', () => { | ||
context('check first valid day / first returned day', () => { | ||
context('en-GB', () => { | ||
const firstDayOfMonth = localDate('2024-01-01').startOf('month') | ||
let days = {} | ||
let dateArray = [] | ||
beforeEach(() => { | ||
days = getMonthDays(firstDayOfMonth, 'en-GB') | ||
dateArray = Object.keys(days) | ||
}) | ||
it('returns days object starting from correct day - en-GB', () => { | ||
expect( | ||
dateArray[0] | ||
).to.equal('2024-01-01') | ||
}) | ||
it('returned object has correct info - en-GB - first valid day', () => { | ||
const dateInfo = days[dateArray[0]] | ||
expect( | ||
dateInfo | ||
).to.equal({ | ||
valid: true, | ||
date: firstDayOfMonth, | ||
year: 2024, | ||
month: 1, | ||
day: 1, | ||
dateString: '2024-01-01', | ||
number: '01', | ||
isToday: false | ||
}) | ||
}) | ||
}) | ||
context('en-US', () => { | ||
const firstDayOfMonth = localDate('2024-01-23').startOf('month') | ||
let days | ||
let dateArray | ||
beforeEach(() => { | ||
days = getMonthDays(firstDayOfMonth, 'en-US') | ||
dateArray = Object.keys(days) | ||
}) | ||
it('returns days object starting from correct day - en-US', () => { | ||
expect( | ||
dateArray[0] | ||
).to.equal('2023-12-31') | ||
}) | ||
it('first calendar day has correct info - en-US', () => { | ||
expect( | ||
days[dateArray[0]] | ||
).to.equal({ | ||
valid: false, | ||
date: firstDayOfMonth.subtract(1, 'days'), | ||
year: 2023, | ||
month: 12, | ||
day: 31, | ||
dateString: '2023-12-31', | ||
number: '31', | ||
isToday: false | ||
}) | ||
}) | ||
it('second calendar day has correct info - en-US - first valid day', () => { | ||
expect( | ||
days[dateArray[1]] | ||
).to.equal({ | ||
valid: true, | ||
date: firstDayOfMonth, | ||
year: 2024, | ||
month: 1, | ||
day: 1, | ||
dateString: '2024-01-01', | ||
number: '01', | ||
isToday: false | ||
}) | ||
}) | ||
}) | ||
context('ar', () => { | ||
const firstDayOfMonth = localDate('2024-01-13').startOf('month') | ||
let days | ||
let dateArray | ||
beforeEach(() => { | ||
days = getMonthDays(firstDayOfMonth, 'ar') | ||
dateArray = Object.keys(days) | ||
}) | ||
it('returns days object starting from correct day - ar', () => { | ||
expect( | ||
dateArray[0] | ||
).to.equal('2023-12-30') | ||
}) | ||
it('first calendar day has correct info - ar', () => { | ||
expect( | ||
days[dateArray[0]] | ||
).to.equal({ | ||
valid: false, | ||
date: firstDayOfMonth.subtract(2, 'days'), | ||
year: 2023, | ||
month: 12, | ||
day: 30, | ||
dateString: '2023-12-30', | ||
number: '30', | ||
isToday: false | ||
}) | ||
}) | ||
it('third calendar day has correct info - ar - first valid day', () => { | ||
expect( | ||
days[dateArray[2]] | ||
).to.equal({ | ||
valid: true, | ||
date: firstDayOfMonth, | ||
year: 2024, | ||
month: 1, | ||
day: 1, | ||
dateString: '2024-01-01', | ||
number: '01', | ||
isToday: false | ||
}) | ||
}) | ||
}) | ||
}) | ||
context('check number of days (tail days)', () => { | ||
it('returns correct numbers of days - no tail days - en-US', () => { | ||
const firstDayOfMonth = localDate('2024-08-10').startOf('month') | ||
const days = getMonthDays(firstDayOfMonth, 'en-US') | ||
expect( | ||
Object.keys(days).length | ||
).to.equal(35) | ||
}) | ||
it('returns correct numbers of days - no tail days - ar', () => { | ||
const firstDayOfMonth = localDate('2024-05-10').startOf('month') | ||
const days = getMonthDays(firstDayOfMonth, 'ar') | ||
expect( | ||
Object.keys(days).length | ||
).to.equal(35) | ||
}) | ||
}) | ||
}) | ||
}) |
{ | ||
"name": "@beyonk/date-utils", | ||
"version": "4.7.7", | ||
"version": "4.8.0", | ||
"description": "Beyonk Date Utils", | ||
@@ -5,0 +5,0 @@ "author": "Antony Jones <aj@desirableobjects.co.uk>", |
Sorry, the diff of this file is not supported yet
54922
1780