Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using .add(1,'month') month becomes correct but year becomes previous year. 2023-01-01 -> +1 month -> 2022-02-01 #2810

Open
sbdd opened this issue Jan 16, 2025 · 2 comments

Comments

@sbdd
Copy link

sbdd commented Jan 16, 2025

Describe the Bug
When using dayjs.utc(...).tz('utc').startOf('day') and then adding a month (.add(1, 'month').startOf('month')), the resulting date sometimes jumps back by a year if the start date is January 1st. This only happens in the browser and not in Node.js. It also seems to only happen when you have a utc instances and call .tz('utc') on it.

Expected Behavior
The date should stay in the correct year without rolling back.

Steps to Reproduce

  1. Initialize the date with dayjs.utc('2023-01-01').tz('utc').startOf('day').
  2. Add one month with .add(1, 'month').startOf('month').
  3. Note how the year can shift back.

Demo
[StackBlitz Link](https://stackblitz.com/edit/dayjs-playground-pcr9xsfg?file=index.js)

Environment

  • Day.js Version: 1.11.13
  • OS: Tested on mac os
  • Browser: Chrome
  • Time Zone: Europe/Oslo

Code from stackblitz:

import './style.css';
import dayjs from 'dayjs';
import timezone from 'dayjs/plugin/timezone.js';
import utc from 'dayjs/plugin/utc.js';
dayjs.extend(utc);
dayjs.extend(timezone);

const doDateStuff = (start = '2023-01-01') => {
  const startDate = dayjs.utc(start).tz('utc');

  let current = startDate;
  const dates = [];

  for (let i = 0; i < 10; i++) {
    dates.push(current.format());
    current = current.add(1, 'month').startOf('month');
  }

  return {
    startDate: startDate.format(),
    dates,
  };
};

const doDateStuffBroken = (start = '2023-01-01') => {
  const startDate = dayjs.utc(start).tz('utc').startOf('day'); // broken because of startOf it seems

  let current = startDate;
  const dates = [];

  for (let i = 0; i < 10; i++) {
    dates.push(current);
    current = current.add(1, 'month').startOf('month');
  }

  return {
    year: startDate.year(),
    startDate: startDate.format(),
    dates,
  };
};

const datesCalc = doDateStuff();
const datesCalcBroken = doDateStuffBroken();

// Write Javascript code!
const appDiv = document.getElementById('app');
appDiv.innerHTML = `
<h1>Dates working</h1>
<table>
    <thead>
        <tr>
            <th>DateTime string should be same year</th>         
        </tr>
    </thead>
    <tbody>
        ${datesCalc.dates
          .map((d) => {
            return `<tr>
            <td>${d}</td>          
        </tr>`;
          })
          .join('')}        
    </tbody>
</table>
<h1>Dates Broken - Skips back a year only if jan 1 and using startOf</h1>
<table>
    <thead>
        <tr>
            <th>DateTime string should be same year</th>         
        </tr>
    </thead>
    <tbody>
        ${datesCalcBroken.dates
          .map((d) => {
            return `<tr>
            <td style="background-color: ${
              d.year() !== datesCalcBroken.year ? 'red' : 'green'
            }">${d}</td>          
        </tr>`;
          })
          .join('')}        
    </tbody>
</table>
`;
@sbdd sbdd changed the title When using .add(1,'month') month becomes correct but year becomes year. 2023-01-01 -> +1 month -> 2022-02-01 When using .add(1,'month') month becomes correct but year becomes previous year. 2023-01-01 -> +1 month -> 2022-02-01 Jan 16, 2025
@github-roushan
Copy link

dayjs has a lot of issues. you should use other datetime libraries.

@github-roushan
Copy link

@sbdd. There you go. Fixed your code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants