1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-11 07:11:04 +01:00

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
This commit is contained in:
epriestley 2016-04-11 07:31:28 -07:00
parent 146fb646f9
commit 5cf09f567a

View file

@ -84,20 +84,14 @@ final class AphrontFormDateControlValue extends Phobject {
$value = new AphrontFormDateControlValue();
$value->viewer = $request->getViewer();
$datetime = $request->getStr($key);
if (strlen($datetime)) {
$date = $datetime;
$time = null;
} else {
$date = $request->getStr($key.'_d');
$time = $request->getStr($key.'_t');
}
$date = $request->getStr($key.'_d');
$time = $request->getStr($key.'_t');
// If this looks like an epoch timestamp, prefix it with "@" so that
// DateTime() reads it as one. Assume small numbers are a "Ymd" digit
// string instead of an epoch timestamp for a time in 1970.
if (ctype_digit($date) && ($date > 30000000)) {
$date = '@'.$date;
// If we have the individual parts, we read them preferentially. If we do
// not, try to read the key as a raw value. This makes it so that HTTP
// prefilling is overwritten by the control value if the user changes it.
if (!strlen($date) && !strlen($time)) {
$date = $request->getStr($key);
$time = null;
}
@ -239,16 +233,19 @@ final class AphrontFormDateControlValue extends Phobject {
private function newDateTime($date, $time) {
$date = $this->getStandardDateFormat($date);
$time = $this->getStandardTimeFormat($time);
try {
$datetime = new DateTime("{$date} {$time}");
// We need to provide the timezone in the constructor, and also set it
// explicitly. If the date is an epoch timestamp, the timezone in the
// constructor is ignored. If the date is not an epoch timestamp, it is
// used to parse the date.
$zone = $this->getTimezone();
$datetime = new DateTime("{$date} {$time}", $zone);
$datetime->setTimezone($zone);
} catch (Exception $ex) {
return null;
}
// Set the timezone explicitly because it is ignored in the constructor
// if the date is an epoch timestamp.
$zone = $this->getTimezone();
$datetime->setTimezone($zone);
return $datetime;
}
@ -312,6 +309,13 @@ final class AphrontFormDateControlValue extends Phobject {
return $colloquial[$normalized];
}
// If this looks like an epoch timestamp, prefix it with "@" so that
// DateTime() reads it as one. Assume small numbers are a "Ymd" digit
// string instead of an epoch timestamp for a time in 1970.
if (ctype_digit($date) && ($date > 30000000)) {
$date = '@'.$date;
}
$separator = $this->getFormatSeparator();
$parts = preg_split('@[,./:-]@', $date);
return implode($separator, $parts);