[FIX] web: don't apply timezone offset for date fields
Before this rev., all date fields values were off by one day as soon as the user timezone was negative. With the new views, all dates manipulated by the JS are moment instances in UTC, and when being displayed, they are correctly formatted in the user locale by applying the timezone offset. However, this should obviously not be done for date fields as when no time is specified when creating a moment instance, it defaults to 00:00:00, so applying a negative offset always leads to the day before. Remark: It happens that datetime fields are displayed as a date (e.g. purchase order line form view). In that case, the offset is applied on the displayed date.
This commit is contained in:
committed by
Aaron Bohy
parent
88dfcfd025
commit
b9bfec96dd
@@ -46,7 +46,7 @@ var ShowPaymentLineWidget = AbstractField.extend({
|
||||
k.index = v;
|
||||
k.amount = field_utils.format.float(k.amount, {digits: k.digits});
|
||||
if (k.date){
|
||||
k.date = field_utils.format.date(field_utils.parse.date(k.date, {isUTC: true}));
|
||||
k.date = field_utils.format.date(field_utils.parse.date(k.date, {}, {isUTC: true}));
|
||||
}
|
||||
});
|
||||
this.$el.html(QWeb.render('ShowPaymentInfo', {
|
||||
|
||||
@@ -95,8 +95,10 @@ function formatDate(value, field, options) {
|
||||
if (value === false) {
|
||||
return "";
|
||||
}
|
||||
if (!options || !('timezone' in options) || options.timezone) {
|
||||
value = value.clone().add(session.tzOffset < 0 ? -1 : 0, 'days');
|
||||
if (field && field.type === 'datetime') {
|
||||
if (!options || !('timezone' in options) || options.timezone) {
|
||||
value = value.clone().add(session.tzOffset, 'minutes');
|
||||
}
|
||||
}
|
||||
var l10n = core._t.database.parameters;
|
||||
var date_format = time.strftime_to_moment_format(l10n.date_format);
|
||||
@@ -357,11 +359,8 @@ function parseDate(value, field, options) {
|
||||
date = moment.utc(value);
|
||||
} else {
|
||||
date = moment.utc(value, [datePattern, datePatternWoZero, moment.ISO_8601], true);
|
||||
if (options && options.timezone) {
|
||||
date.add(session.tzOffset > 0 ? -1 : 0, 'days');
|
||||
}
|
||||
}
|
||||
if (date.isValid() && date.year() >= 1900) {
|
||||
if (date.isValid()) {
|
||||
if (date.year() === 0) {
|
||||
date.year(moment.utc().year());
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ var FieldTimezoneMismatch = FieldSelection.extend({
|
||||
}
|
||||
var offset = this.recordData.tz_offset.match(/([+-])([0-9]{2})([0-9]{2})/);
|
||||
offset = (offset[1] === '-' ? -1 : 1) * (parseInt(offset[2])*60 + parseInt(offset[3]));
|
||||
var datetime = field_utils.format.datetime(moment.utc().add(offset, 'minutes'), {timezone: false});
|
||||
var datetime = field_utils.format.datetime(moment.utc().add(offset, 'minutes'), this.field, {timezone: false});
|
||||
var content = this.$option.html().split(' ')[0];
|
||||
content += ' ('+ datetime + ')';
|
||||
this.$option.html(content);
|
||||
|
||||
@@ -1570,7 +1570,7 @@ QUnit.module('basic_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('date field in form view', function (assert) {
|
||||
QUnit.test('date field in form view (with positive time zone offset)', function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
var form = createView({
|
||||
@@ -1589,7 +1589,7 @@ QUnit.module('basic_fields', {
|
||||
date_format: '%m/%d/%Y',
|
||||
},
|
||||
session: {
|
||||
tzOffset: 120
|
||||
tzOffset: 120 // Should be ignored by date fields
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1621,6 +1621,34 @@ QUnit.module('basic_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('date field in form view (with negative time zone offset)', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch:'<form string="Partners"><field name="date"/></form>',
|
||||
res_id: 1,
|
||||
translateParameters: { // Avoid issues due to localization formats
|
||||
date_format: '%m/%d/%Y',
|
||||
},
|
||||
session: {
|
||||
tzOffset: -120 // Should be ignored by date fields
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_field_date').text(), '02/03/2017',
|
||||
'the date should be correctly displayed in readonly');
|
||||
|
||||
// switch to edit mode
|
||||
form.$buttons.find('.o_form_button_edit').click();
|
||||
assert.strictEqual(form.$('.o_datepicker_input').val(), '02/03/2017',
|
||||
'the date should be correct in edit mode');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('date field in editable list view', function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
@@ -1870,6 +1898,89 @@ QUnit.module('basic_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('datetime field with date/datetime widget (with day change)', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
this.data.partner.records[0].p = [2];
|
||||
this.data.partner.records[1].datetime = "2017-02-08 02:00:00"; // UTC
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch:'<form string="Partners">' +
|
||||
'<field name="p">' +
|
||||
'<tree>' +
|
||||
'<field name="datetime"/>' +
|
||||
'</tree>' +
|
||||
'<form>' +
|
||||
'<field name="datetime" widget="date"/>' +
|
||||
'</form>' +
|
||||
'</field>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
translateParameters: { // Avoid issues due to localization formats
|
||||
date_format: '%m/%d/%Y',
|
||||
time_format: '%H:%M:%S',
|
||||
},
|
||||
session: {
|
||||
tzOffset: -240,
|
||||
},
|
||||
});
|
||||
|
||||
var expectedDateString = "02/07/2017 22:00:00"; // local time zone
|
||||
assert.strictEqual(form.$('.o_field_widget[name=p] .o_data_cell').text(), expectedDateString,
|
||||
'the datetime (datetime widget) should be correctly displayed in tree view');
|
||||
|
||||
// switch to form view
|
||||
form.$('.o_field_widget[name=p] .o_data_row').click();
|
||||
assert.strictEqual($('.modal .o_field_date[name=datetime]').text(), '02/07/2017',
|
||||
'the datetime (date widget) should be correctly displayed in form view');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('datetime field with date/datetime widget (without day change)', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
this.data.partner.records[0].p = [2];
|
||||
this.data.partner.records[1].datetime = "2017-02-08 10:00:00"; // without timezone
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch:'<form string="Partners">' +
|
||||
'<field name="p">' +
|
||||
'<tree>' +
|
||||
'<field name="datetime"/>' +
|
||||
'</tree>' +
|
||||
'<form>' +
|
||||
'<field name="datetime" widget="date"/>' +
|
||||
'</form>' +
|
||||
'</field>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
translateParameters: { // Avoid issues due to localization formats
|
||||
date_format: '%m/%d/%Y',
|
||||
time_format: '%H:%M:%S',
|
||||
},
|
||||
session: {
|
||||
tzOffset: -240,
|
||||
},
|
||||
});
|
||||
|
||||
var expectedDateString = "02/08/2017 06:00:00"; // with timezone
|
||||
assert.strictEqual(form.$('.o_field_widget[name=p] .o_data_cell').text(), expectedDateString,
|
||||
'the datetime (datetime widget) should be correctly displayed in tree view');
|
||||
|
||||
// switch to form view
|
||||
form.$('.o_field_widget[name=p] .o_data_row').click();
|
||||
assert.strictEqual($('.modal .o_field_date[name=datetime]').text(), '02/08/2017',
|
||||
'the datetime (date widget) should be correctly displayed in form view');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('FieldMonetary');
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ QUnit.test("format_datetime", function (assert) {
|
||||
|
||||
var date_string = "2009-05-04 12:34:23";
|
||||
var date = fieldUtils.parse.datetime(date_string, {}, {timezone: false});
|
||||
var str = fieldUtils.format.datetime(date, {timezone: false});
|
||||
var str = fieldUtils.format.datetime(date, {}, {timezone: false});
|
||||
assert.strictEqual(str, moment(date).format("MM/DD/YYYY HH:mm:ss"));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user