forked from extern/egroupware
Another attempt at resolving the browser timezone issue
This commit is contained in:
parent
e4a80cbfc6
commit
ec1471c6d2
@ -30,9 +30,10 @@
|
||||
*
|
||||
* @todo validation of date-duration
|
||||
*
|
||||
* @info beforeSendToClient is no longer neccessary, in order to handle date/time conversion, for this widget
|
||||
* as we are handling both timestamp and string date/time formats on client side
|
||||
*
|
||||
* @info Communication between client and server is always done as a string in ISO8601/W3C
|
||||
* format ("Y-m-d\TH:i:sP"). If the application specifies a different format
|
||||
* for the field, the conversion is done as needed understand what the application
|
||||
* sends, and to give the application what it wants when the form is submitted.
|
||||
*/
|
||||
class etemplate_widget_date extends etemplate_widget_transformer
|
||||
{
|
||||
@ -48,9 +49,48 @@ class etemplate_widget_date extends etemplate_widget_transformer
|
||||
protected $legacy_options = 'dataformat,mode';
|
||||
|
||||
|
||||
/**
|
||||
* Convert the provided date into the format needed for unambiguous communication
|
||||
* with browsers (Javascript). We use W3C format to avoid timestamp issues.
|
||||
*/
|
||||
public function beforeSendToClient($cname)
|
||||
{
|
||||
if($this->type == 'date-houronly')
|
||||
{
|
||||
return parent::beforeSendToClient($cname);
|
||||
}
|
||||
|
||||
$form_name = self::form_name($cname, $this->id);
|
||||
$value =& self::get_array(self::$request->content, $form_name, false, true);
|
||||
|
||||
if($this->type != 'date-duration' && $value)
|
||||
{
|
||||
// string with formatting letters like for php's date() method
|
||||
if ($this->attrs['dataformat'] && !is_numeric($value))
|
||||
{
|
||||
$date = date_create_from_format($this->attrs['dataformat'], $value, new DateTimeZone('UTC'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$date = new egw_time((int)$value, new DateTimeZone('UTC'));
|
||||
}
|
||||
if($date)
|
||||
{
|
||||
// Set timezone to UTC so javascript doesn't add/subtract anything
|
||||
$date->setTimezone(new DateTimeZone('UTC'));
|
||||
$value = $date->format(egw_time::W3C);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate input
|
||||
*
|
||||
* For dates (except duration), it is always a full timestamp in W3C format,
|
||||
* which we then convert to the format the application is expecting. This can
|
||||
* be either a unix timestamp, just a date, just time, or whatever is
|
||||
* specified in the template.
|
||||
*
|
||||
* @param string $cname current namespace
|
||||
* @param array $expand values for keys 'c', 'row', 'c_', 'row_', 'cont'
|
||||
* @param array $content
|
||||
@ -65,13 +105,7 @@ class etemplate_widget_date extends etemplate_widget_transformer
|
||||
{
|
||||
$value = self::get_array($content, $form_name);
|
||||
$valid =& self::get_array($validated, $form_name, true);
|
||||
|
||||
// Client / etemplate always deals in 'user time', which has no timezone
|
||||
// The change to server time is handled elsewhere
|
||||
// Change to UTC to avoid PHP doing automatic timezone math
|
||||
$default_tz = date_default_timezone_get();
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
|
||||
if ((string)$value === '' && $this->attrs['needed'])
|
||||
{
|
||||
self::set_validation_error($form_name,lang('Field must not be empty !!!'));
|
||||
@ -84,12 +118,21 @@ class etemplate_widget_date extends etemplate_widget_transformer
|
||||
{
|
||||
$valid = (string)$value === '' ? '' : (int)$value;
|
||||
}
|
||||
if($value)
|
||||
{
|
||||
$date = new egw_time($value);
|
||||
}
|
||||
if(!$value)
|
||||
{
|
||||
// Not null, blank
|
||||
$value = '';
|
||||
}
|
||||
elseif (empty($this->attrs['dataformat'])) // integer timestamp
|
||||
{
|
||||
$valid = (int)$value;
|
||||
$valid = $date->format('ts');
|
||||
}
|
||||
// string with formatting letters like for php's date() method
|
||||
elseif (($valid = date($this->attrs['dataformat'], $value)))
|
||||
elseif (($valid = $date->format($this->attrs['dataformat'])))
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
@ -98,8 +141,7 @@ class etemplate_widget_date extends etemplate_widget_transformer
|
||||
// this is not really a user error, but one of the clientside engine
|
||||
self::set_validation_error($form_name,lang("'%1' is not a valid date !!!", $value).' '.$this->dataformat);
|
||||
}
|
||||
|
||||
date_default_timezone_set($default_tz);
|
||||
//error_log("$this : ($valid)" . egw_time::to($valid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,8 @@
|
||||
/**
|
||||
* Class which implements the "date" XET-Tag
|
||||
*
|
||||
* Care must be taken anytime a date from the user is parsed. eTemplate client
|
||||
* side dates are all in 'user time', which is dealt with on the server and has
|
||||
* no timezone. Javascript uses the browser's timezone, which affects parsing
|
||||
* and calculations.
|
||||
* Dates are passed to the server in ISO8601 format ("Y-m-d\TH:i:sP"), and data_format is
|
||||
* handled server-side.
|
||||
*
|
||||
* @augments et2_inputWidget
|
||||
*/
|
||||
@ -40,7 +38,7 @@ var et2_date = et2_inputWidget.extend(
|
||||
"ignore": false
|
||||
},
|
||||
"data_format": {
|
||||
"ignore": false,
|
||||
"ignore": true,
|
||||
"description": "Date/Time format. Can be set as an options to date widget",
|
||||
"default": ''
|
||||
}
|
||||
@ -57,7 +55,7 @@ var et2_date = et2_inputWidget.extend(
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.date = new Date();
|
||||
this.date.setHours(0);
|
||||
this.date.setUTCHours(0);
|
||||
this.date.setMinutes(0);
|
||||
this.date.setSeconds(0);
|
||||
this.input = null;
|
||||
@ -126,6 +124,11 @@ var et2_date = et2_inputWidget.extend(
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for full timestamp
|
||||
if(typeof _value == 'string' && _value.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})[+-](\d{2})\:(\d{2})/))
|
||||
{
|
||||
_value = new Date(_value);
|
||||
}
|
||||
// Handle just time as a string in the form H:i
|
||||
if(typeof _value == 'string' && isNaN(_value))
|
||||
{
|
||||
@ -163,7 +166,7 @@ var et2_date = et2_inputWidget.extend(
|
||||
this.change(this.input_date);
|
||||
}
|
||||
}
|
||||
this._oldValue = _value;
|
||||
this._oldValue = this.date.toJSON();
|
||||
return;
|
||||
default:
|
||||
// Parse customfields's date with storage data_format to date object
|
||||
@ -189,11 +192,13 @@ var et2_date = et2_inputWidget.extend(
|
||||
this.set_validation_error(this.egw().lang("%1' han an invalid format !!!",_value));
|
||||
return;
|
||||
}
|
||||
// These should be the same, but this should clear any offset problems
|
||||
parsed.setUTCHours(parsed.getHours());
|
||||
}
|
||||
// Update local variable, but remove the timezone offset that javascript adds
|
||||
// Update local variable, but remove the timezone offset that javascript adds by using timestamp
|
||||
if(parsed)
|
||||
{
|
||||
this.date = new Date(parsed.valueOf() - (parsed.getTimezoneOffset()*60*1000));
|
||||
this.date = new Date(parsed.valueOf());
|
||||
}
|
||||
|
||||
this.set_validation_error(false);
|
||||
@ -210,11 +215,11 @@ var et2_date = et2_inputWidget.extend(
|
||||
|
||||
// Update input - popups do, but framework doesn't
|
||||
_value = '';
|
||||
var formatDate = new Date(this.date.valueOf() + this.date.getTimezoneOffset() * 60 * 1000);
|
||||
if(this._type != 'date-timeonly')
|
||||
{
|
||||
_value = jQuery.datepicker.formatDate(this.input_date.datepicker("option","dateFormat"),
|
||||
// Add timezone offset for datepicker format, or it will lose that many hours
|
||||
new Date(this.date.valueOf() + (this.date.getTimezoneOffset()*60*1000))
|
||||
formatDate
|
||||
);
|
||||
}
|
||||
if(this._type != 'date')
|
||||
@ -222,7 +227,7 @@ var et2_date = et2_inputWidget.extend(
|
||||
if(this._type != 'date-timeonly') _value += ' ';
|
||||
|
||||
_value += jQuery.datepicker.formatTime(this.input_date.datepicker("option","timeFormat"),{
|
||||
hour: this.date.getHours(),
|
||||
hour: this.date.getUTCHours(),
|
||||
minute: this.date.getMinutes(),
|
||||
seconds: 0,
|
||||
timezone: 0
|
||||
@ -249,10 +254,15 @@ var et2_date = et2_inputWidget.extend(
|
||||
this.date.setMonth(0);
|
||||
this.date.setFullYear(1970);
|
||||
}
|
||||
else if (this._type == 'date')
|
||||
{
|
||||
this.date.setUTCHours(0);
|
||||
this.date.setUTCMinutes(0);
|
||||
}
|
||||
|
||||
// Convert to timestamp - no seconds
|
||||
this.date.setSeconds(0,0);
|
||||
return Math.round(this.date.valueOf() / 1000);
|
||||
return this.date.toJSON();
|
||||
}
|
||||
});
|
||||
et2_register_widget(et2_date, ["date", "date-time", "date-timeonly"]);
|
||||
|
Loading…
Reference in New Issue
Block a user