iamkun / dayjs

⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
https://day.js.org
MIT License
47k stars 2.3k forks source link

daysInMonth() returns 1 for april through october when using timezone #1272

Open mjamin opened 3 years ago

mjamin commented 3 years ago

Describe the bug

dayjs(new Date(2020, 3, 1)).tz().daysInMonth() // returns 30
dayjs(new Date(2020, 3, 1)).tz('America/New_York').daysInMonth() // returns 1

https://stackblitz.com/edit/typescript-tqxa8b?file=index.ts

Information

cianx commented 3 years ago

I am seeing the same issue on dayjs@1.9.8 ubuntu 20.4 node 12.18.2

const dayjs = require('dayjs');

const timezone = require('dayjs/plugin/timezone');
const utc = require('dayjs/plugin/utc');

dayjs.extend(timezone);
dayjs.extend(utc);

const now = dayjs();
console.log('days in local', now.daysInMonth());

const now2 = now.tz('utc');
console.log('days in utc', now2.daysInMonth());

Produces output

days in local 31
days in utc 1
ulfandersson commented 3 years ago

Same issue on dayjs@1.10.4 Windows 10 node 14.16.0

daysInMonth() uses endOf('month') and it's endOf('month') that gives incorrect result:

> dayjs.tz("2021-04-01", 'Europe/Stockholm')
d {
  '$L': 'en',
  '$d': 2021-03-31T22:00:00.000Z,
  '$x': { '$localOffset': -120, '$timezone': 'Europe/Stockholm' },
  '$y': 2021,
  '$M': 3,
  '$D': 1,
  '$W': 4,
  '$H': 0,
  '$m': 0,
  '$s': 0,
  '$ms': 0,
  '$offset': 120
}
> dayjs.tz("2021-04-01", 'Europe/Stockholm').endOf('month')
d {
  '$L': 'en',
  '$offset': 60,
  '$d': 2021-04-30T22:59:59.999Z,
  '$x': { '$timezone': 'Europe/Stockholm' },
  '$y': 2021,
  '$M': 4,
  '$D': 1,
  '$W': 6,
  '$H': 0,
  '$m': 59,
  '$s': 59,
  '$ms': 999
}
DarkEye123 commented 1 month ago

was there any progress? We fought with this issue on last year. We are currently doing some nasty trick

currentSelectedMonth.endOf("month").diff(currentSelectedMonth, "days") + 1