• FunkyStuff [he/him]@hexbear.net
      link
      fedilink
      English
      arrow-up
      31
      ·
      23 days ago

      None of the hard things like leap seconds and different time standards due to relativity that are the reason for this comic justify a 1 hour time difference. The person coding the fancy stylized display just made a big mistake handling the time here, maybe they just forgot to account for timezones and used the computer’s local time directly, compared to a hardcoded shutdown time with no timezones.

      • the rizzler@lemmygrad.ml
        link
        fedilink
        arrow-up
        6
        ·
        edit-2
        23 days ago

        things get murky where leap seconds are involved (murky as in there are a thousand different ways to handle them in practice)

  • regul [any]@hexbear.net
    link
    fedilink
    English
    arrow-up
    30
    ·
    23 days ago

    Off-by-one errors. We’ve all been there.

    It’s either that or failing to account for timezones.

      • AernaLingus [any]@hexbear.net
        link
        fedilink
        English
        arrow-up
        23
        ·
        edit-2
        23 days ago

        Yup, this is it. Here’s the data declared for the top bar:

        var WHAnnouncementBarData = {
            "enabled": "1",
            "text": "Democrat Shutdown is Imminent",
            "link": "https://whitehouse.gov/government-shutdown-clock/",
            "end": "2025-10-01T04:00:00+00:00",
            "endText": "Democrats Have Shut Down the Government",
            "countup": "1"
        }
        

        The code that actually handles the timer is obfuscated, so I won’t bother posting it, but you can see that it’s correctly hardcoded to 4:00 AM UTC, which is equivalent to midnight EDT.

        The seven-segment display uses entirely different unobfuscated code (at its own peril!):

        expand to see code
        const segmentMap = {
        	0: ['a', 'b', 'c', 'd', 'e', 'f'],
        	1: ['b', 'c'],
        	2: ['a', 'b', 'd', 'e', 'g'],
        	3: ['a', 'b', 'c', 'd', 'g'],
        	4: ['b', 'c', 'f', 'g'],
        	5: ['a', 'c', 'd', 'f', 'g'],
        	6: ['a', 'c', 'd', 'e', 'f', 'g'],
        	7: ['a', 'b', 'c'],
        	8: ['a', 'b', 'c', 'd', 'e', 'f', 'g'],
        	9: ['a', 'b', 'c', 'd', 'f', 'g']
        };
        const endDate = new Date('October 1, 2025 00:00:00').getTime();
        let lastSecond = -1;
        function updateClock() {
        	// console.log('updateClock called');
        	let now = Date.now();
        	let distance = endDate - now;
        	if (0 > distance) {
        		setAllDigits(0);
        		return;
        	}
        	setAllDigits(Math.floor(distance / 1000));
        	setTimeout(updateClock, 100);
        }
        function setDigit(index, value) {
        	if (value > 9 || value < 0 ) value = 0;
        	let digit = document.getElementById('d' + index);
        	if (!digit) {
        		// console.error('Digit ' + index + ' not found');
        		return;
        	}
        	digit.querySelectorAll('.segment').forEach(s => s.classList.remove('lit'));
        	(segmentMap[value] || []).forEach(cls => {
        		let seg = digit.querySelector('.' + cls);
        		if (seg) seg.classList.add('lit');
        	});
        }
        function setAllDigits(value) {
        	// console.log('setAllDigits ' + value);
        	// value is total seconds remaining
        	let hours   = Math.floor(value / 3600);
        	let minutes = Math.floor((value % 3600) / 60);
        	let seconds = value % 60;
        
        	let d1 = Math.floor(hours / 10) % 10; // hours tens
        	let d2 = hours % 10;                   // hours ones
        	let d3 = Math.floor(minutes / 10);     // minutes tens
        	let d4 = minutes % 10;                 // minutes ones
        	let d5 = Math.floor(seconds / 10);     // seconds tens
        	let d6 = seconds % 10;                 // seconds ones
        
        	setDigit(1, d1);
        	setDigit(2, d2);
        	setDigit(3, d3);
        	setDigit(4, d4);
        	setDigit(5, d5);
        	setDigit(6, d6);
        }
        updateClock();
        document.addEventListener('click', function () { document.querySelector('#countdown-audio audio').play(); });
        

        The smoking gun is const endDate = new Date('October 1, 2025 00:00:00').getTime();. The Date object methods work on local time so it shows a longer time if you’re west of EDT, and (as of writing) if you’re anywhere between Africa and New Zealand (UTC+00:00 or greater) the clock’s already hit zero. Oopsy-daisy! bleh

        Pretty sure you can fix this by just swapping out the argument to the constructor with the result of a call to Date.UTC, like so:

        const endDate = new Date(Date.UTC(2025, 10, 1, 4)).getTime();
        
          • FunkyStuff [he/him]@hexbear.net
            link
            fedilink
            English
            arrow-up
            5
            ·
            23 days ago

            Admittedly time is always hard, no matter the language.

            But a language that doesn’t yell at you when comparing different time stamps that may not semantically refer to times in different time zones is a bad language. Python’s datetime might be a bit better if you have pylance enabled in your IDE to yell at you, I’m not sure if it would catch this error. Rust’s std::time has the decency to not support hardcoding its Instant type, so you have to use external crates that probably force you to specify time zone.

            • footfaults@lemmygrad.ml
              link
              fedilink
              English
              arrow-up
              2
              ·
              edit-2
              22 days ago

              Python’s datetime stuff is quite bad. They really fumbled it and I have to deal with naive vs timezone aware datetime objects. Very annoying. Django at least has warnings when you accidentally use naive objects.

    • FunkyStuff [he/him]@hexbear.net
      link
      fedilink
      English
      arrow-up
      12
      ·
      23 days ago

      Fencepost problem but for hours? Unless bro did T1 - T2 + 1 hour, for some reason, I think it has to be the latter. But it’s definitely vibe coded, I’ll tell you that.

  • BountifulEggnog [she/her]@hexbear.net
    link
    fedilink
    English
    arrow-up
    24
    ·
    23 days ago

    I don’t know js but it feels like the lazy way to do this would just be have both timers pull their time from the same place. Like one timer and two displays for it.