Source: utils/countdown.js

/**
 * Unified logic for client and server to determine the time remaining until
 * the specified targetDay and targetTime. Time is in 24 hour format of hh:mm,
 * and days is capitalized english day (i.e. "Monday")
 * @param targetDay
 * @param targetTime
 * @returns {{total: number, hours: number, seconds: number, minutes: number, days: number}}
 */
export const calculateTimeLeft = (targetDay, targetTime) => {
  const now = new Date()

  // Convert current time to Eastern Time (UTC-5 or UTC-4 during daylight saving time)
  const isDst = now.getTimezoneOffset() < new Date(now.getFullYear(), 6, 1).getTimezoneOffset();
  const offsetET = isDst ? -4 : -5;
  const nowInET = new Date(now.valueOf() + (now.getTimezoneOffset() + offsetET * 60) * 60000);

  // Find next target day
  const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
  const currentDayIndex = nowInET.getDay()
  const targetDayIndex = daysOfWeek.indexOf(targetDay)

  const targetHours = parseInt(targetTime.split(':')[0])
  const targetMinutes = parseInt(targetTime.split(':')[1] || '0')

  let daysToAdd = 0
  if (targetDayIndex > currentDayIndex) {
    daysToAdd = targetDayIndex - currentDayIndex
  } else if (targetDayIndex < currentDayIndex) {
    daysToAdd = 7 - (currentDayIndex - targetDayIndex)
  } else {
    // Same day scenario
    if (targetHours > nowInET.getHours() || (targetHours === nowInET.getHours() && targetMinutes > nowInET.getMinutes())) {
      daysToAdd = 0
    } else {
      daysToAdd = 7
    }
  }

  // Create target date based on the day difference
  const targetDate = new Date(nowInET.getTime() + daysToAdd * 24 * 60 * 60 * 1000);
  targetDate.setHours(targetHours, targetMinutes, 0, 0);

  const difference = targetDate - nowInET

  return {
    total: difference,
    days: Math.floor(difference / (1000 * 60 * 60 * 24)),
    hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
    minutes: Math.floor((difference / (1000 * 60)) % 60),
    seconds: Math.floor((difference / 1000) % 60)
  }
}