Skip to content

Fix timezone and timechange#1571

Merged
prxt6529 merged 4 commits intomainfrom
daylight-change-manifold-claim
Oct 27, 2025
Merged

Fix timezone and timechange#1571
prxt6529 merged 4 commits intomainfrom
daylight-change-manifold-claim

Conversation

@prxt6529
Copy link
Copy Markdown
Collaborator

@prxt6529 prxt6529 commented Oct 27, 2025

Summary by CodeRabbit

  • Updates
    • Meme calendar timezone changed from US Eastern to Europe/Nicosia (EET/EEST).
    • Mint start and end times moved to European schedule (17:40 start, 17:00 end).
    • Phase timing and mint phase determination updated for correct behavior under the new timezone, ensuring accurate phase boundaries and mint availability.

Signed-off-by: prxt6529 <prxt@6529.io>
@prxt6529
Copy link
Copy Markdown
Collaborator Author

@claude review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 27, 2025

Warning

Rate limit exceeded

@prxt6529 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 7 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between adf9065 and 4b23ab3.

📒 Files selected for processing (2)
  • abis.ts (2 hunks)
  • hooks/useManifoldClaim.ts (7 hunks)

Walkthrough

Time zone handling moved from US Eastern to Europe/Nicosia (EET/EEST) and mint times shifted from 10:40/10:00 ET to 17:40/17:00 local Europe times. A new exported helper wallTimeToUtcInstantInZone computes UTC instants for wall times; phase selection now uses end-time-only logic.

Changes

Cohort / File(s) Summary
Timezone helper refactor
components/meme-calendar/meme-calendar.helpers.tsx
Added export function wallTimeToUtcInstantInZone(utcDay: Date, hour: number, minute: number): Date; replaced US Eastern DST logic with Europe/Nicosia (EET/EEST) handling and DST offsets; updated mint start/end wall times from 10:40/10:00 ET to 17:40/17:00 Europe; rewired mintStartInstantUtcForMintDay and mintEndInstantUtcForMintDay to use the new helper.
Phase calculation update
hooks/useManifoldClaim.ts
Removed Luxon DateTime usage; added buildTime using wallTimeToUtcInstantInZone (with next-day handling); phase time computations changed for Phase 0/1/2 and Public; getMemePhase signature narrowed to (phase, end) and now selects phase by comparing end-time (using Time.gte); call sites updated to pass endDate only.

Sequence Diagram(s)

sequenceDiagram
  participant Hook as useManifoldClaim
  participant Helper as meme-calendar.helpers
  participant Phase as getMemePhase

  Note over Hook,Helper: Phase time construction
  Hook->>Helper: buildTime(utcDay, hour, minute)
  Helper-->>Hook: UTC instant (wallTimeToUtcInstantInZone)

  Note over Hook,Phase: Phase selection
  Hook->>Phase: getMemePhase(MEME_PHASES, endDate)
  Phase-->>Hook: selected phase
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Verify Europe/Nicosia DST offsets and boundary/date transitions in wallTimeToUtcInstantInZone.
  • Confirm mint start/end instants (17:40/17:00 Europe) map to intended UTC instants across seasons.
  • Review getMemePhase signature change and all call sites for correctness and no regressions.
  • Check removal of Luxon usage for any subtle semantics changes (e.g., next-day handling, inclusive/exclusive comparisons).

Suggested reviewers

  • ragnep

Poem

🐰 I hopped from East to Cypriot skies,
Swapped clocks and rules and changed sunrise,
A helper maps wall time to UTC,
Phases follow where end times be,
Tiny paws, precise timewise.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Fix timezone and timechange" is directly related to the main changes in the changeset. The raw summary shows that the core modifications involve replacing hard-coded US Eastern DST logic with Europe/Nicosia timezone logic, shifting mint start/end times from Eastern to European schedule, and creating a new zone-aware time conversion function. The title clearly captures these primary changes: "timezone" refers to the shift from US Eastern to Europe/Nicosia, and "timechange" refers to the DST adjustments and time logic modifications. The title is concise, avoids noise, and is specific enough that a developer reviewing the commit history would understand the primary change is about timezone and daylight saving time fixes.

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown

claude Bot commented Oct 27, 2025

Claude finished @prxt6529's task —— View job


PR Review: Fix timezone and timechange

Review Tasks

  • Read and analyze components/meme-calendar/meme-calendar.helpers.tsx
  • Read and analyze hooks/useManifoldClaim.ts
  • Check timezone handling correctness
  • Look for potential bugs or edge cases
  • Provide comprehensive review feedback

Code Review Summary

