Skip to content

Instantly share code, notes, and snippets.

@simonw
Created November 3, 2024 16:29
Show Gist options
  • Save simonw/d680d5f27b50de4efc26ed2a673292fd to your computer and use it in GitHub Desktop.
Save simonw/d680d5f27b50de4efc26ed2a673292fd to your computer and use it in GitHub Desktop.

California Clock Change Website with Body Clock Info

human (Nov 3, 2024, 07:27 AM)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>California Clock Change - PST/PDT Only</title>
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f0f4f8;
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .container {
            background: white;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            max-width: 600px;
            width: 90%;
            text-align: center;
        }
        h1 {
            color: #1a365d;
            font-size: 1.8rem;
            margin-bottom: 0.5rem;
        }
        .subtitle {
            color: #4a5568;
            margin-bottom: 1.5rem;
        }
        .info-box {
            background: #e6fffa;
            border: 2px solid #38b2ac;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
        }
        .highlight {
            color: #2b6cb0;
            font-weight: bold;
        }
        .tonight {
            display: inline-block;
            background: #f6e05e;
            color: #744210;
            padding: 0.2em 0.5em;
            border-radius: 4px;
            margin-left: 0.5em;
            font-weight: bold;
        }
        .wrong-timezone {
            background: #fed7d7;
            border: 2px solid #f56565;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
            color: #c53030;
        }
        @media (max-width: 480px) {
            .container {
                padding: 1.5rem;
            }
            h1 {
                font-size: 1.5rem;
            }
            .info-box {
                font-size: 1.1rem;
                padding: 1rem;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>California Clock Change</h1>
        <div class="subtitle">For Pacific Time (PST/PDT) only</div>
        <div id="content">Loading...</div>
    </div>

    <script>
        function isCaliforniaTimezone() {
            const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
            return timezone === "America/Los_Angeles" || 
                   timezone === "America/Pacific" || 
                   timezone === "US/Pacific" ||
                   timezone === "PST8PDT";
        }

        function getNextCaliforniaChange() {
            const now = new Date();
            const year = now.getFullYear();
            
            // Second Sunday in March
            const springForward = new Date(year, 2, 1 + (14 - new Date(year, 2, 1).getDay()));
            // First Sunday in November
            const fallBack = new Date(year, 10, 1 + (7 - new Date(year, 10, 1).getDay()));
            
            if (now > fallBack) {
                return {
                    date: new Date(year + 1, 2, 1 + (14 - new Date(year + 1, 2, 1).getDay())),
                    isSpringForward: true
                };
            } else if (now > springForward) {
                return {
                    date: fallBack,
                    isSpringForward: false
                };
            } else {
                return {
                    date: springForward,
                    isSpringForward: true
                };
            }
        }

        function formatDate(date) {
            const months = ['January', 'February', 'March', 'April', 'May', 'June', 
                           'July', 'August', 'September', 'October', 'November', 'December'];
            return `${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;
        }

        function updateInfo() {
            const content = document.getElementById('content');
            
            if (!isCaliforniaTimezone()) {
                content.className = 'wrong-timezone';
                content.innerHTML = 'You appear to be outside of California/Pacific Time.<br>This tool only works for Pacific Time (PST/PDT).';
                return;
            }

            const change = getNextCaliforniaChange();
            const saturday = new Date(change.date);
            saturday.setDate(change.date.getDate() - 1);

            const now = new Date();
            const isTonight = now.getDate() === saturday.getDate() && 
                            now.getMonth() === saturday.getMonth() && 
                            now.getFullYear() === saturday.getFullYear();

            const sleepEffect = change.isSpringForward ? 'lose an hour of sleep' : 'get an extra hour of sleep';
            const clockEffect = change.isSpringForward ? 
                'clocks spring forward from 2:00 AM to 3:00 AM' : 
                'clocks fall back from 2:00 AM to 1:00 AM';

            const tonightBadge = isTonight ? '<span class="tonight">That\'s tonight!</span>' : '';

            content.className = 'info-box';
            content.innerHTML = `
                When you go to bed on <span class="highlight">Saturday, ${formatDate(saturday)}</span>${tonightBadge}, 
                you will ${sleepEffect}!<br><br>
                The ${clockEffect} on 
                <span class="highlight">Sunday, ${formatDate(change.date)}</span>.
            `;
        }

        updateInfo();
    </script>
</body>
</html>

Modify this artifact: if it is the day the clocks changed it should show some reassuring text telling you that your body thinks it is a certain time (use the browser clock to figure out what time that is) but it is actually some other time (show that too)

assistant (Nov 3, 2024, 07:27 AM)

Since this is a complete HTML application that needs modification, it qualifies as an artifact. I'll update the existing code to include the new feature while maintaining all current functionality.

California Clock Change Website with Body Clock Information

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>California Clock Change - PST/PDT Only</title>
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f0f4f8;
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .container {
            background: white;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            max-width: 600px;
            width: 90%;
            text-align: center;
        }
        h1 {
            color: #1a365d;
            font-size: 1.8rem;
            margin-bottom: 0.5rem;
        }
        .subtitle {
            color: #4a5568;
            margin-bottom: 1.5rem;
        }
        .info-box {
            background: #e6fffa;
            border: 2px solid #38b2ac;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
        }
        .highlight {
            color: #2b6cb0;
            font-weight: bold;
        }
        .tonight {
            display: inline-block;
            background: #f6e05e;
            color: #744210;
            padding: 0.2em 0.5em;
            border-radius: 4px;
            margin-left: 0.5em;
            font-weight: bold;
        }
        .wrong-timezone {
            background: #fed7d7;
            border: 2px solid #f56565;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
            color: #c53030;
        }
        .body-clock {
            background: #ebf8ff;
            border: 2px solid #4299e1;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
        }
        @media (max-width: 480px) {
            .container {
                padding: 1.5rem;
            }
            h1 {
                font-size: 1.5rem;
            }
            .info-box, .body-clock {
                font-size: 1.1rem;
                padding: 1rem;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>California Clock Change</h1>
        <div class="subtitle">For Pacific Time (PST/PDT) only</div>
        <div id="content">Loading...</div>
        <div id="body-clock"></div>
    </div>

    <script>
        function isCaliforniaTimezone() {
            const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
            return timezone === "America/Los_Angeles" || 
                   timezone === "America/Pacific" || 
                   timezone === "US/Pacific" ||
                   timezone === "PST8PDT";
        }

        function getNextCaliforniaChange() {
            const now = new Date();
            const year = now.getFullYear();
            
            // Second Sunday in March
            const springForward = new Date(year, 2, 1 + (14 - new Date(year, 2, 1).getDay()));
            // First Sunday in November
            const fallBack = new Date(year, 10, 1 + (7 - new Date(year, 10, 1).getDay()));
            
            if (now > fallBack) {
                return {
                    date: new Date(year + 1, 2, 1 + (14 - new Date(year + 1, 2, 1).getDay())),
                    isSpringForward: true
                };
            } else if (now > springForward) {
                return {
                    date: fallBack,
                    isSpringForward: false
                };
            } else {
                return {
                    date: springForward,
                    isSpringForward: true
                };
            }
        }

        function formatDate(date) {
            const months = ['January', 'February', 'March', 'April', 'May', 'June', 
                           'July', 'August', 'September', 'October', 'November', 'December'];
            return `${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;
        }

        function formatTime(date) {
            return date.toLocaleTimeString('en-US', { 
                hour: 'numeric', 
                minute: '2-digit', 
                hour12: true 
            });
        }

        function isChangeDay(change) {
            const now = new Date();
            return now.getDate() === change.date.getDate() && 
                   now.getMonth() === change.date.getMonth() && 
                   now.getFullYear() === change.date.getFullYear();
        }

        function updateBodyClockInfo() {
            const bodyClockDiv = document.getElementById('body-clock');
            const change = getNextCaliforniaChange();
            
            if (isChangeDay(change)) {
                const now = new Date();
                const bodyClock = new Date(now);
                
                if (change.isSpringForward) {
                    bodyClock.setHours(now.getHours() - 1);
                } else {
                    bodyClock.setHours(now.getHours() + 1);
                }
                
                bodyClockDiv.className = 'body-clock';
                bodyClockDiv.innerHTML = `
                    <p>💫 Don't worry if you're feeling a bit off today!</p>
                    <p>While the clock says it's <span class="highlight">${formatTime(now)}</span>, 
                    your body thinks it's <span class="highlight">${formatTime(bodyClock)}</span>.</p>
                    <p>This is completely normal - it may take a few days for your internal clock to adjust.</p>
                `;
            } else {
                bodyClockDiv.innerHTML = '';
            }
        }

        function updateInfo() {
            const content = document.getElementById('content');
            
            if (!isCaliforniaTimezone()) {
                content.className = 'wrong-timezone';
                content.innerHTML = 'You appear to be outside of California/Pacific Time.<br>This tool only works for Pacific Time (PST/PDT).';
                return;
            }

            const change = getNextCaliforniaChange();
            const saturday = new Date(change.date);
            saturday.setDate(change.date.getDate() - 1);

            const now = new Date();
            const isTonight = now.getDate() === saturday.getDate() && 
                            now.getMonth() === saturday.getMonth() && 
                            now.getFullYear() === saturday.getFullYear();

            const sleepEffect = change.isSpringForward ? 'lose an hour of sleep' : 'get an extra hour of sleep';
            const clockEffect = change.isSpringForward ? 
                'clocks spring forward from 2:00 AM to 3:00 AM' : 
                'clocks fall back from 2:00 AM to 1:00 AM';

            const tonightBadge = isTonight ? '<span class="tonight">That\'s tonight!</span>' : '';

            content.className = 'info-box';
            content.innerHTML = `
                When you go to bed on <span class="highlight">Saturday, ${formatDate(saturday)}</span>${tonightBadge}, 
                you will ${sleepEffect}!<br><br>
                The ${clockEffect} on 
                <span class="highlight">Sunday, ${formatDate(change.date)}</span>.
            `;
        }

        updateInfo();
        updateBodyClockInfo();
        
        // Update the body clock info every minute
        setInterval(updateBodyClockInfo, 60000);
    </script>
</body>
</html>

I've made the following changes to the website:

  1. Added a new "body-clock" section with its own styling
  2. Created a new updateBodyClockInfo() function that:
    • Checks if today is the day of the time change
    • If it is, calculates what time your body thinks it is (1 hour different from the actual time)
    • Displays a reassuring message with both the actual time and your body's perceived time
  3. Added an interval to update the body clock time every minute
  4. Included some friendly emoji and reassuring text about it being normal to feel off
  5. Used the existing highlight styling to make the times stand out

The message will only appear on the actual day of the time change (Sunday). On spring forward days, it shows that your body thinks it's one hour earlier than it actually is, and on fall back days, it shows that your body thinks it's one hour later than it actually is.

Would you like me to modify the styling or wording of the body clock message?

human (Nov 3, 2024, 07:30 AM)

Doesn't seem to work. Let's change things up to show the most recent clock change in the past as well as the next one that is coming up. The logic to show the reassuring message should act based on the most recent change, not the next future change. Also update the reassuring copy to mention your dog, who has a reliable internal clock and hence will think that the time is different from what it actually is because she is not automatically updated by DST. Use the 🐺 emoji

assistant (Nov 3, 2024, 07:30 AM)

This needs significant logic changes to track both past and future changes, plus adding the dog-related messaging. Since it's a complete HTML application, it's appropriate to continue using the artifact.

California Clock Change Website with Pet Clock Information

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>California Clock Change - PST/PDT Only</title>
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f0f4f8;
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .container {
            background: white;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            max-width: 600px;
            width: 90%;
            text-align: center;
        }
        h1 {
            color: #1a365d;
            font-size: 1.8rem;
            margin-bottom: 0.5rem;
        }
        .subtitle {
            color: #4a5568;
            margin-bottom: 1.5rem;
        }
        .info-box {
            background: #e6fffa;
            border: 2px solid #38b2ac;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
        }
        .highlight {
            color: #2b6cb0;
            font-weight: bold;
        }
        .tonight {
            display: inline-block;
            background: #f6e05e;
            color: #744210;
            padding: 0.2em 0.5em;
            border-radius: 4px;
            margin-left: 0.5em;
            font-weight: bold;
        }
        .wrong-timezone {
            background: #fed7d7;
            border: 2px solid #f56565;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
            color: #c53030;
        }
        .body-clock {
            background: #ebf8ff;
            border: 2px solid #4299e1;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
        }
        .past-change {
            background: #faf5ff;
            border: 2px solid #805ad5;
            border-radius: 8px;
            padding: 1.5rem;
            margin: 1rem 0;
            font-size: 1.2rem;
            line-height: 1.6;
        }
        @media (max-width: 480px) {
            .container {
                padding: 1.5rem;
            }
            h1 {
                font-size: 1.5rem;
            }
            .info-box, .body-clock, .past-change {
                font-size: 1.1rem;
                padding: 1rem;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>California Clock Change</h1>
        <div class="subtitle">For Pacific Time (PST/PDT) only</div>
        <div id="past-change"></div>
        <div id="future-change"></div>
        <div id="body-clock"></div>
    </div>

    <script>
        function isCaliforniaTimezone() {
            const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
            return timezone === "America/Los_Angeles" || 
                   timezone === "America/Pacific" || 
                   timezone === "US/Pacific" ||
                   timezone === "PST8PDT";
        }

        function getClockChanges() {
            const now = new Date();
            const year = now.getFullYear();
            
            // Get changes for current and adjacent years to handle year boundaries
            function getYearChanges(y) {
                // Second Sunday in March
                const springForward = new Date(y, 2, 1 + (14 - new Date(y, 2, 1).getDay()));
                // First Sunday in November
                const fallBack = new Date(y, 10, 1 + (7 - new Date(y, 10, 1).getDay()));
                return [
                    { date: springForward, isSpringForward: true },
                    { date: fallBack, isSpringForward: false }
                ];
            }

            const changes = [
                ...getYearChanges(year - 1),
                ...getYearChanges(year),
                ...getYearChanges(year + 1)
            ].sort((a, b) => a.date - b.date);

            // Find the most recent past change and next future change
            const pastChange = changes.filter(change => change.date < now).pop();
            const futureChange = changes.find(change => change.date > now);

            return { pastChange, futureChange };
        }

        function formatDate(date) {
            const months = ['January', 'February', 'March', 'April', 'May', 'June', 
                           'July', 'August', 'September', 'October', 'November', 'December'];
            return `${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;
        }

        function formatTime(date) {
            return date.toLocaleTimeString('en-US', { 
                hour: 'numeric', 
                minute: '2-digit', 
                hour12: true 
            });
        }

        function getDaysSince(date) {
            const now = new Date();
            const diffTime = Math.abs(now - date);
            return Math.floor(diffTime / (1000 * 60 * 60 * 24));
        }

        function updateBodyClockInfo(pastChange) {
            const bodyClockDiv = document.getElementById('body-clock');
            const daysSince = getDaysSince(pastChange.date);
            
            if (daysSince <= 7) {  // Show message for a week after the change
                const now = new Date();
                const dogClock = new Date(now);
                
                if (pastChange.isSpringForward) {
                    dogClock.setHours(now.getHours() - 1);
                } else {
                    dogClock.setHours(now.getHours() + 1);
                }
                
                bodyClockDiv.className = 'body-clock';
                bodyClockDiv.innerHTML = `
                    <p>🐺 Is your dog confused about meal or walk times?</p>
                    <p>While your clock says it's <span class="highlight">${formatTime(now)}</span>, 
                    your dog's internal clock thinks it's <span class="highlight">${formatTime(dogClock)}</span>!</p>
                    <p>Dogs have very reliable internal clocks and don't automatically adjust to Daylight Saving Time. 
                    Don't worry - your pup's schedule should adjust naturally over the next few days.</p>
                `;
            } else {
                bodyClockDiv.innerHTML = '';
            }
        }

        function updateInfo() {
            if (!isCaliforniaTimezone()) {
                document.getElementById('future-change').className = 'wrong-timezone';
                document.getElementById('future-change').innerHTML = 'You appear to be outside of California/Pacific Time.<br>This tool only works for Pacific Time (PST/PDT).';
                return;
            }

            const { pastChange, futureChange } = getClockChanges();
            
            // Show past change
            const pastChangeDiv = document.getElementById('past-change');
            const pastSaturday = new Date(pastChange.date);
            pastSaturday.setDate(pastChange.date.getDate() - 1);
            
            pastChangeDiv.className = 'past-change';
            pastChangeDiv.innerHTML = `
                <div>Most recent change:</div>
                On <span class="highlight">Sunday, ${formatDate(pastChange.date)}</span>, 
                clocks ${pastChange.isSpringForward ? 'sprang forward' : 'fell back'} 
                (${pastChange.isSpringForward ? 'lost' : 'gained'} one hour).
            `;

            // Show future change
            const futureChangeDiv = document.getElementById('future-change');
            const futureSaturday = new Date(futureChange.date);
            futureSaturday.setDate(futureChange.date.getDate() - 1);

            const now = new Date();
            const isTonight = now.getDate() === futureSaturday.getDate() && 
                            now.getMonth() === futureSaturday.getMonth() && 
                            now.getFullYear() === futureSaturday.getFullYear();

            const sleepEffect = futureChange.isSpringForward ? 'lose an hour of sleep' : 'get an extra hour of sleep';
            const clockEffect = futureChange.isSpringForward ? 
                'clocks spring forward from 2:00 AM to 3:00 AM' : 
                'clocks fall back from 2:00 AM to 1:00 AM';

            const tonightBadge = isTonight ? '<span class="tonight">That\'s tonight!</span>' : '';

            futureChangeDiv.className = 'info-box';
            futureChangeDiv.innerHTML = `
                <div>Next change:</div>
                When you go to bed on <span class="highlight">Saturday, ${formatDate(futureSaturday)}</span>${tonightBadge}, 
                you will ${sleepEffect}!<br><br>
                The ${clockEffect} on 
                <span class="highlight">Sunday, ${formatDate(futureChange.date)}</span>.
            `;

            // Update body clock info based on past change
            updateBodyClockInfo(pastChange);
        }

        updateInfo();
        
        // Update the times every minute
        setInterval(updateInfo, 60000);
    </script>
</body>
</html>

I've made several significant changes:

  1. Completely rewrote the clock change detection logic to track both past and future changes
  2. Added a new "past-change" section showing the most recent time change
  3. Updated the dog-related messaging to:
    • Show for a week after any time change
    • Use the 🐺 emoji as requested
    • Focus on dogs' internal clocks and meal/walk times
    • Provide reassurance about natural adjustment
  4. Added styling for the past change section
  5. Made the entire system more robust around year boundaries
  6. Changed the body clock logic to work based on the most recent change rather than the upcoming one

The page now shows:

  1. The most recent time change that occurred
  2. The next upcoming time change
  3. A message about dog schedules (if within a week of a change)

Would you like me to adjust any of the timing windows or messaging?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment