Generate file attachment transactions for explicit Remarkup attachments on common...
[phabricator.git] / src / view / viewutils.php
blob956f6ca2c2326b58fbf44a2bd89ebac1af26e006
1 <?php
3 function phabricator_date($epoch, PhabricatorUser $user) {
4 return phabricator_format_local_time(
5 $epoch,
6 $user,
7 phutil_date_format($epoch));
10 function phabricator_relative_date($epoch, $user, $on = false) {
11 static $today;
12 static $yesterday;
14 if (!$today || !$yesterday) {
15 $now = time();
16 $today = phabricator_date($now, $user);
17 $yesterday = phabricator_date($now - 86400, $user);
20 $date = phabricator_date($epoch, $user);
22 if ($date === $today) {
23 return 'today';
26 if ($date === $yesterday) {
27 return 'yesterday';
30 return (($on ? 'on ' : '').$date);
33 function phabricator_time($epoch, $user) {
34 $time_key = PhabricatorTimeFormatSetting::SETTINGKEY;
35 return phabricator_format_local_time(
36 $epoch,
37 $user,
38 $user->getUserSetting($time_key));
41 function phabricator_dual_datetime($epoch, $user) {
42 $screen_view = phabricator_datetime($epoch, $user);
43 $print_view = phabricator_absolute_datetime($epoch, $user);
45 $screen_tag = javelin_tag(
46 'span',
47 array(
48 'print' => false,
50 $screen_view);
52 $print_tag = javelin_tag(
53 'span',
54 array(
55 'print' => true,
57 $print_view);
59 return array(
60 $screen_tag,
61 $print_tag,
65 function phabricator_absolute_datetime($epoch, $user) {
66 $format = 'Y-m-d H:i:s (\\U\\T\\CP)';
68 $datetime = phabricator_format_local_time($epoch, $user, $format);
69 $datetime = preg_replace('/(UTC[+-])0?([^:]+)(:00)?/', '\\1\\2', $datetime);
71 return $datetime;
74 function 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)));
84 function phabricator_datetimezone($epoch, $user) {
85 $datetime = phabricator_datetime($epoch, $user);
86 $timezone = phabricator_format_local_time($epoch, $user, 'T');
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);
99 return pht('%s (%s)', $datetime, $timezone);
103 * This function does not usually need to be called directly. Instead, call
104 * @{function:phabricator_date}, @{function:phabricator_time}, or
105 * @{function:phabricator_datetime}.
107 * @param int Unix epoch timestamp.
108 * @param PhabricatorUser User viewing the timestamp.
109 * @param string Date format, as per DateTime class.
110 * @return string Formatted, local date/time.
112 function phabricator_format_local_time($epoch, $user, $format) {
113 if (!$epoch) {
114 // If we're missing date information for something, the DateTime class will
115 // throw an exception when we try to construct an object. Since this is a
116 // display function, just return an empty string.
117 return '';
120 $user_zone = $user->getTimezoneIdentifier();
122 static $zones = array();
123 if (empty($zones[$user_zone])) {
124 $zones[$user_zone] = new DateTimeZone($user_zone);
126 $zone = $zones[$user_zone];
128 // NOTE: Although DateTime takes a second DateTimeZone parameter to its
129 // constructor, it ignores it if the date string includes timezone
130 // information. Further, it treats epoch timestamps ("@946684800") as having
131 // a UTC timezone. Set the timezone explicitly after constructing the object.
132 try {
133 $date = new DateTime('@'.$epoch);
134 } catch (Exception $ex) {
135 // NOTE: DateTime throws an empty exception if the format is invalid,
136 // just replace it with a useful one.
137 throw new Exception(
138 pht("Construction of a DateTime() with epoch '%s' ".
139 "raised an exception.", $epoch));
142 $date->setTimezone($zone);
144 return PhutilTranslator::getInstance()->translateDate($format, $date);