Kristjan ESPERANTO 40301f2a59 fix(calendar): correct day-of-week for full-day recurring events across all timezones (#4004)
Fixes **full-day recurring events showing on wrong day** in timezones
west of UTC (reported in #4003).

**Root cause**: `moment.tz(date, eventTimezone).startOf("day")`
interprets UTC midnight as local time:
- `2025-11-03T00:00:00.000Z` in America/Chicago (UTC-6)
- → Converts to `2025-11-02 18:00:00` (6 hours back)
- → `.startOf("day")` → `2025-11-02 00:00:00`  **Wrong day!**

**Impact**: The bug affects:
- All timezones west of UTC (UTC-1 through UTC-12): Americas, Pacific
- Timezones east of UTC (UTC+1 through UTC+12): Europe, Asia, Africa -
work correctly
- UTC itself - works correctly

The issue was introduced with commit c2ec6fc2 (#3976), which fixed the
time but broke the date. This PR fixes both.

| | Result | Day | Time | Notes |
|----------|--------|-----|------|-------|
| **Before c2ec6fc2** | `2025-11-03 05:00:00 Monday` |  |  | Wrong
time, but correct day |
| **Current (c2ec6fc2)** | `2025-11-02 00:00:00 Sunday` |  (west of
UTC)<br> (east of UTC) |  | Wrong day - visible bug! |
| **This fix** | `2025-11-03 00:00:00 Monday` |  |  | Correct in all
timezones |

Note: While the old logic had incorrect timing, it produced the correct
calendar day due to how it handled UTC offsets. The current logic fixed
the timing issue but introduced the more visible calendar day bug.

### Solution

Extract UTC date components and interpret as local calendar dates:

```javascript
const utcYear = date.getUTCFullYear();
const utcMonth = date.getUTCMonth();
const utcDate = date.getUTCDate();
return moment.tz([utcYear, utcMonth, utcDate], eventTimezone);
```

### Testing

To prevent this from happening again in future refactorings, I wrote a
test for it.

```bash
npm test -- tests/unit/modules/default/calendar/calendar_fetcher_utils_spec.js
```
2026-01-04 06:36:16 -06:00
2025-01-08 11:46:42 +01:00
2023-07-01 21:17:31 +02:00
2024-03-16 13:06:27 +01:00
2020-05-11 22:22:32 +02:00
2025-09-30 18:14:08 +02:00
2024-03-28 12:37:18 +01:00
2023-10-01 20:13:41 +02:00

MagicMirror²: The open source modular smart mirror platform.

License GitHub Actions Build Status GitHub Stars

MagicMirror² is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant. MagicMirror² is built by the creator of the original MagicMirror with the incredible help of a growing community of contributors.

MagicMirror² focuses on a modular plugin system and uses Electron as an application wrapper. So no more web server or browser installs necessary!

Animated demonstration of MagicMirror²

Documentation

For the full documentation including installation instructions, please visit our dedicated documentation website: https://docs.magicmirror.builders.

Contributing Guidelines

Contributions of all kinds are welcome, not only in the form of code but also with regards to

  • bug reports
  • documentation
  • translations

For the full contribution guidelines, check out: https://docs.magicmirror.builders/about/contributing.html

Enjoying MagicMirror? Consider a donation!

MagicMirror² is Open Source and free. That doesn't mean we don't need any money.

Please consider a donation to help us cover the ongoing costs like webservers and email services. If we receive enough donations we might even be able to free up some working hours and spend some extra time improving the MagicMirror² core.

To donate, please follow this link.

MagPi Top 50

Description
MagicMirror² is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant.
Readme 66 MiB
Languages
JavaScript 84.2%
HTML 8.6%
CSS 5.6%
Nunjucks 1.5%
TypeScript 0.1%