@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix an issue with date parsing when viewer timezone differs from server timezone

Summary:
The way `DateTime` works with epochs is weird, I goofed this by having my server/viewer timezone the same and not noticing.

Also fix an issue where you do `?epoch=...` and then manually fiddle with the control: the control should win.

Test Plan:
- Set viewer and server timezone to different vlaues.
- Created a countdown using `?epoch=...`.
- Created a countdown using `?epoch=...` and fiddling with date controls.
- Created and edited a countdown using date/time control.
- Poked around Calendar to make sure I didn't ruin anything this time (browsed, created event, edited event).

Reviewers: lpriestley, chad

Reviewed By: chad

Differential Revision: https://secure.phabricator.com/D15680

+22 -18
+22 -18
src/view/form/control/AphrontFormDateControlValue.php
··· 84 84 $value = new AphrontFormDateControlValue(); 85 85 $value->viewer = $request->getViewer(); 86 86 87 - $datetime = $request->getStr($key); 88 - if (strlen($datetime)) { 89 - $date = $datetime; 90 - $time = null; 91 - } else { 92 - $date = $request->getStr($key.'_d'); 93 - $time = $request->getStr($key.'_t'); 94 - } 87 + $date = $request->getStr($key.'_d'); 88 + $time = $request->getStr($key.'_t'); 95 89 96 - // If this looks like an epoch timestamp, prefix it with "@" so that 97 - // DateTime() reads it as one. Assume small numbers are a "Ymd" digit 98 - // string instead of an epoch timestamp for a time in 1970. 99 - if (ctype_digit($date) && ($date > 30000000)) { 100 - $date = '@'.$date; 90 + // If we have the individual parts, we read them preferentially. If we do 91 + // not, try to read the key as a raw value. This makes it so that HTTP 92 + // prefilling is overwritten by the control value if the user changes it. 93 + if (!strlen($date) && !strlen($time)) { 94 + $date = $request->getStr($key); 101 95 $time = null; 102 96 } 103 97 ··· 239 233 private function newDateTime($date, $time) { 240 234 $date = $this->getStandardDateFormat($date); 241 235 $time = $this->getStandardTimeFormat($time); 236 + 242 237 try { 243 - $datetime = new DateTime("{$date} {$time}"); 238 + // We need to provide the timezone in the constructor, and also set it 239 + // explicitly. If the date is an epoch timestamp, the timezone in the 240 + // constructor is ignored. If the date is not an epoch timestamp, it is 241 + // used to parse the date. 242 + $zone = $this->getTimezone(); 243 + $datetime = new DateTime("{$date} {$time}", $zone); 244 + $datetime->setTimezone($zone); 244 245 } catch (Exception $ex) { 245 246 return null; 246 247 } 247 248 248 - // Set the timezone explicitly because it is ignored in the constructor 249 - // if the date is an epoch timestamp. 250 - $zone = $this->getTimezone(); 251 - $datetime->setTimezone($zone); 252 249 253 250 return $datetime; 254 251 } ··· 310 307 311 308 if (isset($colloquial[$normalized])) { 312 309 return $colloquial[$normalized]; 310 + } 311 + 312 + // If this looks like an epoch timestamp, prefix it with "@" so that 313 + // DateTime() reads it as one. Assume small numbers are a "Ymd" digit 314 + // string instead of an epoch timestamp for a time in 1970. 315 + if (ctype_digit($date) && ($date > 30000000)) { 316 + $date = '@'.$date; 313 317 } 314 318 315 319 $separator = $this->getFormatSeparator();