Skip to content

Instantly share code, notes, and snippets.

@spotco
Created December 9, 2025 23:44
Show Gist options
  • Select an option

  • Save spotco/4faeb0e07543d083d288a98dff6911cb to your computer and use it in GitHub Desktop.

Select an option

Save spotco/4faeb0e07543d083d288a98dff6911cb to your computer and use it in GitHub Desktop.
time.php
<?php
header('Content-Type: application/json; charset=utf-8');
// === Configuration (exact match to Ruby) ===
$time_offset = -8 * 3600; // -8 hours → midnight PST
$debug_time_offset = 0; // in seconds (DEBUG_DAYS * 24 * 3600 to debug offset days)
$day_of_week_offset = -3;
$month_offset = 10;
$year_offset = 2019;
// Base epoch: June 23, 2017 00:00:00 UTC, adjusted by $time_offset
$base_epoch = strtotime('2017-06-23 00:00:00+00:00') + $time_offset;
// Current virtual time (UTC + offset + debug)
function time_now() {
# ruby:
# return Time.now.utc + $time_offset + $debug_time_offset
global $time_offset, $debug_time_offset;
return time() + $time_offset + $debug_time_offset;
}
function virtual_midnight($ts) {
$y = (int)gmdate('Y', $ts);
$m = (int)gmdate('n', $ts);
$d = (int)gmdate('j', $ts);
return gmmktime(0, 0, 0, $m, $d, $y);
}
function get_day_id() {
# ruby:
# return ((time().beginning_of_day - ("2017-6-23".to_time(:utc) + $time_offset)) / 86400).to_i
global $base_epoch;
$now = time_now();
$midnight = virtual_midnight($now);
return (int)floor(($midnight - $base_epoch) / 86400);
}
function get_time_to_next_day() {
# ruby:
# return ((time() + 1.day).beginning_of_day - time()).to_i
$now = time_now();
$midnight = virtual_midnight($now);
return $midnight + 86400 - $now;
}
// Custom week ID: same as Ruby's get_week_for_dayid
function get_week_for_dayid($dayid) {
# ruby:
# return ((dayid + $day_of_week_offset) / 7).to_i
global $day_of_week_offset;
return (int)floor(($dayid + $day_of_week_offset) / 7);
}
function get_week() {
# ruby:
# return get_week_for_dayid(get_day_id())
return get_week_for_dayid(get_day_id());
}
function get_time_to_next_week() {
# ruby:
# return (6 - get_day_of_week_for_dayid(get_day_id())).days.to_i + get_time_to_next_day()
global $day_of_week_offset;
$dayid = get_day_id();
// This is exactly what Ruby does internally:
// shifted = dayid + $day_of_week_offset # dayid - 3
// current_position_in_week = shifted % 7
$position = ($dayid + $day_of_week_offset) % 7;
if ($position < 0) $position += 7; // PHP % can be negative → fix it
// Days remaining in the custom week (not including today)
$days_remaining = 6 - $position;
return $days_remaining * 86400 + get_time_to_next_day();
}
function get_month($ts = null) {
# ruby:
# if date.nil? then date = time() end
# return (date.month - $month_offset) + (date.year - $year_offset) * 12
global $month_offset, $year_offset;
if ($ts === null) $ts = time_now();
$y = (int)gmdate('Y', $ts);
$m = (int)gmdate('n', $ts);
return ($m - $month_offset) + ($y - $year_offset) * 12;
}
function get_time_to_next_month($ts = null) {
# if date.nil? then date = time() end
# return (date.end_of_month - date).to_i
if ($ts === null) $ts = time_now();
$current_day = (int)gmdate('j', $ts);
$days_in_month = (int)gmdate('t', $ts);
$seconds_in_day = 86400;
return ($days_in_month - $current_day + 1) * $seconds_in_day - (gmdate('H', $ts) * 3600 + gmdate('i', $ts) * 60 + gmdate('s', $ts));
}
$data = [
"Day" => get_day_id(),
"Time" => gmdate('c', time() + $debug_time_offset),
"SecondsToNextDay" => get_time_to_next_day(),
"Week" => get_week(),
"DataUpdatedTime" => 0,
"GlobalTime" => time() + $debug_time_offset,
"SecondsToNextWeek" => get_time_to_next_week(),
"Month" => get_month(),
"SecondsToNextMonth" => get_time_to_next_month(),
];
echo json_encode($data, JSON_UNESCAPED_SLASHES);
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment