Differences in behavior between moment and dayjs when parsing objects
- Dominant language
- JavaScript
- Stars
- 48.7k
- Forks
- 2.5k
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
The following can be run in `https://npm.runkit.com/` to demonstrate the problem. The results between moment and dayjs at consistent in most cases but not for `result_from_object` and `result_from_utc_string` cases. Why are they different? Which library is right and which is wrong?
```
var dayjs = require("dayjs")
var utc = require('dayjs/plugin/utc');
var timezone = require('dayjs/plugin/timezone');
var advanced = require('dayjs/plugin/advancedFormat');
var objectSupport = require('dayjs/plugin/objectSupport');
var duration = require('dayjs/plugin/duration');
var arraySupport = require('dayjs/plugin/arraySupport');
var isBetween = require('dayjs/plugin/isBetween');
var localizedFormat = require('dayjs/plugin/localizedFormat');
dayjs.extend(utc);
dayjs.extend(advanced);
dayjs.extend(objectSupport);
dayjs.extend(duration);
dayjs.extend(timezone);
dayjs.extend(arraySupport);
dayjs.extend(isBetween);
dayjs.extend(localizedFormat);
var moment = require("moment-timezone");
// old
const timeZonedMoment = (date = new Date(), timeZone = '') => {
return timeZone ? moment.tz(date, timeZone) : moment(date);
}
// new
const timeZonedDay = (date = new Date(), timeZone = '') => {
if (timeZone === 'UTC' || timeZone === 'utc') {
return dayjs(date).utc(true).tz(timeZone);
}
return timeZone ? dayjs.tz(date, timeZone) : dayjs(date);
// I thought that this would have the same result as above, but it does not in all cases
// return timeZone ? dayjs(date).tz(timeZone) : dayjs(date);
}
const result_from_epoch = [
timeZonedMoment(1570690800000, "Europe/Madrid").format(),
timeZonedDay(1570690800000, "Europe/Madrid").format(),
timeZonedDay(1570690800000, "America/Los_Angeles").format(),
];
const result_from_js_date = [
timeZonedMoment(new Date(2019, 9, 10), "Europe/Madrid").format(),
timeZonedDay(new Date(2019, 9, 10), "Europe/Madrid").format(),
timeZonedDay(new Date(2019, 9, 10), "America/Los_Angeles").format(),
];
const result_from_object = [
timeZonedMoment({year: 2019, month: 9, day: 10}, "Europe/Madrid").format(),
timeZonedDay({year: 2019, month: 9, day: 10}, "Europe/Madrid").format(),
timeZonedDay({year: 2019, month: 9, day: 10}, "America/Los_Angeles").format(),
];
const result_from_string = [
timeZonedMoment("2019-10-10T00:00:00", "Europe/Madrid").format(),
timeZonedDay("2019-10-10T00:00:00", "Europe/Madrid").format(),
timeZonedDay("2019-10-10T00:00:00", "America/Los_Angeles").format(),
]
const result_from_utc_string = [
timeZonedMoment("2019-10-10T00:00:00Z", "Europe/Madrid").format(),
timeZonedDay("2019-10-10T00:00:00Z", "Europe/Madrid").format(),
timeZonedDay("2019-10-10T00:00:00Z", "America/Los_Angeles").format(),
]
console.log('result_from_epoch = ' + result_from_epoch);
console.log('result_from_js_date = ' + result_from_js_date);
console.log('result_from_object = ' + result_from_object);
console.log('result_from_string = ' + result_from_string);
console.log('result_from_utc_string = ' + result_from_utc_string);
```
**Expected behavior**
The results between moment and dayjs should be consistent for object and utc-string cases. If they are not, then one of the libraries has a bug.
**Information**
- Day.js Version - 1.11.7
- OS: Mac in PST timezone
- Browser - chrome
- Time zone: PST
Contributor guide
Research direction
Start by running the provided RunKit reproduction with Day.js 1.11.7, focusing on the result_from_object and result_from_utc_string cases and the timeZonedMoment/timeZonedDay entry points. Compare the objectSupport and timezone behavior with Moment, then determine which result is intended and document or test the corrected behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100