Skip to main content
Glama
pshempel

MCP Time Server Node

by pshempel
time-testing-implementation-guide.md4.81 kB
# Time Testing Implementation Guide ## The Problem We Just Discovered Our `daysUntil` tests were passing when run during the day but failing at night because: ```javascript // At 9:43 PM Eastern on July 28: new Date() // July 28, 9:43 PM Eastern new Date().toISOString() // July 29, 1:43 AM UTC .toISOString().split('T')[0] // "2025-07-29" (wrong day!) ``` ## Immediate Actions ### 1. Fix Existing Tests (✅ Done) Replace `toISOString().split('T')[0]` with `format(date, 'yyyy-MM-dd')` ### 2. Add Boundary Tests ```javascript // Add to each date-related test file describe('timezone boundary behavior', () => { it('handles late evening correctly', () => { jest.setSystemTime(new Date('2025-01-01T23:00:00-05:00')); // Run the test }); }); ``` ### 3. Create Time Test Checklist Before committing any date-related code: - [ ] Test at midnight - [ ] Test at 11:59 PM - [ ] Test when UTC date ≠ local date - [ ] Test with DST transitions - [ ] Test with different timezones ## Long-term Strategy ### Phase 1: Local Testing (Now) 1. Add `timezone-boundaries.test.ts` for edge cases 2. Use `jest.setSystemTime()` to simulate problematic times 3. Create test utilities for common scenarios ### Phase 2: CI Enhancement (Next Sprint) ```yaml # .github/workflows/time-edge-tests.yml name: Time Edge Case Tests on: schedule: - cron: '0 */6 * * *' # Every 6 hours pull_request: paths: - 'src/tools/*Time*.ts' - 'src/tools/*days*.ts' - 'src/tools/*business*.ts' ``` ### Phase 3: Continuous Monitoring - Add telemetry for timezone-related errors - Log when calculations cross date boundaries - Alert on timezone calculation discrepancies ## Practical Testing Patterns ### Pattern 1: The Time Bracket Test ```javascript // Test same operation at multiple times [0, 6, 12, 18, 23].forEach(hour => { it(`works correctly at ${hour}:00`, () => { const testTime = new Date(); testTime.setHours(hour, 0, 0, 0); jest.setSystemTime(testTime); // Your test here }); }); ``` ### Pattern 2: The Timezone Sandwich ```javascript // Test with early and late timezone it('handles timezone extremes', () => { // Baker Island (UTC-12) process.env.TZ = 'Pacific/Baker'; const bakerResult = daysUntil({ target_date: '2025-12-25' }); // Line Islands (UTC+14) process.env.TZ = 'Pacific/Kiritimati'; const lineResult = daysUntil({ target_date: '2025-12-25' }); // Should differ by at most 1 day expect(Math.abs(bakerResult - lineResult)).toBeLessThanOrEqual(1); }); ``` ### Pattern 3: The DST Trap Detector ```javascript // Catch DST-related bugs const DST_DATES = { US_SPRING: '2025-03-09T02:00:00', US_FALL: '2025-11-02T02:00:00', EU_SPRING: '2025-03-30T02:00:00', EU_FALL: '2025-10-26T02:00:00', }; Object.entries(DST_DATES).forEach(([name, date]) => { it(`handles ${name} DST transition`, () => { jest.setSystemTime(new Date(date)); // Your test }); }); ``` ## What We Can't Test (But Should Document) 1. **Real Timezone Changes**: We can't actually change the system timezone in tests 2. **Leap Seconds**: JavaScript doesn't handle them 3. **Future DST Rule Changes**: Governments change DST rules 4. **Every Possible Moment**: We can only test samples ## Recommended Tools ### For Now - `jest.useFakeTimers()` - Good enough for most cases - `date-fns/format` - Consistent date formatting - Manual edge case tests - Like we just added ### For Future - `@sinonjs/fake-timers` - More advanced time control - `fast-check` - Property-based testing for dates - Docker containers with different TZ settings ## The Golden Rules 1. **Never trust** `toISOString()` for date-only operations 2. **Always test** at 11 PM in your local timezone 3. **Document** timezone assumptions in tests 4. **Use `format()`** for consistent date strings 5. **Test both** UTC and local timezone scenarios ## Quick Win: Add This to Every Date Test ```javascript // Add to setupTests.js or each test file beforeEach(() => { // Log warning if running at a problematic time const now = new Date(); const localDate = format(now, 'yyyy-MM-dd'); const utcDate = now.toISOString().split('T')[0]; if (localDate !== utcDate) { console.warn(`⚠️ Testing at timezone boundary: Local=${localDate}, UTC=${utcDate}`); } }); ``` ## Conclusion Time bugs are insidious because they: - Only appear at certain times - Work fine in most timezones - Pass in CI but fail locally (or vice versa) - Are hard to reproduce The best defense is: 1. Defensive coding (use `format()`) 2. Comprehensive testing (multiple times/zones) 3. Good monitoring (log timezone issues) 4. Clear documentation (state assumptions) Remember: If a test involves dates, it needs timezone edge case testing!

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pshempel/mcp-time-server-node'

If you have feedback or need assistance with the MCP directory API, please join our Discord server