Skip to content

Conversation

@miraclebakelaser
Copy link

@miraclebakelaser miraclebakelaser commented Jul 17, 2025

Description

Fixes the --reset-hour parameter which was not being used in reset time calculations. The monitor was ignoring the user's custom reset hour setting and falling back to session end times from the API or default 5-hour intervals.

Problem

When using --reset-hour, the monitor would display an incorrect reset time based on the API session end time or default intervals, completely ignoring the user-specified reset hour.

Solution

  • Added get_next_reset_time() method to TimezoneHandler class that calculates the next occurrence of a specific hour in a given timezone.
  • Modified DisplayController to prioritize user's custom reset hour over API end times.
  • Maintained backward compatibility—when no reset hour is specified, the behavior remains unchanged.
  • Added comprehensive test coverage for various timezone and edge case scenarios.

Testing

  • All existing tests pass.
  • Added 12 new tests covering:
    • Custom reset hour calculations (same day/next day)
    • Default interval behavior
    • Timezone conversions
    • Invalid input handling
    • Error conditions with proper fallbacks

Root Cause

The refactored version of the application removed the get_next_reset_time() function that was responsible for calculating the next occurrence of a specific hour in a given timezone. The current code only handled API-provided end times or fell back to a simple time offset, making the --reset-hour parameter effectively non-functional.


Fixes #95

Summary by CodeRabbit

  • New Features

    • Added support for customizable session reset hours and timezones in session time calculations.
    • Introduced a new method to accurately compute the next reset time based on user-specified parameters.
  • Bug Fixes

    • Improved handling of invalid timezone and reset hour inputs, ensuring robust fallback behavior.
  • Tests

    • Added comprehensive tests covering various reset hour, timezone, and error-handling scenarios for the new reset time functionality.

@coderabbitai
Copy link

coderabbitai bot commented Jul 17, 2025

