Remove user-independent date and time functions from Phabricator

Summary: These have been moved into libphutil.

Test Plan: Browsed Phabricator, didn't see a crash.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: epriestley, Korvin

Differential Revision: https://secure.phabricator.com/D9907
This commit is contained in:
James Rhodes
2014-07-13 12:03:17 +10:00
parent ca6b3a632d
commit 9cb6b2cfcc
19 changed files with 38 additions and 212 deletions

View File

@@ -2709,7 +2709,6 @@ phutil_register_library_map(array(
), ),
'function' => 'function' =>
array( array(
'_phabricator_date_format' => 'view/viewutils.php',
'_phabricator_time_format' => 'view/viewutils.php', '_phabricator_time_format' => 'view/viewutils.php',
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api.php', 'celerity_generate_unique_node_id' => 'infrastructure/celerity/api.php',
'celerity_get_resource_uri' => 'infrastructure/celerity/api.php', 'celerity_get_resource_uri' => 'infrastructure/celerity/api.php',
@@ -2718,13 +2717,8 @@ phutil_register_library_map(array(
'phabricator_date' => 'view/viewutils.php', 'phabricator_date' => 'view/viewutils.php',
'phabricator_datetime' => 'view/viewutils.php', 'phabricator_datetime' => 'view/viewutils.php',
'phabricator_form' => 'infrastructure/javelin/markup.php', 'phabricator_form' => 'infrastructure/javelin/markup.php',
'phabricator_format_bytes' => 'view/viewutils.php',
'phabricator_format_local_time' => 'view/viewutils.php', 'phabricator_format_local_time' => 'view/viewutils.php',
'phabricator_format_relative_time' => 'view/viewutils.php',
'phabricator_format_relative_time_detailed' => 'view/viewutils.php',
'phabricator_format_units_generic' => 'view/viewutils.php',
'phabricator_on_relative_date' => 'view/viewutils.php', 'phabricator_on_relative_date' => 'view/viewutils.php',
'phabricator_parse_bytes' => 'view/viewutils.php',
'phabricator_relative_date' => 'view/viewutils.php', 'phabricator_relative_date' => 'view/viewutils.php',
'phabricator_time' => 'view/viewutils.php', 'phabricator_time' => 'view/viewutils.php',
'phid_get_subtype' => 'applications/phid/utils.php', 'phid_get_subtype' => 'applications/phid/utils.php',

View File

@@ -125,7 +125,7 @@ final class ConduitAPI_conduit_connect_Method extends ConduitAPIMethod {
'timestamp must differ from the server time by no more than '. 'timestamp must differ from the server time by no more than '.
'%s seconds. Your client or server clock may not be set '. '%s seconds. Your client or server clock may not be set '.
'correctly.', 'correctly.',
phabricator_format_relative_time($threshold), phutil_format_relative_time($threshold),
$token, $token,
date('r', $token), date('r', $token),
$now, $now,

View File

@@ -109,14 +109,14 @@ final class PhabricatorDaemonLogViewController
$details = pht( $details = pht(
'This daemon is running normally and reported a status update '. 'This daemon is running normally and reported a status update '.
'recently (within %s).', 'recently (within %s).',
phabricator_format_relative_time($unknown_time)); phutil_format_relative_time($unknown_time));
break; break;
case PhabricatorDaemonLog::STATUS_UNKNOWN: case PhabricatorDaemonLog::STATUS_UNKNOWN:
$details = pht( $details = pht(
'This daemon has not reported a status update recently (within %s). '. 'This daemon has not reported a status update recently (within %s). '.
'It may have exited abruptly. After %s, it will be presumed dead.', 'It may have exited abruptly. After %s, it will be presumed dead.',
phabricator_format_relative_time($unknown_time), phutil_format_relative_time($unknown_time),
phabricator_format_relative_time($dead_time)); phutil_format_relative_time($dead_time));
break; break;
case PhabricatorDaemonLog::STATUS_DEAD: case PhabricatorDaemonLog::STATUS_DEAD:
$details = pht( $details = pht(
@@ -124,7 +124,7 @@ final class PhabricatorDaemonLogViewController
'presumed dead. Usually, this indicates that the daemon was '. 'presumed dead. Usually, this indicates that the daemon was '.
'killed or otherwise exited abruptly with an error. You may '. 'killed or otherwise exited abruptly with an error. You may '.
'need to restart it.', 'need to restart it.',
phabricator_format_relative_time($dead_time)); phutil_format_relative_time($dead_time));
break; break;
case PhabricatorDaemonLog::STATUS_WAIT: case PhabricatorDaemonLog::STATUS_WAIT:
$details = pht( $details = pht(
@@ -133,8 +133,8 @@ final class PhabricatorDaemonLogViewController
'doing work and is waiting a little while (%s) to resume '. 'doing work and is waiting a little while (%s) to resume '.
'processing. After encountering an error, daemons wait before '. 'processing. After encountering an error, daemons wait before '.
'resuming work to avoid overloading services.', 'resuming work to avoid overloading services.',
phabricator_format_relative_time($unknown_time), phutil_format_relative_time($unknown_time),
phabricator_format_relative_time($wait_time)); phutil_format_relative_time($wait_time));
break; break;
case PhabricatorDaemonLog::STATUS_EXITED: case PhabricatorDaemonLog::STATUS_EXITED:
$details = pht( $details = pht(
@@ -152,7 +152,7 @@ final class PhabricatorDaemonLogViewController
pht('Seen'), pht('Seen'),
pht( pht(
'%s ago (%s)', '%s ago (%s)',
phabricator_format_relative_time(time() - $u_epoch), phutil_format_relative_time(time() - $u_epoch),
phabricator_datetime($u_epoch, $viewer))); phabricator_datetime($u_epoch, $viewer)));
$argv = $daemon->getArgv(); $argv = $daemon->getArgv();

View File

@@ -174,7 +174,7 @@ final class PhabricatorWorkerTaskDetailController
if ($task->getLeaseExpires() && $task->getLeaseOwner()) { if ($task->getLeaseExpires() && $task->getLeaseOwner()) {
$expires = ($task->getLeaseExpires() - time()); $expires = ($task->getLeaseExpires() - time());
$expires = phabricator_format_relative_time_detailed($expires); $expires = phutil_format_relative_time_detailed($expires);
} else { } else {
$expires = phutil_tag('em', array(), pht('None')); $expires = phutil_tag('em', array(), pht('None'));
} }
@@ -247,7 +247,7 @@ final class PhabricatorWorkerTaskDetailController
$duration = 60; $duration = 60;
} }
$cumulative += $duration; $cumulative += $duration;
$next[$key] = phabricator_format_relative_time($cumulative); $next[$key] = phutil_format_relative_time($cumulative);
} }
if ($ii != $retry_count) { if ($ii != $retry_count) {
$next[] = '...'; $next[] = '...';

View File

@@ -179,7 +179,7 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$finfo->addProperty( $finfo->addProperty(
pht('Size'), pht('Size'),
phabricator_format_bytes($file->getByteSize())); phutil_format_bytes($file->getByteSize()));
$finfo->addProperty( $finfo->addProperty(
pht('Mime Type'), pht('Mime Type'),

View File

@@ -86,9 +86,9 @@ final class PhabricatorFileUploadController extends PhabricatorFileController {
private function renderUploadLimit() { private function renderUploadLimit() {
$limit = PhabricatorEnv::getEnvConfig('storage.upload-size-limit'); $limit = PhabricatorEnv::getEnvConfig('storage.upload-size-limit');
$limit = phabricator_parse_bytes($limit); $limit = phutil_parse_bytes($limit);
if ($limit) { if ($limit) {
$formatted = phabricator_format_bytes($limit); $formatted = phutil_format_bytes($limit);
return 'Maximum file size: '.$formatted; return 'Maximum file size: '.$formatted;
} }

View File

@@ -166,7 +166,7 @@ final class PhabricatorFileSearchEngine
->setHeader($name) ->setHeader($name)
->setHref($file_uri) ->setHref($file_uri)
->addAttribute($uploaded) ->addAttribute($uploaded)
->addIcon('none', phabricator_format_bytes($file->getByteSize())); ->addIcon('none', phutil_format_bytes($file->getByteSize()));
$ttl = $file->getTTL(); $ttl = $file->getTTL();
if ($ttl !== null) { if ($ttl !== null) {

View File

@@ -108,7 +108,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
return; return;
} }
$limit = phabricator_parse_bytes($limit); $limit = phutil_parse_bytes($limit);
if ($size > $limit) { if ($size > $limit) {
throw new PhabricatorFileUploadException(-1000); throw new PhabricatorFileUploadException(-1000);
} }

View File

@@ -41,7 +41,7 @@ final class PhabricatorNotificationStatusController
switch ($key) { switch ($key) {
case 'uptime': case 'uptime':
$value /= 1000; $value /= 1000;
$value = phabricator_format_relative_time_detailed($value); $value = phutil_format_relative_time_detailed($value);
break; break;
case 'log': case 'log':
break; break;

View File

@@ -26,7 +26,7 @@ final class PhabricatorUserSinceField
$this->getObject()->getDateCreated(), $this->getObject()->getDateCreated(),
$this->getViewer()); $this->getViewer());
$relative = phabricator_format_relative_time_detailed( $relative = phutil_format_relative_time_detailed(
time() - $this->getObject()->getDateCreated(), time() - $this->getObject()->getDateCreated(),
$levels = 2); $levels = 2);

View File

@@ -138,7 +138,7 @@ final class PhrequentUIEventListener
$block = new PhrequentTimeBlock($event_group); $block = new PhrequentTimeBlock($event_group);
$item->setNote( $item->setNote(
phabricator_format_relative_time( phutil_format_relative_time(
$block->getTimeSpentOnObject( $block->getTimeSpentOnObject(
$object->getPHID(), $object->getPHID(),
time()))); time())));

View File

@@ -166,7 +166,7 @@ final class PhrequentSearchEngine
} }
$time_spent = $time_spent == 0 ? 'none' : $time_spent = $time_spent == 0 ? 'none' :
phabricator_format_relative_time_detailed($time_spent); phutil_format_relative_time_detailed($time_spent);
if ($usertime->getDateEnded() !== null) { if ($usertime->getDateEnded() !== null) {
$item->addAttribute( $item->addAttribute(

View File

@@ -195,7 +195,7 @@ final class ReleephRequestEditController extends ReleephBranchController {
$age_string = ''; $age_string = '';
if ($is_edit) { if ($is_edit) {
$age_string = phabricator_format_relative_time( $age_string = phutil_format_relative_time(
time() - $pull->getDateCreated()).' ago'; time() - $pull->getDateCreated()).' ago';
} }

View File

@@ -56,7 +56,7 @@ final class ReleephRequestTypeaheadController
$full_commit_id, $full_commit_id,
$short_commit_id, $short_commit_id,
$row['authorName'], $row['authorName'],
phabricator_format_relative_time($now - $row['epoch']), phutil_format_relative_time($now - $row['epoch']),
$first_line, $first_line,
); );
} }

View File

@@ -469,8 +469,8 @@ final class PhabricatorRepositoryCommitHeraldWorker
$size = strlen($raw_diff); $size = strlen($raw_diff);
if ($byte_limit && $size > $byte_limit) { if ($byte_limit && $size > $byte_limit) {
$pretty_size = phabricator_format_bytes($size); $pretty_size = phutil_format_bytes($size);
$pretty_limit = phabricator_format_bytes($byte_limit); $pretty_limit = phutil_format_bytes($byte_limit);
throw new Exception( throw new Exception(
"Patch size of {$pretty_size} exceeds configured byte size limit of ". "Patch size of {$pretty_size} exceeds configured byte size limit of ".
"{$pretty_limit}."); "{$pretty_limit}.");

View File

@@ -78,7 +78,7 @@ final class PhabricatorSettingsPanelSessions
substr($session->getSessionKey(), 0, 6), substr($session->getSessionKey(), 0, 6),
$session->getType(), $session->getType(),
($hisec > 0) ($hisec > 0)
? phabricator_format_relative_time($hisec) ? phutil_format_relative_time($hisec)
: null, : null,
phabricator_datetime($session->getSessionStart(), $viewer), phabricator_datetime($session->getSessionStart(), $viewer),
phabricator_date($session->getSessionExpires(), $viewer), phabricator_date($session->getSessionExpires(), $viewer),

View File

@@ -19,8 +19,8 @@ final class PhabricatorUnitsTestCase extends PhabricatorTestCase {
foreach ($tests as $input => $expect) { foreach ($tests as $input => $expect) {
$this->assertEqual( $this->assertEqual(
$expect, $expect,
phabricator_format_bytes($input), phutil_format_bytes($input),
'phabricator_format_bytes('.$input.')'); 'phutil_format_bytes('.$input.')');
} }
} }
@@ -42,14 +42,14 @@ final class PhabricatorUnitsTestCase extends PhabricatorTestCase {
foreach ($tests as $input => $expect) { foreach ($tests as $input => $expect) {
$this->assertEqual( $this->assertEqual(
$expect, $expect,
phabricator_parse_bytes($input), phutil_parse_bytes($input),
'phabricator_parse_bytes('.$input.')'); 'phutil_parse_bytes('.$input.')');
} }
$this->tryTestCases( $this->tryTestCases(
array('string' => 'string'), array('string' => 'string'),
array(false), array(false),
'phabricator_parse_bytes'); 'phutil_parse_bytes');
} }
public function testDetailedDurationFormatting() { public function testDetailedDurationFormatting() {
@@ -68,8 +68,8 @@ final class PhabricatorUnitsTestCase extends PhabricatorTestCase {
foreach ($tests as $duration => $expect) { foreach ($tests as $duration => $expect) {
$this->assertEqual( $this->assertEqual(
$expect, $expect,
phabricator_format_relative_time_detailed($duration), phutil_format_relative_time_detailed($duration),
'phabricator_format_relative_time_detailed('.$duration.')'); 'phutil_format_relative_time_detailed('.$duration.')');
} }
@@ -113,16 +113,16 @@ final class PhabricatorUnitsTestCase extends PhabricatorTestCase {
foreach ($sub_tests as $levels => $expect) { foreach ($sub_tests as $levels => $expect) {
$this->assertEqual( $this->assertEqual(
$expect, $expect,
phabricator_format_relative_time_detailed($duration, $levels), phutil_format_relative_time_detailed($duration, $levels),
'phabricator_format_relative_time_detailed('.$duration.', 'phutil_format_relative_time_detailed('.$duration.',
'.$levels.')'); '.$levels.')');
} }
} else { } else {
$expect = $sub_tests; $expect = $sub_tests;
$this->assertEqual( $this->assertEqual(
$expect, $expect,
phabricator_format_relative_time_detailed($duration), phutil_format_relative_time_detailed($duration),
'phabricator_format_relative_time_detailed('.$duration.')'); 'phutil_format_relative_time_detailed('.$duration.')');
} }
} }

View File

@@ -171,7 +171,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
if ($user->hasSession()) { if ($user->hasSession()) {
$hisec = ($user->getSession()->getHighSecurityUntil() - time()); $hisec = ($user->getSession()->getHighSecurityUntil() - time());
if ($hisec > 0) { if ($hisec > 0) {
$remaining_time = phabricator_format_relative_time($hisec); $remaining_time = phutil_format_relative_time($hisec);
Javelin::initBehavior( Javelin::initBehavior(
'high-security-warning', 'high-security-warning',
array( array(

View File

@@ -4,7 +4,7 @@ function phabricator_date($epoch, PhabricatorUser $user) {
return phabricator_format_local_time( return phabricator_format_local_time(
$epoch, $epoch,
$user, $user,
_phabricator_date_format($epoch)); _phutil_date_format($epoch));
} }
function phabricator_on_relative_date($epoch, $user) { function phabricator_on_relative_date($epoch, $user) {
@@ -46,21 +46,10 @@ function phabricator_datetime($epoch, $user) {
$epoch, $epoch,
$user, $user,
pht('%s, %s', pht('%s, %s',
_phabricator_date_format($epoch), _phutil_date_format($epoch),
_phabricator_time_format($user))); _phabricator_time_format($user)));
} }
function _phabricator_date_format($epoch) {
$now = time();
$shift = 30 * 24 * 60 * 60;
if ($epoch < $now + $shift && $epoch > $now - $shift) {
$format = pht('D, M j');
} else {
$format = pht('M j Y');
}
return $format;
}
function _phabricator_time_format($user) { function _phabricator_time_format($user) {
$prefs = $user->loadPreferences(); $prefs = $user->loadPreferences();
@@ -119,161 +108,4 @@ function phabricator_format_local_time($epoch, $user, $format) {
return PhutilTranslator::getInstance()->translateDate($format, $date); return PhutilTranslator::getInstance()->translateDate($format, $date);
} }
function phabricator_format_relative_time($duration) {
return phabricator_format_units_generic(
$duration,
array(60, 60, 24, 7),
array('s', 'm', 'h', 'd', 'w'),
$precision = 0);
}
/**
* Format a relative time (duration) into weeks, days, hours, minutes,
* seconds, but unlike phabricator_format_relative_time, does so for more than
* just the largest unit.
*
* @param int Duration in seconds.
* @param int Levels to render - will render the three highest levels, ie:
* 5 h, 37 m, 1 s
* @return string Human-readable description.
*/
function phabricator_format_relative_time_detailed($duration, $levels = 2) {
if ($duration == 0) {
return 'now';
}
$levels = max(1, min($levels, 5));
$remainder = 0;
$is_negative = false;
if ($duration < 0) {
$is_negative = true;
$duration = abs($duration);
}
$this_level = 1;
$detailed_relative_time = phabricator_format_units_generic(
$duration,
array(60, 60, 24, 7),
array('s', 'm', 'h', 'd', 'w'),
$precision = 0,
$remainder);
$duration = $remainder;
while ($remainder > 0 && $this_level < $levels) {
$detailed_relative_time .= ', '.phabricator_format_units_generic(
$duration,
array(60, 60, 24, 7),
array('s', 'm', 'h', 'd', 'w'),
$precision = 0,
$remainder);
$duration = $remainder;
$this_level++;
};
if ($is_negative) {
$detailed_relative_time .= ' ago';
}
return $detailed_relative_time;
}
/**
* Format a byte count for human consumption, e.g. "10MB" instead of
* "10000000".
*
* @param int Number of bytes.
* @return string Human-readable description.
*/
function phabricator_format_bytes($bytes) {
return phabricator_format_units_generic(
$bytes,
// NOTE: Using the SI version of these units rather than the 1024 version.
array(1000, 1000, 1000, 1000, 1000),
array('B', 'KB', 'MB', 'GB', 'TB', 'PB'),
$precision = 0);
}
/**
* Parse a human-readable byte description (like "6MB") into an integer.
*
* @param string Human-readable description.
* @return int Number of represented bytes.
*/
function phabricator_parse_bytes($input) {
$bytes = trim($input);
if (!strlen($bytes)) {
return null;
}
// NOTE: Assumes US-centric numeral notation.
$bytes = preg_replace('/[ ,]/', '', $bytes);
$matches = null;
if (!preg_match('/^(?:\d+(?:[.]\d+)?)([kmgtp]?)b?$/i', $bytes, $matches)) {
throw new Exception("Unable to parse byte size '{$input}'!");
}
$scale = array(
'k' => 1000,
'm' => 1000 * 1000,
'g' => 1000 * 1000 * 1000,
't' => 1000 * 1000 * 1000 * 1000,
'p' => 1000 * 1000 * 1000 * 1000 * 1000,
);
$bytes = (float)$bytes;
if ($matches[1]) {
$bytes *= $scale[strtolower($matches[1])];
}
return (int)$bytes;
}
function phabricator_format_units_generic(
$n,
array $scales,
array $labels,
$precision = 0,
&$remainder = null) {
$is_negative = false;
if ($n < 0) {
$is_negative = true;
$n = abs($n);
}
$remainder = 0;
$accum = 1;
$scale = array_shift($scales);
$label = array_shift($labels);
while ($n >= $scale && count($labels)) {
$remainder += ($n % $scale) * $accum;
$n /= $scale;
$accum *= $scale;
$label = array_shift($labels);
if (!count($scales)) {
break;
}
$scale = array_shift($scales);
}
if ($is_negative) {
$n = -$n;
$remainder = -$remainder;
}
if ($precision) {
$num_string = number_format($n, $precision);
} else {
$num_string = (int)floor($n);
}
if ($label) {
$num_string .= ' '.$label;
}
return $num_string;
}