This PR makes a significant timezone change from Eastern Time (America/New_York) to Europe/Nicosia (Europe/Nicosia), updating mint times from 10:40 EST/EDT to 17:40 EET/EEST. The changes look well-implemented with improved DST handling.

Strengths

1. Robust DST Handling in wallTimeToUtcInstantInZone (components/meme-calendar/meme-calendar.helpers.tsx:104-136)

  • Excellent approach: Tests both winter/summer candidates and validates using Intl.DateTimeFormat
  • Handles edge cases: Gracefully manages DST transitions and ambiguous times
  • Safer than manual DST calculations: Replaces brittle manual DST logic with browser-native timezone support

2. Consistent Implementation

  • All mint timing functions properly updated to use the new helper
  • useManifoldClaim.ts correctly adopts the new timezone helper
  • Dependency cleanup: Removes unused DateTime from luxon

3. Clean Refactoring

  • Eliminates complex manual DST calculations (getNthWeekdayOfMonthUtc, isEasternDaylightTime)
  • Simplifies phase time calculations in manifold claims
  • Code is more maintainable and less error-prone

⚠️ Potential Issues & Considerations

1. Breaking Change Impact ⚠️

This is a 7-8 hour timezone shift:

  • Old: 10:40 EST/EDT (UTC-5/-4) = 15:40/14:40 UTC
  • New: 17:40 EET/EEST (UTC+2/+3) = 15:40/14:40 UTC

Critical Questions:

  • Are users/systems expecting this timezone change?
  • Are there any hardcoded references to Eastern Time elsewhere in the codebase?
  • Have notification systems, external integrations been updated?

2. buildMemesPhases Logic Issue (hooks/useManifoldClaim.ts:78-79)

end: Time.fromString(
  wallTimeToUtcInstantInZone(mintDate.toDate(), 17, 0).toISOString()
),

The public phase end time (17:00) is before start time (19:20) on the same day. This suggests the end should be the next day at 17:00:

// Should probably be:
const nextDay = new Date(mintDate.toDate());
nextDay.setUTCDate(nextDay.getUTCDate() + 1);

end: Time.fromString(
  wallTimeToUtcInstantInZone(nextDay, 17, 0).toISOString()
),

3. Minor Code Quality

  • getMemePhase dependency (hooks/useManifoldClaim.ts:136): Good that contract was added to dependency array
  • Fallback behavior: wallTimeToUtcInstantInZone defaults to summer candidate - this seems reasonable but should be documented

🔍 Edge Cases to Test

  1. DST transition dates (March/October in Europe)
  2. Public phase spanning midnight - verify end time logic
  3. Systems that cached Eastern Time schedules
  4. Calendar integrations and external time references

Recommendation

Approve with one fix needed: The public phase end time logic should account for the next day. Otherwise, this is a well-implemented timezone migration with much improved DST handling.


Signed-off-by: prxt6529 <prxt@6529.io>
@prxt6529
Copy link
Copy Markdown
Collaborator Author

@claude review

@claude
Copy link
Copy Markdown

claude Bot commented Oct 27, 2025

Claude finished @prxt6529's task —— View job


PR Review: Fix timezone and timechange

Review Tasks

  • Read and analyze components/meme-calendar/meme-calendar.helpers.tsx
  • Read and analyze hooks/useManifoldClaim.ts
  • Check timezone handling correctness
  • Look for potential bugs or edge cases
  • Provide comprehensive review feedback

Code Review Summary

This PR makes a significant timezone change from Eastern Time (America/New_York) to Europe/Nicosia (Europe/Nicosia), updating mint times from 10:40 EST/EDT to 17:40 EET/EEST. The changes look well-implemented with improved DST handling.

Strengths

1. Robust DST Handling in wallTimeToUtcInstantInZone (components/meme-calendar/meme-calendar.helpers.tsx:104-136)

  • Excellent approach: Tests both winter/summer candidates and validates using Intl.DateTimeFormat
  • Handles edge cases: Gracefully manages DST transitions and ambiguous times
  • Safer than manual DST calculations: Replaces brittle manual DST logic with browser-native timezone support

2. Consistent Implementation

  • All mint timing functions properly updated to use the new helper
  • useManifoldClaim.ts correctly adopts the new timezone helper
  • Dependency cleanup: Removes unused DateTime from luxon

3. Clean Refactoring

  • Eliminates complex manual DST calculations (getNthWeekdayOfMonthUtc, isEasternDaylightTime)
  • Simplifies phase time calculations in manifold claims
  • Code is more maintainable and less error-prone

⚠️ Potential Issues & Considerations

1. Breaking Change Impact ⚠️

This is a 7-8 hour timezone shift:

  • Old: 10:40 EST/EDT (UTC-5/-4) = 15:40/14:40 UTC
  • New: 17:40 EET/EEST (UTC+2/+3) = 15:40/14:40 UTC

