Skip to content

fix: the 10 day forecast shows wrong day/night symbols at certain times#123

Open
jenniferarnesen wants to merge 9 commits into
mainfrom
fix/forecast-timezone
Open

fix: the 10 day forecast shows wrong day/night symbols at certain times#123
jenniferarnesen wants to merge 9 commits into
mainfrom
fix/forecast-timezone

Conversation

@jenniferarnesen
Copy link
Copy Markdown
Collaborator

@jenniferarnesen jenniferarnesen commented May 14, 2026

There are 2 main changes in this fix:

  1. Instead of having the user manually set the timezone in the Settings page, that is only used in the Explore forecast page, automatically detect the timezone based on the org unit location using tz-lookup.
  2. When determining the symbol to display, only use the next_6_hours when the local time is right at the beginning of the period (e.g afternoon is 12-18, so only when the local time is within that first hour of 12-13). Otherwise use the next_1_hour, since that is unlikely to show a night symbol for a day period.

CLIM-22
CLIM-23

@dhis2-bot
Copy link
Copy Markdown
Contributor

dhis2-bot commented May 14, 2026

🚀 Deployed on https://pr-123.climate-app.netlify.dhis2.org

@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 10:01 Inactive
@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 10:05 Inactive
@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 10:09 Inactive
@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 12:44 Inactive
@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 12:50 Inactive
@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 12:51 Inactive
@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 12:52 Inactive
@jenniferarnesen jenniferarnesen changed the title fix: automatically look up the timezone for the org unit when displaying 10 day forecast fix: the 10 day forecast shows wrong day/night symbols at certain times May 14, 2026
@sonarqubecloud
Copy link
Copy Markdown

@dhis2-bot dhis2-bot temporarily deployed to netlify May 14, 2026 12:59 Inactive
Comment thread src/components/explore/forecast/Forecast.cy.jsx
cy.wait('@getForecast')
cy.contains(
'The forecast is using the time zone of your browser'
).should('be.visible')
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node -e "const tz = require('tz-lookup'); console.log(tz(0, -160))"

Returns Pacific/Kiritimati not null. So I think the fallback won't be triggered.

tz-lookup documentation indicates:

The exported function call will throw an error if the latitude or longitude provided are NaN or out of bounds. Otherwise, it will never throw an error and will always return an IANA timezone database string. (Barring bugs.)
https://github.com/photostructure/tz-lookup#usage

The maintenance / metadata management apps prevent entering wrong coordinates, but you can import any numeric value via the API (eg: -999, -999). So guarding against an error from tz-lookup can make sense and keeping the fallback would be relevant.

Note, main fix is in: src/components/explore/forecast/Forecast.jsx

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an invalid coordinate is supplied, then the met api returns 400. In that case, I think an error message should be shown (will update the implementation to do this). The tz-lookup will never happen in this case.

return (
hour >= start &&
hour < end &&
(s.data?.next_6_hours || s.data?.next_1_hours)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some context on the Met.no API first: after ~day 3, the API switches from hourly to 6-hourly resolution. During the transition, a handful of entries (the non-UTC-6h-boundary hours - 01, 02, 03, 04, 05 UTC) still appear in the response with next_1_hours but no longer have next_6_hours. After that, only entries at 00, 06, 12, 18 UTC exist, each with next_6_hours only.

The forecast displays four columns per day: 00-06, 06-12, 12-18, 18-24 local time. The fix to use next_1_hours for mid-column entries solves the day/night symbol issue, but switching from next_6_hours to next_1_hours is problematic for two reasons:

  • Symbol accuracy: next_1_hours and next_6_hours can differ not just on day/night but also on weather condition - e.g. next_6_hours might return lightrainshowers_day if rain is expected later, while next_1_hours returns clearsky_day because it's clear right now.

  • Precipitation: widening the find() condition at L28 means it can now select one of those transition entries that have next_1_hours but no next_6_hours. Even with a ?? next_1_hours fallback, you'd only be capturing 1 hour of rain - next_1_hours.details.precipitation_amount represents the next hour only, not the full 6-hour total.

An alternative worth considering: always use next_6_hours (preserving both rain symbol and precipitation accuracy), but override just the _day/_night suffix based on the local hour.

return undefined
}
const hour = entry.localTime.substring(11, 13)
if (hour === start) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When hour === start and the entry has no next_6_hours (the transition case we identified), it returns undefined instead of falling back to next_1_hours. A simple ?? fallback fixes it.

That said, if you adopt the alternative approach of always using next_6_hours and overriding the _day/_night suffix, this whole function goes away.


const precip = roundOneDecimal(
sixHourSeries.reduce((p, s) => {
const value = s?.data?.next_6_hours?.details?.precipitation_amount
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here again, when find() selects a transition entry with no next_6_hours, this silently returns 0 instead of the actual precipitation. See L28.

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

Successfully merging this pull request may close these issues.

3 participants