From 76bdeb291f6eae7284378a48c2321b4bc67aaded Mon Sep 17 00:00:00 2001 From: Pppery Date: Sun, 8 Feb 2026 21:45:33 -0500 Subject: [PATCH] Don't try to translate date elements used internally in AphrontFormDateControlValue Summary: Fixes T15811. Alternative to D25618 Test Plan: Observe that the lengthy steps to reproduce in T15811 no longer reproduce. Observe that translated date strings (e.p.p.) still appear in most parts of the interface Reviewers: O1 Blessed Committers, aklapper Reviewed By: O1 Blessed Committers, aklapper Subscribers: avivey, aklapper, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15811 Differential Revision: https://we.phorge.it/D25861 --- src/__phutil_library_map__.php | 1 + .../control/AphrontFormDateControlValue.php | 12 ++++-- src/view/viewutils.php | 38 +++++++++++++------ 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 4b2ba6bef9..920851756b 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5961,6 +5961,7 @@ phutil_register_library_map(array( 'phid_get_subtype' => 'applications/phid/utils.php', 'phid_get_type' => 'applications/phid/utils.php', 'phid_group_by_type' => 'applications/phid/utils.php', + 'phorge_localize_time' => 'view/viewutils.php', 'phutil_escape_html' => 'infrastructure/markup/render.php', 'phutil_escape_html_newlines' => 'infrastructure/markup/render.php', 'phutil_implode_html' => 'infrastructure/markup/render.php', diff --git a/src/view/form/control/AphrontFormDateControlValue.php b/src/view/form/control/AphrontFormDateControlValue.php index 8b7952c8cd..45bc7fcb2c 100644 --- a/src/view/form/control/AphrontFormDateControlValue.php +++ b/src/view/form/control/AphrontFormDateControlValue.php @@ -166,10 +166,14 @@ final class AphrontFormDateControlValue extends Phobject { } private function formatTime($epoch, $format) { - return phabricator_format_local_time( - $epoch, - $this->viewer, - $format); + $date = phorge_localize_time($epoch, $this->viewer); + if (!$date) { + return ''; + } + // Call DateTime->format directly (bypassing PhutilTranslator) + // so that getFormattedDateFromParts below can decode the parts + // back into a DateTime + return $date->format($format); } public function getEpoch() { diff --git a/src/view/viewutils.php b/src/view/viewutils.php index 47a6f0178d..5abf0d19a2 100644 --- a/src/view/viewutils.php +++ b/src/view/viewutils.php @@ -99,25 +99,21 @@ function phabricator_datetimezone($epoch, $user) { return pht('%s (%s)', $datetime, $timezone); } + /** - * This function does not usually need to be called directly. Instead, call - * @{function:phabricator_date}, @{function:phabricator_time}, or - * @{function:phabricator_datetime}. - * + * Applies the user's timezone preferences to convert the give + * epoch (number of seconds since January 1, 1970) to a DateTime object * @param int $epoch Unix epoch timestamp. * @param PhabricatorUser $user User viewing the timestamp. - * @param string $format Date format, as per DateTime class. - * @return string Formatted, local date/time. + * @return ?DateTime */ -function phabricator_format_local_time($epoch, $user, $format) { +function phorge_localize_time($epoch, $user) { if (!$epoch) { // If we're missing date information for something, the DateTime class will - // throw an exception when we try to construct an object. Since this is a - // display function, just return an empty string. - return ''; + // throw an exception when we try to construct an object. + return null; } - - $user_zone = $user->getTimezoneIdentifier(); + $user_zone = $user->getTimezoneIdentifier(); static $zones = array(); if (empty($zones[$user_zone])) { @@ -140,6 +136,24 @@ function phabricator_format_local_time($epoch, $user, $format) { } $date->setTimezone($zone); + return $date; +} +/** + * This function does not usually need to be called directly. Instead, call + * @{function:phabricator_date}, @{function:phabricator_time}, or + * @{function:phabricator_datetime}. + * + + * @param string $format Date format, as per DateTime class. + * @return string Formatted, local date/time. + */ +function phabricator_format_local_time($epoch, $user, $format) { + $date = phorge_localize_time($epoch, $user); + if (!$date) { + // If we're missing date information for something, display that as + // an empty string + return ''; + } return PhutilTranslator::getInstance()->translateDate($format, $date); } -- 2.51.2