"""

Walkthrough

The changes implement support for a customizable reset hour and timezone in session time calculations. They introduce new parameters to relevant methods, add logic to prioritize user-supplied reset hour and timezone, and provide a utility for calculating the next reset time. Comprehensive tests are added to ensure correct behavior.

Changes

File(s) Change Summary
src/claude_monitor/ui/display_controller.py Added reset_hour and timezone parameters to time calculation methods; updated logic to use them.
src/claude_monitor/utils/time_utils.py Added TimezoneHandler.get_next_reset_time for computing next reset time with custom hour/timezone.
src/tests/test_time_utils.py Added TestGetNextResetTime with tests for various reset hour and timezone scenarios.

Sequence Diagram(s)

sequenceDiagram
    participant CLI/User
    participant DisplayController
    participant SessionCalculator
    participant TimezoneHandler

    CLI/User->>DisplayController: Provide reset_hour, timezone (via args)
    DisplayController->>SessionCalculator: calculate_time_data(..., reset_hour, timezone)
    SessionCalculator->>TimezoneHandler: get_next_reset_time(current_time, reset_hour, timezone)
    TimezoneHandler-->>SessionCalculator: next_reset_time
    SessionCalculator-->>DisplayController: time_data (using next_reset_time)
    DisplayController-->>CLI/User: Display updated reset time
Loading

Assessment against linked issues

Objective Addressed Explanation
Support --reset-hour parameter in reset time calculations (#95)
Ensure reset time uses user-specified hour and timezone when provided (#95)
Fallback to previous/default logic when no custom hour is provided (#95)

Poem

In the warren, time resets anew,
With custom hours and zones in view.
The clocks now tick just as you please,
Across the world, with gentle ease.
🕰️🐇
A hop, a skip, the tests all chime—
Resetting right, and right on time!
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7be84ab and 91115c3.

📒 Files selected for processing (2)
  • src/claude_monitor/utils/time_utils.py (2 hunks)
  • src/tests/test_time_utils.py (21 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/claude_monitor/utils/time_utils.py
🔇 Additional comments (16)
src/tests/test_time_utils.py (16)

5-5: LGTM: Formatting improvements enhance readability.

The formatting changes break long lines appropriately and improve code readability without altering any test logic. These follow Python PEP 8 guidelines.

Also applies to: 67-69, 78-80, 136-138, 229-231, 249-251, 269-271, 273-275, 292-294, 298-300, 309-311, 320-322, 324-326, 329-331, 337-339, 340-342, 355-361, 379-385, 402-404, 426-428, 503-505, 554-556, 572-574, 641-643, 761-763, 768-770, 777-779, 786-788, 808-810


822-824: LGTM: Well-structured test class with comprehensive coverage.

The new test class follows proper naming conventions and provides comprehensive coverage for the get_next_reset_time method functionality.


825-842: LGTM: Comprehensive test for same-day reset scenario.

This test properly validates the core functionality when the reset hour is later in the same day, using proper timezone handling and clear assertions.


844-861: LGTM: Proper test for next-day reset scenario.

This test correctly validates the behavior when the current time is past the reset hour, ensuring the next reset is scheduled for the following day.


863-880: LGTM: Appropriate handling of exact reset time boundary.

This test correctly validates the edge case where the current time is exactly at the reset hour, with the reasonable expectation that it returns the current reset time.


882-899: LGTM: Proper boundary handling for time just after reset hour.

This test correctly validates the boundary behavior when the current time is just after the reset hour, ensuring the next reset is scheduled for the following day.


901-951: LGTM: Excellent comprehensive test ensuring reset time is never in the past.

This test validates the critical invariant that the reset time should never be in the past, with comprehensive boundary condition testing and thorough assertions.


953-964: LGTM: Proper testing of default interval behavior.

This test correctly validates the fallback behavior when no custom reset hour is provided, ensuring the system uses predefined intervals appropriately.


966-977: LGTM: Proper testing of default interval day wrapping.

This test correctly validates the behavior when default intervals need to wrap to the next day, ensuring the system properly handles day boundaries.


979-995: LGTM: Excellent timezone conversion test.

This test properly validates the critical timezone conversion functionality, ensuring accurate time calculations across different timezones with correct UTC conversion.


997-1011: LGTM: Proper error handling test for invalid timezone.

This test correctly validates the fallback behavior for invalid timezone inputs, ensuring graceful error handling with appropriate logging.


1013-1026: LGTM: Proper error handling test for invalid reset hour.

This test correctly validates the fallback behavior for invalid reset hour values, ensuring graceful error handling with appropriate logging and fallback to default intervals.


1028-1040: LGTM: Proper handling of naive datetime input.

This test correctly validates the method's ability to handle naive datetime inputs, ensuring robustness in various input scenarios.


1042-1063: LGTM: Comprehensive error handling test with proper fallback.

This test correctly validates the robust error handling mechanism, ensuring the system has appropriate fallback behavior and error reporting when unexpected exceptions occur.


1065-1097: LGTM: Comprehensive timezone combination test with DST coverage.

This test provides excellent coverage of various timezone combinations and includes DST testing, ensuring the method works correctly across different timezone scenarios.


822-1097: Excellent comprehensive test suite for get_next_reset_time method.

This test class provides outstanding coverage of the new get_next_reset_time functionality with:

  • Comprehensive scenarios: Same-day reset, next-day reset, exact time boundaries, and various timezone combinations
  • Robust error handling: Invalid timezones, invalid reset hours, and exception fallback scenarios
  • Edge case coverage: Naive datetime inputs, DST handling, and boundary conditions
  • Proper test structure: Clear test names, appropriate assertions, and effective use of mocking

The tests align perfectly with the PR objective of fixing the --reset-hour parameter functionality and ensure the implementation is robust and reliable.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/claude_monitor/utils/time_utils.py (1)

538-545: Consider using normalize() for more robust DST handling.

While the current DST handling works, you could make it more robust by using pytz's normalize() method after localization to handle DST transitions properly.

             except Exception as e:
                 logger.warning(f"DST handling issue: {e}, using naive datetime")
                 naive_dt = datetime.combine(
                     next_reset_date, 
                     datetime.min.time().replace(hour=next_reset_hour)
                 )
-                next_reset = target_tz.localize(naive_dt)
+                next_reset = target_tz.normalize(target_tz.localize(naive_dt))
src/tests/test_time_utils.py (1)

803-821: Add test case for seconds handling.

Based on the edge case identified in the main implementation, consider adding a test to verify behavior when the current time has non-zero seconds at the reset hour.

Add this test after test_custom_reset_hour_after_exact_time:

def test_custom_reset_hour_with_seconds(self) -> None:
    """Test when current time is at reset hour but with non-zero seconds."""
    handler = TimezoneHandler("Asia/Seoul")
    # Set current time to 1:00:30 PM in Asia/Seoul (30 seconds past reset hour)
    current_time = pytz.timezone("Asia/Seoul").localize(
        datetime(2024, 1, 1, 13, 0, 30)
    )
    
    # Call get_next_reset_time with reset_hour=13 (1 PM)
    reset_time = handler.get_next_reset_time(
        current_time, reset_hour=13, timezone_str="Asia/Seoul"
    )
    
    # Should return tomorrow's reset time since we're past the hour
    expected = pytz.timezone("Asia/Seoul").localize(
        datetime(2024, 1, 2, 13, 0, 0)
    )
    assert reset_time == expected
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a19040 and 2edda2f.

📒 Files selected for processing (3)
  • src/claude_monitor/ui/display_controller.py (4 hunks)
  • src/claude_monitor/utils/time_utils.py (2 hunks)
  • src/tests/test_time_utils.py (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/claude_monitor/utils/time_utils.py (2)
src/tests/test_calculations.py (1)
  • current_time (157-159)
src/claude_monitor/error_handling.py (1)
  • report_error (21-53)
🔇 Additional comments (8)
src/claude_monitor/utils/time_utils.py (2)

460-481: LGTM! Well-documented method with clear purpose.

The method signature and documentation are comprehensive, providing clear examples and explaining all parameters and return values.


552-564: Excellent error handling with appropriate fallback.

The error handling properly reports the exception with context and falls back to the original behavior (current time + 5 hours), ensuring the application continues to function even if the new logic fails.

src/tests/test_time_utils.py (3)

762-783: Well-structured test for same-day reset scenario.

The test properly validates that when the current time is before the reset hour, it returns the reset time on the same day. Good use of timezone-aware datetime objects.


928-943: Comprehensive error handling test.

Excellent test that verifies the fallback behavior when an exception occurs. The use of mocking to simulate an error and verification of both the fallback result and error reporting is thorough.


945-977: Excellent DST and timezone combination testing.

The test comprehensively validates the method across different timezones including during DST periods (June 15). The assertions properly verify that reset times are at the correct hour in the target timezone.

src/claude_monitor/ui/display_controller.py (3)

74-84: Clean parameter addition maintaining backward compatibility.

The addition of optional reset_hour and timezone parameters is well-implemented, preserving existing functionality while enabling the new feature.


351-356: Safe attribute access with proper defaults.

Good use of getattr with None defaults to handle cases where the args object might not have these attributes, ensuring backward compatibility.


618-636: Correct implementation of reset time priority logic.

The implementation properly prioritizes:

  1. User-specified custom reset hour (if provided)
  2. API-provided end time (backward compatibility)
  3. Default 5-hour intervals (fallback)

This matches the PR objectives perfectly.

The --reset-hour parameter was being stored but not actually used in reset time
calculations. The monitor would always use session end times from the API or
default 5-hour intervals, ignoring the user's custom reset hour setting.

This fix:
- Adds get_next_reset_time() method to TimezoneHandler class
- Prioritizes user's custom reset hour over API end times
- Maintains backward compatibility with existing behavior
- Handles timezone conversions correctly
- Includes comprehensive test coverage

Fixes Maciek-roboblog#95
@miraclebakelaser miraclebakelaser force-pushed the fix/reset-hour-timezone-calculation branch from 2edda2f to ce84971 Compare July 17, 2025 02:53
@miraclebakelaser
Copy link
Author

@Maciek-roboblog lmk your thoughts. If you're cool with the PR I have another enhancement lined up that'll clear the reset hour from the params file if we're past the reset hour.

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.

Bug: --reset-hour parameter not being used in reset time calculations

1 participant