@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at recaptime-dev/main 159 lines 4.3 kB view raw
1<?php 2 3function phabricator_date($epoch, PhabricatorUser $user) { 4 return phabricator_format_local_time( 5 $epoch, 6 $user, 7 phutil_date_format($epoch)); 8} 9 10function phabricator_relative_date($epoch, $user, $on = false) { 11 static $today; 12 static $yesterday; 13 14 if (!$today || !$yesterday) { 15 $now = time(); 16 $today = phabricator_date($now, $user); 17 $yesterday = phabricator_date($now - 86400, $user); 18 } 19 20 $date = phabricator_date($epoch, $user); 21 22 if ($date === $today) { 23 return 'today'; 24 } 25 26 if ($date === $yesterday) { 27 return 'yesterday'; 28 } 29 30 return (($on ? 'on ' : '').$date); 31} 32 33function phabricator_time($epoch, $user) { 34 $time_key = PhabricatorTimeFormatSetting::SETTINGKEY; 35 return phabricator_format_local_time( 36 $epoch, 37 $user, 38 $user->getUserSetting($time_key)); 39} 40 41function phabricator_dual_datetime($epoch, $user) { 42 $screen_view = phabricator_datetime($epoch, $user); 43 $print_view = phabricator_absolute_datetime($epoch, $user); 44 45 $screen_tag = javelin_tag( 46 'span', 47 array( 48 'print' => false, 49 ), 50 $screen_view); 51 52 $print_tag = javelin_tag( 53 'span', 54 array( 55 'print' => true, 56 ), 57 $print_view); 58 59 return array( 60 $screen_tag, 61 $print_tag, 62 ); 63} 64 65function phabricator_absolute_datetime($epoch, $user) { 66 $format = 'Y-m-d H:i:s (\\U\\T\\CP)'; 67 68 $datetime = phabricator_format_local_time($epoch, $user, $format); 69 $datetime = preg_replace('/(UTC[+-])0?([^:]+)(:00)?/', '\\1\\2', $datetime); 70 71 return $datetime; 72} 73 74function phabricator_datetime($epoch, $user) { 75 $time_key = PhabricatorTimeFormatSetting::SETTINGKEY; 76 return phabricator_format_local_time( 77 $epoch, 78 $user, 79 pht('%s, %s', 80 phutil_date_format($epoch), 81 $user->getUserSetting($time_key))); 82} 83 84function phabricator_datetimezone($epoch, $user) { 85 $datetime = phabricator_datetime($epoch, $user); 86 $timezone = phabricator_format_local_time($epoch, $user, 'T'); 87 88 // Some obscure timezones just render as "+03" or "-09". Make these render 89 // as "UTC+3" instead. 90 if (preg_match('/^[+-]/', $timezone)) { 91 $timezone = (int)trim($timezone, '+'); 92 if ($timezone < 0) { 93 $timezone = pht('UTC-%s', $timezone); 94 } else { 95 $timezone = pht('UTC+%s', $timezone); 96 } 97 } 98 99 return pht('%s (%s)', $datetime, $timezone); 100} 101 102 103/** 104 * Applies the user's timezone preferences to convert the give 105 * epoch (number of seconds since January 1, 1970) to a DateTime object 106 * @param int $epoch Unix epoch timestamp. 107 * @param PhabricatorUser $user User viewing the timestamp. 108 * @return ?DateTime 109 */ 110function phorge_localize_time($epoch, $user) { 111 if (!$epoch) { 112 // If we're missing date information for something, the DateTime class will 113 // throw an exception when we try to construct an object. 114 return null; 115 } 116 $user_zone = $user->getTimezoneIdentifier(); 117 118 static $zones = array(); 119 if (empty($zones[$user_zone])) { 120 $zones[$user_zone] = new DateTimeZone($user_zone); 121 } 122 $zone = $zones[$user_zone]; 123 124 // NOTE: Although DateTime takes a second DateTimeZone parameter to its 125 // constructor, it ignores it if the date string includes timezone 126 // information. Further, it treats epoch timestamps ("@946684800") as having 127 // a UTC timezone. Set the timezone explicitly after constructing the object. 128 try { 129 $date = new DateTime('@'.$epoch); 130 } catch (Exception $ex) { 131 // NOTE: DateTime throws an empty exception if the format is invalid, 132 // just replace it with a useful one. 133 throw new Exception( 134 pht("Construction of a DateTime() with epoch '%s' ". 135 "raised an exception.", $epoch)); 136 } 137 138 $date->setTimezone($zone); 139 return $date; 140} 141 142/** 143 * This function does not usually need to be called directly. Instead, call 144 * @{function:phabricator_date}, @{function:phabricator_time}, or 145 * @{function:phabricator_datetime}. 146 * 147 148 * @param string $format Date format, as per DateTime class. 149 * @return string Formatted, local date/time. 150 */ 151function phabricator_format_local_time($epoch, $user, $format) { 152 $date = phorge_localize_time($epoch, $user); 153 if (!$date) { 154 // If we're missing date information for something, display that as 155 // an empty string 156 return ''; 157 } 158 return PhutilTranslator::getInstance()->translateDate($format, $date); 159}