Critical Questions:

  • Are users/systems expecting this timezone change?
  • Are there any hardcoded references to Eastern Time elsewhere in the codebase?
  • Have notification systems, external integrations been updated?

2. buildMemesPhases Logic Issue (hooks/useManifoldClaim.ts:78-79)

end: buildTime(17, 0, true),

The public phase end time (17:00) is before start time (19:20) on the same day. This suggests the end should be the next day at 17:00:

// Should probably be:
const nextDay = new Date(mintDate.toDate());
nextDay.setUTCDate(nextDay.getUTCDate() + 1);

end: Time.fromString(
  wallTimeToUtcInstantInZone(nextDay, 17, 0).toISOString()
),

3. Minor Code Quality

  • getMemePhase dependency (hooks/useManifoldClaim.ts:136): Good that contract was added to dependency array
  • Fallback behavior: wallTimeToUtcInstantInZone defaults to summer candidate - this seems reasonable but should be documented

🔍 Edge Cases to Test

  1. DST transition dates (March/October in Europe)
  2. Public phase spanning midnight - verify end time logic
  3. Systems that cached Eastern Time schedules
  4. Calendar integrations and external time references

Recommendation

Approve with one fix needed: The public phase end time logic should account for the next day. Otherwise, this is a well-implemented timezone migration with much improved DST handling.


Copy link
Copy Markdown

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
hooks/useManifoldClaim.ts (1)

112-120: Boundary bug: start instant is not considered ACTIVE at t == start.

Use now >= start for activation.

