Time Zones Are Hard - https://tz.rita.moe
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185<?php// Configurationconst COOKIE_LIFETIME = 60 * 60 * 24 * 365; // 1 yearconst SITE_BASE = 'https://tz.rita.moe'; // Base URL, no trailing slash
// Set security headers$nonce = bin2hex(random_bytes(16));header("Content-Security-Policy: default-src 'none'; script-src 'self' " . "'nonce-$nonce'; img-src 'self'; style-src 'self'; form-action 'self';");header('X-Content-Type-Options: nosniff');header('X-Frame-Options: DENY');header('X-XSS-Protection: 1; mode=block');
function getOffset($tz) { $tz = new DateTime('now', new DateTimeZone($tz)); $offset = $tz->format('T'); return (str_starts_with($offset, '-') || str_starts_with($offset, '+')) ? 'UTC' . $offset : $offset;}
function toTZ($dt, $tz, $format='Y-m-d H:i') { $tz = new DateTimeZone($tz); return $dt->setTimezone($tz)->format($format);}
function setUserCookie($name, $value) { setcookie($name, $value, time() + COOKIE_LIFETIME, '/'); $_COOKIE[$name] = $value;}
$popTZ = [ 'America/Los_Angeles', // PST/PDT 'America/New_York', // EST/EDT 'Europe/London', // BST/GMT 'Europe/Paris', // CEST/CET 'Asia/Dubai', // UTC+04 "UAE" 'Asia/Jakarta', // WIB 'Asia/Tokyo', // JST 'Australia/Sydney', // AEST/AEDT 'UTC'];
$allTZ = timezone_identifiers_list(DateTimeZone::ALL);$currPageEncoded = htmlspecialchars(SITE_BASE . $_SERVER['REQUEST_URI'], ENT_QUOTES, 'UTF-8');
// User sets timezone cookieif (isset($_POST['user-tz']) && in_array($_POST['user-tz'], $allTZ)) { setUserCookie('user-tz', $_POST['user-tz']);}
// User sets 24 hoursif (isset($_POST['user-24'])) { setUserCookie('user-24', '1');}
// If had JS enabled but doesn't now, set has-js to 0if (isset($_POST['no-js'])) { setUserCookie('has-js', '0');}
// Micro-routingtry { if (isset($_POST['datetime']) && isset($_POST['timezone'])) { // -- Redirect to submitted date // @NOTE(Kody): I'm fine not validating all inputs here. // Either it will fall in the catch block, or fail at // the validation after the redirect.
// Handle if timezone is an offset $postTZ = $_POST['timezone']; if (is_numeric($_POST['timezone'])) { $isNeg = str_starts_with($postTZ, '-'); $h = str_pad(abs(intdiv($postTZ, 60)), 2, '0', STR_PAD_LEFT); $m = str_pad($postTZ % 60, 2, '0', STR_PAD_LEFT); $postTZ = ($isNeg ? '-' : '+') . $h . $m; }
// Make our date object $dateObj = new DateTime($_POST['datetime'], new DateTimeZone($postTZ));
// Redirect, with the "+" replaced by "_" header('Location: /' . str_replace('+', '_', $dateObj->format('c'))); exit; } elseif ($_SERVER['REQUEST_URI'] !== '/') { // -- Show date infos // Remove leading "/" $req = substr($_SERVER['REQUEST_URI'], 1);
// Check if date is following the format $re = '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[\_|-]\d{2}:\d{2}$/'; if (!preg_match($re, $req)) { http_response_code(404); $error = 'Date is not valid, wrong format, or file not found.'; } else { // Make our date object, convert back "_" to "+" $dt = new DateTime(str_replace('_', '+', $req)); } }} catch (Exception $e) { http_response_code(400); $error = 'Date is not valid, or wrong format.';}?><!DOCTYPE html><!-- Source code: https://git.rita.moe/Rita/tz License: MIT--><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Time Zones Are Hard<?= isset($req) ? ' - ' . htmlspecialchars( str_replace('_', '+', $req), ENT_QUOTES, 'UTF-8' ) : '' ?></title> <link rel="stylesheet" href="/css/styles.css"><?php if (isset($dt)) { ?> <meta name="robots" content="noindex,noarchive"> <script src="/js/dayjs.min.js"></script> <script src="/js/relativeTime.js"></script> <script nonce="<?= $nonce ?>"> dayjs.extend(window.dayjs_plugin_relativeTime) </script><?php } ?> <link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png"> <link rel="manifest" href="/site.webmanifest"> <link rel="mask-icon" href="/img/safari-pinned-tab.svg" color="#111111"> <meta name="msapplication-TileColor" content="#111111"> <meta name="theme-color" content="#111111"></head><body> <header> <h1> <a href="/"> <?= file_get_contents('./img/clock.svg') . PHP_EOL; ?> Time Zones Are Hard </a> </h1> </header>
<main><?php if (isset($error)) { ?> <h2 class="error">Error: <?= $error ?></h2> <form action="/" method="post"> <button type="submit">Go back home</button> </form><?php } elseif (isset($dt)) { require_once './pages/dt.php'; } else { require_once './pages/home.php'; }?> </main>
<footer> © <?= date('Y') ?> rita.moe - Made with 🍮<br/> <a href="https://thenounproject.com/icon/wall-clock-5456766/" rel="noopener" target="_blank" title="Wall Clock Icon" >Wall Clock by Basicon</a> from Noun Project (CC BY 3.0) </footer><?php if ($_COOKIE['has-js'] !== '1') { ?>
<script nonce="<?= $nonce ?>"> // Save on the document size if user has JavaScript const date = new Date() date.setTime(date.getTime() + (1000 * <?= COOKIE_LIFETIME ?>)) document.cookie = 'has-js=1; expires=' + date.toUTCString() + '; path=/' </script><?php } ?></body></html>