Skip to content

Conversation

@Sjoerd-Bo3
Copy link
Contributor

@Sjoerd-Bo3 Sjoerd-Bo3 commented Jul 5, 2025

Summary

  • Fixed timezone boundary alignment causing 0g carbs in summary while chart showed 75g
  • Extended fix to all statistics types (Meal, TDD, Bolus) with same issue
  • Ensures consistent day boundary calculations between chart display and summary data

Description

This PR resolves issue #687 where users (particularly in negative UTC timezones like UTC-7) experienced discrepancies between statistics chart data and summary calculations. The main symptom was charts correctly showing 75g of carbs while the summary displayed 0g.

Root Cause

The issue stemmed from inconsistent date boundary calculations:

  • Chart data: Used complex timezone alignment logic in StatChartUtils.visibleDateRange()
  • Summary data: Used simple calendar.startOfDay() grouping during data collection
  • Filter logic: Used direct date comparison without day boundary alignment

This created misaligned date ranges that failed to match cached data, especially problematic for users in negative UTC offsets.

Solution

Standardized all date boundary logic to use consistent calendar.startOfDay() approach:

  1. Simplified chart date range calculation - Removed complex time-based alignment
  2. Fixed summary filtering - Added day boundary alignment before filtering cached data
  3. Applied to all statistics - Extended fix to Meal, TDD, and Bolus statistics

Test plan

  • Verify meal summary matches chart data for carbs
  • Test with negative UTC timezone scenarios (UTC-7)
  • Confirm TDD and Bolus summaries also display correctly
  • Check regional formatting changes don't affect results
  • Validate fix works across different time intervals (day/week/month)

Fixes #687

Fixed discrepancy between carb data displayed in main graph vs summary
by ensuring consistent day boundary calculations between chart data and
summary calculations.

Key changes:
- Simplified visibleDateRange() to use same startOfDay() logic as meal data grouping
- Removed complex time-based alignment that caused issues for negative UTC timezones
- Added day boundary alignment in calculateAveragesForDateRange()
- Ensures both chart display and summary use identical date boundaries

Fixes nightscout#687
Extended the timezone boundary fix to TDD and Bolus statistics which had
the same date alignment issue as meal statistics. All summary calculations
now use consistent startOfDay() logic matching the chart data grouping.

- Fixed calculateTDDAveragesForDateRange() in TDDSetup.swift
- Fixed calculateBolusAveragesForDateRange() and calculateBolusTotalsForDateRange() in BolusStatsSetup.swift
- Ensures all statistics summaries work correctly for users in negative UTC timezones

Related to nightscout#687
Copy link

@kingst kingst left a comment

Choose a reason for hiding this comment

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

Tested it in my simulator and it appears to be working. I left one comment, but there are a few -1 for dates can you double check to make sure that the aligning logic isn't dropping a day at the end?

- Replace sortedEvents.first\! with safe guard statement
- Use TimeInterval.hours(24) for clearer date arithmetic
- Addresses kingst's feedback about potential crashes and timezone handling

This ensures the app won't crash with empty event arrays and makes
the date calculation logic more explicit and safer.
- Test -1 second logic across full UTC offset spectrum (-11 to +14)
- Verify empty events are handled without forced unwrap crashes
- Test DST transitions maintain correct day boundaries
- Ensure multiple consecutive days work correctly

Tests specifically verify kingst's concern that the -1 second
adjustment doesn't accidentally drop days with negative UTC offsets.

Signed-off-by: Sjoerd Bozon <[email protected]>
@Sjoerd-Bo3
Copy link
Contributor Author

Sjoerd-Bo3 commented Jul 6, 2025

@kingst, I've addressed your feedback about the forced unwraps and the concern about the -1 logic potentially dropping days. Thanks for catching that!

Changes Made

  1. Removed forced unwraps: Replaced sortedEvents.first!.timestamp with a safe guard statement that returns an empty array if there are no events
  2. Used clearer date arithmetic: Changed to TimeInterval.hours(24) as you suggested

Testing Your Concern

I added comprehensive tests specifically for your worry about the -1 second adjustment. The test testMinusOneLogicAcrossAllTimezones() verifies that:

  • The -1 logic works correctly across all UTC offsets (from UTC-11 to UTC+14)
  • Tests specifically stress-test with late evening times (23:30) when timezone differences are most pronounced
  • Verifies that startOfDay and endOfDay always remain on the same calendar day
  • Confirms we get exactly 23:59:59 as the end time

For example, in Hawaii (UTC-10), when it's 11:30 PM on Jan 15, it's already 9:30 AM Jan 16 in UTC. The tests confirm that our calculation still correctly produces Jan 15 00:00:00 to Jan 15 23:59:59, not accidentally dropping back to
Jan 14.

Also tested:

  • DST transitions (spring forward/fall back)
  • Half-hour offset timezones like India (UTC+5:30)
  • Multiple consecutive days

The fix is split into two commits:

  1. The actual code fix removing forced unwraps
  2. The comprehensive test suite

Let me know if you'd like me to adjust anything else!

Copy link

@kingst kingst left a comment

Choose a reason for hiding this comment

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

Looks good! I'm still seeing a forced unwrap on line 44 of Trio/Sources/Modules/Stat/View/StatChartUtils.swift but once you fix that I can approve

Address kingst's code review feedback by replacing forced unwrap with nil coalescing operator on line 44, providing a safe fallback to endOfDay if the date calculation fails.
@Sjoerd-Bo3
Copy link
Contributor Author

Looks good! I'm still seeing a forced unwrap on line 44 of Trio/Sources/Modules/Stat/View/StatChartUtils.swift but once you fix that I can approve

@kingst Fixed

Copy link

@kingst kingst left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for taking this on!

@Sjoerd-Bo3 Sjoerd-Bo3 self-assigned this Jul 7, 2025
Copy link
Contributor

@MikePlante1 MikePlante1 left a comment

Choose a reason for hiding this comment

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

The ending of visible date is incorrect with this PR applied. It should say Jul 2 - Jul 8, but instead it says Jul 2 - Jul 9. I checked the Week charts for TDD, Meals, Bolus Distribution, Percentile (by day), and Distribution (by day), and they all showed Jul 2 - Jul 9.

start end
IMG_7789 IMG_7788

@mountrcg
Copy link
Contributor

mountrcg commented Aug 8, 2025

@Sjoerd-Bo3 can confirm @MikePlante1 comment. It is less critical than what you fixed, but most probably can be remedied by setting that end date -1?

@dnzxy
Copy link
Contributor

dnzxy commented Aug 11, 2025

Status here?

@dnzxy dnzxy added the stale label Aug 11, 2025
@dnzxy
Copy link
Contributor

dnzxy commented Nov 1, 2025

3 months later, status here?

@github-actions github-actions bot removed the stale label Nov 2, 2025
@mountrcg
Copy link
Contributor

mountrcg commented Nov 2, 2025

I have been using this for the 3 months, the issue with d+1 being shown in the the time intervall for week or month etc.. Mike mentions is still there. But it’s the lesser evil compared to what was being fixed.

@dnzxy
Copy link
Contributor

dnzxy commented Nov 2, 2025

So this PR isn’t done cause we don’t fix one thing to break another.

Please fix the date offset, then this can move up.

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.

5 participants