-  } else if (now > start && now < end) {
+  } else if (now >= start && now < end) {
🧹 Nitpick comments (4)
hooks/useManifoldClaim.ts (3)

102-108: Type ABI precisely.

Avoid any; wagmi/viem exposes Abi. Improves safety.

-import { useReadContract } from "wagmi";
+import { useReadContract } from "wagmi";
+import type { Abi } from "viem";
@@
-export function useManifoldClaim(
+export function useManifoldClaim(
   contract: string,
   proxy: string,
-  abi: any,
+  abi: Abi,
   tokenId: number,
   onError?: () => void
 ) {

41-47: Extract phase instant conversion into a local helper to eliminate repetition.

The existing mintStartInstantUtcForMintDay / mintEndInstantUtcForMintDay helpers use fixed global times and cannot be reused here. However, the 8 repetitions of wallTimeToUtcInstantInZone(mintDate.toDate(), hour, minute) across this function should be consolidated via a simple local helper to improve readability and reduce timezone logic duplication.


84-84: Build meme phases dynamically based on claim's endDate to avoid time drift across day boundaries.

The drift risk is real: phases in the global MEME_PHASES are anchored to the date when the module loaded (via Time.now()). If the app stays open across UTC midnight or DST change, buildMemesPhases phases remain frozen to the old date while new claims arrive with endDates from the current date. In getMemePhase (line 122), the end parameter contains the claim's endDate but is only used for comparison against the stale MEME_PHASES.

Refactor: Call buildMemesPhases inside getMemePhase with a mintDate derived from the claim's end parameter to ensure phases align with the actual claim day.

components/meme-calendar/meme-calendar.helpers.tsx (1)

21-27: Project guideline note: comments in TS/TSX.

Coding guidelines state no comments in ts/tsx. The newly added constants include comments. If the guideline is enforced, consider moving notes to docs or JSDoc on exported types only.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c01bf38 and 770b2f8.

📒 Files selected for processing (2)
  • components/meme-calendar/meme-calendar.helpers.tsx (4 hunks)
  • hooks/useManifoldClaim.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Use TypeScript across the codebase

Files:

  • components/meme-calendar/meme-calendar.helpers.tsx
  • hooks/useManifoldClaim.ts
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Use React functional components with hooks for UI components

Files:

  • components/meme-calendar/meme-calendar.helpers.tsx
🧬 Code graph analysis (1)
hooks/useManifoldClaim.ts (2)
helpers/time.ts (1)
  • Time (4-445)
components/meme-calendar/meme-calendar.helpers.tsx (1)
  • wallTimeToUtcInstantInZone (104-136)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
components/meme-calendar/meme-calendar.helpers.tsx (2)

169-175: Mint start/end helpers correctly apply next‑day end.

This aligns with the intended schedule (start at 17:40; end next day 17:00). Good reuse for downstream callers.

Also applies to: 177-190


104-136: Verification confirms DST logic is correct; function handles edge cases properly.

The dual-candidate check via Intl.DateTimeFormat works as intended. On 2025-03-30 (spring forward), the summer candidate correctly resolves to 17:40 wall time with UTC offset -3. On 2025-10-26 (fall back), the winter candidate correctly resolves to 17:40 with UTC offset -2. The function logic is sound for both DST transitions.

Comment thread hooks/useManifoldClaim.ts Outdated
Comment thread hooks/useManifoldClaim.ts
Signed-off-by: prxt6529 <prxt@6529.io>
GelatoGenesis
GelatoGenesis previously approved these changes Oct 27, 2025
Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
hooks/useManifoldClaim.ts (1)

82-82: Do not cache MEME_PHASES at module load; compute from the claim’s day.

Anchoring to Time.now() breaks phase selection for claims not minted “today” (e.g., viewing yesterday’s or tomorrow’s claim). Build phases from the claim’s end (or start) instant instead.

-const MEME_PHASES = buildMemesPhases(Time.now());
+// Removed: build phases per-claim in getMemePhase to ensure correct day anchoring.
♻️ Duplicate comments (2)
hooks/useManifoldClaim.ts (2)

76-78: Use shared helper for Public end to avoid drift with calendar logic.

Prefer mintEndInstantUtcForMintDay for single source of truth and future DST changes. This mirrors the calendar helper usage.

-import { wallTimeToUtcInstantInZone } from "@/components/meme-calendar/meme-calendar.helpers";
+import { wallTimeToUtcInstantInZone, mintEndInstantUtcForMintDay } from "@/components/meme-calendar/meme-calendar.helpers";
@@
     {
       id: "public",
       name: "Public Phase",
       type: ManifoldPhase.PUBLIC,
       start: buildTime(19, 20),
-      end: buildTime(17, 0, true),
+      end: Time.fromString(
+        mintEndInstantUtcForMintDay(mintDate.toDate()).toISOString()
+      ),
     },

120-134: Compute phases from end’s day and restrict to ALLOWLIST for deterministic selection.

Build phases using the claim’s end instant so dates line up, and restrict find() to ALLOWLIST to avoid matching the Public phase.

-  const getMemePhase = useCallback(
-    (phase: ManifoldPhase, end: number) => {
+  const getMemePhase = useCallback(
+    (phase: ManifoldPhase, end: number) => {
       if (!areEqualAddresses(contract, MEMES_CONTRACT)) {
         return undefined;
       }
 
-      if (phase === ManifoldPhase.PUBLIC) {
-        return MEME_PHASES.find((mp) => mp.id === "public");
-      }
-
-      const endTime = Time.seconds(end);
-      return MEME_PHASES.find((mp) => mp.end.gte(endTime));
+      const endTime = Time.seconds(end);
+      const phases = buildMemesPhases(endTime);
+      if (phase === ManifoldPhase.PUBLIC) {
+        return phases.find((mp) => mp.id === "public");
+      }
+      return phases.find(
+        (mp) => mp.type === ManifoldPhase.ALLOWLIST && mp.end.gte(endTime)
+      );
     },
-    [contract]
+    [contract]
   );
🧹 Nitpick comments (3)
hooks/useManifoldClaim.ts (3)

55-57: Allowlist phase times look correct.

17:40–18:20, 18:30–18:50, 19:00–19:20 (Europe/Nicosia) align with the schedule.

Consider extracting these wall times into a typed constant to avoid duplication across modules.

Also applies to: 62-64, 69-71


149-181: Include getMemePhase in effect deps to avoid stale closure.

Without it, phase labeling may not update when contract changes or when getMemePhase logic changes.

-  }, [readContract.data, getStatus]);
+  }, [readContract.data, getStatus, getMemePhase]);

110-118: Boundary: treat start as inclusive.

Use now >= start so a claim flips to ACTIVE exactly at the start timestamp.

-    } else if (now > start && now < end) {
+    } else if (now >= start && now < end) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 770b2f8 and adf9065.

📒 Files selected for processing (1)
  • hooks/useManifoldClaim.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Use TypeScript across the codebase

Files:

  • hooks/useManifoldClaim.ts
🧬 Code graph analysis (1)
hooks/useManifoldClaim.ts (2)
helpers/time.ts (1)
  • Time (4-445)
components/meme-calendar/meme-calendar.helpers.tsx (1)
  • wallTimeToUtcInstantInZone (104-136)

Comment thread hooks/useManifoldClaim.ts
Signed-off-by: prxt6529 <prxt@6529.io>
@sonarqubecloud
Copy link
Copy Markdown

@prxt6529 prxt6529 merged commit 7288494 into main Oct 27, 2025
8 checks passed
@prxt6529 prxt6529 deleted the daylight-change-manifold-claim branch October 27, 2025 17:10
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