flash-calendar icon indicating copy to clipboard operation
flash-calendar copied to clipboard

duplicate days.

Open m-reda1996 opened this issue 2 years ago • 14 comments

sometimes we get duplicate days, it's not consistent but it happens quit often, we're not using anything advanced.


  const [selectedDate, setSelectedDate] = React.useState(() => toDateId(new Date()));
  
<Calendar
  calendarMonthId={currentMonth}
  onCalendarDayPress={(toDateId) => {
    console.log(toDateId);
  }}
  theme={process.env.EXPO_PUBLIC_PRIMARY_DEFAULT === "#EEEEDE" ? linearThemeDark : linearThemeLight}
  />                 
Screenshot 2024-04-16 at 10 35 19 PM Screenshot 2024-04-16 at 10 38 44 PM

m-reda1996 avatar Apr 16 '24 20:04 m-reda1996

This happens to me as well. Here is the scenario that creates the duplicate key warning:

Set the default date to now. Then set the year to 2020, and subtract 1 month from that date.

@MarceloPrado let me know if this didn't reproduce the bug, and then I will create a repro.

AlirezaHadjar avatar Apr 17 '24 07:04 AlirezaHadjar

we're also facing this duplicate day issue.

a-eid avatar Apr 17 '24 11:04 a-eid

Hi folks! Could you share a snippet that helps reproing the issue? Something like this would be really helpful for me

MarceloPrado avatar Apr 18 '24 16:04 MarceloPrado

Sure thing, I'll try to create one in the next week 👍

AlirezaHadjar avatar Apr 21 '24 05:04 AlirezaHadjar

Hi @MarceloPrado, Here is the link to the minimal bug reproducer. Here are the steps to follow to get to the warning:

  1. Clone the repo
  2. Install deps
  3. run the project
  4. Click on the Set Year to 2020
  5. Click on the Reduce Month by 1
  6. Warning shows up

Here is the video of it:

https://github.com/MarceloPrado/flash-calendar/assets/57192409/ce1a2de9-47ab-426f-af4f-0d15222adc33

If you press Reduce Month by 1 a few times more, you will see that the styles of days break. Screenshot 2024-04-26 at 1 34 48 PM

Let me know if you needed any more information 😉

AlirezaHadjar avatar Apr 26 '24 10:04 AlirezaHadjar

@AlirezaHadjar thanks for taking the time with the repro. Interestingly, I can't repro the duplicate key error:

https://github.com/MarceloPrado/flash-calendar/assets/8047841/bf82cbfa-444c-4c32-b640-650d1891a040

I tried running with both bun and yarn, just to rule out any dependency issues. Are you able to repro it consistently?

MarceloPrado avatar Apr 26 '24 13:04 MarceloPrado

@MarceloPrado I'm using yarn and yarn ios for building the project on Expo Go. and yes this happens to me consistently.

https://github.com/MarceloPrado/flash-calendar/assets/57192409/617c93cb-6f16-45ef-9123-4cce671d18c3

AlirezaHadjar avatar Apr 26 '24 13:04 AlirezaHadjar

@a-eid @m-reda1996 could any of you guys try out the repro I shared please and see if the issue happens to you or not? If not, we can reproduce it in another way

AlirezaHadjar avatar Apr 27 '24 20:04 AlirezaHadjar

@AlirezaHadjar I tried again from a different computer and unfortunately it also didn't repro it 😔 It could be easier if you jump into the source code on your side to debug it

MarceloPrado avatar May 06 '24 21:05 MarceloPrado

Yeah sure, I'll do it when I find some free time 🙂

AlirezaHadjar avatar May 06 '24 21:05 AlirezaHadjar

@MarceloPrado I dug deeper and found out that sometimes two dates get the same id and label. And the reason you don't face this is because of our timezone difference.

For example 2020-03-19T20:30:00.000Z and 2020-03-20T19:30:00.000Z will be displayed as 2020 3 20. And that's why I get two 20s on the calendar

Screenshot 2024-05-07 at 9 04 32 PM

I changed

export function toDateId(date: Date) {
  const year = date.getFullYear();
  const month = date.getMonth() + 1; // getMonth() returns 0-11
  const day = date.getDate();

  // Pad single digit month and day with leading zeros
  const monthFormatted = month < 10 ? `0${month}` : month;
  const dayFormatted = day < 10 ? `0${day}` : day;

  return `${year}-${monthFormatted}-${dayFormatted}`;
}

to:

export function toDateId(date: Date) {
  const year = date.getUTCFullYear();
  const month = date.getUTCMonth() + 1; // getMonth() returns 0-11
  const day = date.getUTCDate();

  // Pad single digit month and day with leading zeros
  const monthFormatted = month < 10 ? `0${month}` : month;
  const dayFormatted = day < 10 ? `0${day}` : day;

  return `${year}-${monthFormatted}-${dayFormatted}`;
}

This fixed the id issue but the display function getBaseCalendarDayFormat still displays both of them as 2020 3 20. And I don't think my method is the best option.

BTW, my timezone is Asia/Tehran. I think if you change your timezone to mine, you can reproduce the issue.

AlirezaHadjar avatar May 07 '24 17:05 AlirezaHadjar

@AlirezaHadjar nice find! thanks! I'll work on a fix soon and let you know 🙏

MarceloPrado avatar May 09 '24 17:05 MarceloPrado

I was able to repro locally but don't have a good fix yet. Turns out Tehran abolished DST timezones couple of years ago and I'm not entirely sure the best way to handle that lol

MarceloPrado avatar May 20 '24 21:05 MarceloPrado

This sounds like another one of those date-time edge cases that is unavoidable when working in non-UTC timezones.

My guess is that you'll have to build the dates for each month within the context of the local timezone, rather than from UTC and then converting it into the local timezone.

bryanmylee avatar Feb 06 '25 16:02 bryanmylee