Skip to content

Instantly share code, notes, and snippets.

@andreimerlescu
Last active September 5, 2026 00:32
Show Gist options
  • Select an option

  • Save andreimerlescu/495c66c38f8ad31f042fc95e08ce1d8f to your computer and use it in GitHub Desktop.

Select an option

Save andreimerlescu/495c66c38f8ad31f042fc95e08ce1d8f to your computer and use it in GitHub Desktop.
<?php declare(strict_types=1);
namespace AVC;
class Shabbat
{
public static function enforce(): void {
if (is_falsy(from_server(key: IS_DEV)) && self::is_shabbat()) {
self::send_headers();
echo self::render_shabbat();
exit;
}
}
public static function str_date(): string
{
$date = new \DateTime(
datetime: 'now',
timezone: new \DateTimeZone(timezone: 'America/New_York'),
);
$jd = gregoriantojd(
month: (int)$date->format(format: 'm'),
day: (int)$date->format(format: 'd'),
year: (int)$date->format(format: 'Y'),
);
$hebrew_date = cal_from_jd(
julian_day: $jd,
calendar: CAL_JEWISH,
);
$hebrew_months = [
1 => 'Tishri',
2 => 'Heshvan',
3 => 'Kislev',
4 => 'Tevet',
5 => 'Shevat',
6 => 'Adar',
7 => 'Adar II',
8 => 'Nisan',
9 => 'Iyar',
10 => 'Sivan',
11 => 'Tammuz',
12 => 'Av',
13 => 'Elul'
];
return sprintf("%d %s %d",
$hebrew_date['day'],
$hebrew_months[$hebrew_date['month']],
$hebrew_date['year']
);
}
private static function current_time(): \DateTime {
return new \DateTime();
}
private static function friday_730pm(): \DateTime {
return new \DateTime(datetime: 'Friday this week 19:30')
->setTimezone(new \DateTimeZone(timezone: 'America/New_York'));
}
private static function saturday_830pm(): \DateTime {
return new \DateTime(datetime: 'Saturday this week 20:30')
->setTimezone(new \DateTimeZone(timezone: 'America/New_York'));
}
public static function is_shabbat(): bool
{
return (
self::current_time() >= self::friday_730pm()
&&
self::current_time() < self::saturday_830pm()
);
}
public static function remaining_time(): int {
return self::saturday_830pm()->getTimestamp() - self::current_time()->getTimestamp();
}
public static function end_time(): string {
return self::saturday_830pm()->format('l, F j, Y');
}
public static function send_headers(): void {
if (!empty($_SERVER['HTTP_X_SHABBAT_CHECK'])) {
return; // Exit if this header is already set
}
header('X-Shabbat-Check: true');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
header('Content-Type: text/html; charset=utf-8');
}
public static function render_shabbat(): string {
global $configs;
$company = $configs['general']['company'] ?? 'This website';
$title = i18n::__("Shabbat Shalom!");
$remaining_time = self::remaining_time();
$h1 = i18n::__("SHABBAT SHALOM!");
$p1 = i18n::__("is honoring Yeshua's Sabbath for Shabbat.");
$p2 = i18n::__("Our site will be back online in");
$p3 = i18n::__("We will reopen at 8:30pm on");
$p4 = i18n::__("Current Date");
$end_time = self::end_time();
$str_date = self::str_date();
return <<<DOD
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$title}</title>
<style>
body {
background-color: #2F4F4F; /* Slate Steel Gray */
color: #2C2C2C; /* Noir Graphite Dark Gray */
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background-color: rgba(255, 255, 255, 0.9);
padding: 2rem;
border-radius: 10px;
text-align: center;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
max-width: 600px;
width: 90%;
}
.countdown {
font-size: 2rem;
margin: 1rem 0;
font-weight: bold;
}
h1 {
margin-top: 0;
}
</style>
<script>
function startCountdown(seconds) {
const countdownElem = document.getElementById('countdown');
function updateCountdown() {
const days = Math.floor(seconds / 86400);
const hours = Math.floor((seconds % 86400) / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
countdownElem.textContent =
String(days).padStart(2, '0') + 'd ' +
String(hours).padStart(2, '0') + 'h ' +
String(minutes).padStart(2, '0') + 'm ' +
String(secs).padStart(2, '0') + 's';
if (seconds > 0) {
seconds--;
setTimeout(updateCountdown, 1000);
}
}
updateCountdown();
}
document.addEventListener('DOMContentLoaded', () => {
const remainingTime = {$remaining_time};
startCountdown(remainingTime);
});
</script>
</head>
<body>
<div class="container">
<h1>{$h1}</h1>
<p>{$company} {$p1}</p>
<p>{$p2}:</p>
<div class="countdown" id="countdown"></div>
<p>{$p3} {$end_time}.</p>
<p>{$p4}: {$str_date}</p>
</div>
</body>
</html>
DOD;
}
}
\class_alias(Shabbat::class, 'Shabbat');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment