ExtJS:如何在自定义 DateTimeField 中使用 UTC 时间
ExtJS: How to utilize UTC time in custom DateTimeField
我正在尝试将 UTC 时间戳转换为 UTC 日期,修改这些日期,并 return selected date/time 的 UTC 时间戳。由于 Ext.form.field.Date
和 Ext.form.field.Time
字段在内部使用本地时间,我必须将时间增加 5 小时并确保日期保持不变,要检索时间戳,我必须反转过程并获得ISO 时间戳(不含毫秒)。
一切似乎都正常,但是当我 select 2015-01-01T01:15:00Z
日期字段设置为第二天时(01/02/2015
;参见 图 #1).我不确定我在哪里没有正确转换日期?
图 #1: 日期设置为第二天。
编辑
经过一番调整后,我的日期似乎是正确的,但现在时间字段出现问题(参见 图 #2)。看起来设置的值已从时间下拉列表中删除。这非常令人困惑。
setValue: function (value) {
// ...
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(me.convertFromUTC(timeDate));
}
// ...
}
图 #2: 时间字段验证失败。
您可以在以下站点访问以下代码的演示:
DateTime.components.DateTimeField
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
ignoreOnSubmit: true,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
minValue: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80,
ignoreOnSubmit: true
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideData) {
me.lookupReference('dateField').hide();
}
me.callParent();
},
getValue: function () {
var me = this,
dateValue = me.getDate(),
timeValue = me.getTime();
if (dateValue != null && timeValue != null) {
dateValue = Ext.Date.add(dateValue, Ext.Date.MILLI, timeValue);
}
return this.convertToUTC(dateValue);
},
setValue: function (value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
// Debug
console.log('Parsed Date: ' + value);
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
timeDate = me.convertFromUTC(timeDate);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(timeDate);
}
},
getInputId: function () {
return null;
},
getTime: function () {
var me = this,
timeValue = me.lookupReference('timeField').getValue();
timeValue.setFullYear(1970, 0, 1);
timeValue = this.convertToUTC(timeValue, this.getDate());
return timeValue.getTime();
},
getDate: function () {
return this.lookupReference('dateField').getValue();
},
setDate: function (value) {
this.lookupReference('dateField').setValue(value);
},
convertToUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.subtract(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
},
convertFromUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.add(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
}
});
完整代码
//////////////////////////////////////////////////////////
// Requires
//////////////////////////////////////////////////////////
Ext.require(['*']);
//////////////////////////////////////////////////////////
// Data
//////////////////////////////////////////////////////////
var timestampData = [
['2014-02-28T08:45:00Z'],
['2015-01-01T01:15:00Z'],
['2014-12-31T11:30:00Z']
];
//////////////////////////////////////////////////////////
// Models
//////////////////////////////////////////////////////////
Ext.define('DateTime.model.Timestamp', {
extend: 'Ext.data.Model',
fields: ['timestamp']
});
//////////////////////////////////////////////////////////
// Stores
//////////////////////////////////////////////////////////
Ext.define('DateTime.store.Timestamp', {
extend : 'Ext.data.ArrayStore',
model: 'DateTime.model.Timestamp',
autoLoad: true,
autoSync: true,
proxy: {
type: 'memory'
}
});
//////////////////////////////////////////////////////////
// Mixins
//////////////////////////////////////////////////////////
Ext.define('DateTime.mixin.CommonUtils', {
dateToISOString: function (date) {
var pad = function (number) {
return ('00' + number).slice(-2);
};
return date.getUTCFullYear() + '-'
+ pad(date.getUTCMonth() + 1) + '-'
+ pad(date.getUTCDate()) + 'T'
+ pad(date.getUTCHours()) + ':'
+ pad(date.getUTCMinutes()) + ':'
+ pad(date.getUTCSeconds()) + 'Z';
}
});
//////////////////////////////////////////////////////////
// Components
//////////////////////////////////////////////////////////
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
ignoreOnSubmit: true,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
minValue: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80,
ignoreOnSubmit: true
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideData) {
me.lookupReference('dateField').hide();
}
me.callParent();
},
getValue: function () {
var me = this,
dateValue = me.getDate(),
timeValue = me.getTime();
if (dateValue != null && timeValue != null) {
dateValue = Ext.Date.add(dateValue, Ext.Date.MILLI, timeValue);
}
return this.convertToUTC(dateValue);
},
setValue: function (value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
// Debug
console.log('Parsed Date: ' + value);
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
timeDate = me.convertFromUTC(timeDate);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(timeDate);
}
},
getInputId: function () {
return null;
},
getTime: function () {
var me = this,
timeValue = me.lookupReference('timeField').getValue();
timeValue.setFullYear(1970, 0, 1);
timeValue = this.convertToUTC(timeValue, this.getDate());
return timeValue.getTime();
},
getDate: function () {
return this.lookupReference('dateField').getValue();
},
setDate: function (value) {
this.lookupReference('dateField').setValue(value);
},
convertToUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.subtract(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
},
convertFromUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.add(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
}
});
//////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////
Ext.define('DateTime.view.MainView', {
extend: 'Ext.panel.Panel',
xtype: 'mainView',
alias: 'widget.mainview',
mixins: {
utils: 'DateTime.mixin.CommonUtils'
},
title: 'Date-Time Field Example',
referenceHolder: true,
layout: {
type: 'border',
//padding: 5
},
initComponent: function () {
var me = this;
me.items = [{
region: 'north',
xtype: 'grid',
itemId: 'timestampList',
store: Ext.create('DateTime.store.Timestamp', {
data : timestampData
}),
cls: 'timestamp-list',
multiSelect: false,
hideHeaders : true,
viewConfig: {
emptyText: 'No images to display'
},
columns: [{
dataIndex: 'timestamp',
text: 'Timestamp',
flex: 1
}]
}, {
region: 'center',
xtype: 'panel',
layout: {
type: 'vbox'
},
bodyPadding: 8,
items: [{
xtype: 'container',
layout: 'hbox',
margin: '8 0 0 0',
items: [{
xtype: 'textfield',
reference: 'txtTimestampIn',
fieldLabel: 'Timestamp In'
}, {
xtype: 'button',
itemId: 'btnSetTime',
text: 'Set Time',
margin: '0 0 0 12'
}]
}, {
xtype: 'container',
layout: 'hbox',
margin: '8 0 0 0',
items: [{
xtype: 'datetimefield',
name: 'startDate',
itemId: 'startDate',
reference: 'startDate',
dateConfig: {
fieldLabel: 'Start'
},
listeners: {
afterrender: {
fn: me.dateTimeField_onComplete,
scope: me
}
}
}, {
xtype: 'button',
itemId: 'btnExportTime',
text: 'Get Time',
margin: '0 0 0 12'
}]
}, {
xtype: 'textfield',
reference: 'txtTimestampOut',
fieldLabel: 'Timestamp Out',
margin: '8 0 0 0'
}]
}],
me.callParent();
},
dateTimeField_onComplete: function (field, eOpts) {
var me = this,
timestamp = timestampData[0][0];
field.setValue(timestamp);
}
});
////////////////////////////////////////////////////////////
// Controllers
////////////////////////////////////////////////////////////
Ext.define('DateTime.controller.MainController', {
extend: 'Ext.app.Controller',
views: ['DateTime.view.MainView'],
mixins: {
utils: 'DateTime.mixin.CommonUtils'
},
refs: [{
ref: 'mainView',
selector: 'mainView'
}],
init: function () {
var me = this;
me.control({
'#startDate': {
dateFieldChange: me.handleDateChange
},
'#btnSetTime': {
click: me.handleSetTime
},
'#btnExportTime': {
click: me.handleExportTime
},
'#timestampList' : {
selectionchange: me.handleChangeTimestamp
}
});
},
handleDateChange: function (field, newValue, oldValue) {
// Do nothing...
},
handleSetTime: function (button, e, eOpts) {
var me = this,
view = me.getMainView(),
timestampIn = view.lookupReference('txtTimestampIn');
view.lookupReference('startDate').setValue(timestampIn.getValue());
me.handleExportTime();
},
handleExportTime: function (button, e, eOpts) {
var me = this,
toISOStr = me.mixins.utils.dateToISOString,
view = me.getMainView(),
timestampIn = view.lookupReference('txtTimestampOut');
timestampIn.setValue(toISOStr(view.lookupReference('startDate').getValue()));
},
handleChangeTimestamp: function(grid, selected, eOpts) {
var me = this,
view = me.getMainView(),
timestamp = selected[0].data.timestamp;
view.lookupReference('txtTimestampIn').setValue(timestamp);
me.handleSetTime();
}
});
//////////////////////////////////////////////////////////
// Applications
//////////////////////////////////////////////////////////
Ext.define('DateTime.app.DateTimeApp', {
extend: 'Ext.app.Application',
name: 'DateTimeApp',
controllers: ['DateTime.controller.MainController'],
launch: function () {
Ext.create('Ext.Viewport', {
layout: 'fit',
flex: 1,
items: [{
xtype: 'mainview'
}]
});
}
});
//////////////////////////////////////////////////////////
// Startup
//////////////////////////////////////////////////////////
Ext.onReady(function () {
Ext.application('DateTime.app.DateTimeApp');
});
看来我想通了,虽然还有一个问题。选择的时间没有出现在下拉列表中......它只是没有出现这很奇怪。如果有人有任何建议,请在下方发表评论,或添加您自己的答案。
无论如何,如果有人需要 UTC 日期时间字段,就在这里。我清理了一下。我完全重构了问题中的代码,因此时区信息无关紧要。日期明确地从 UTC 转换为本地时间,反之亦然。这样就不用计算了。
Ext.ux.form.field.DateTimeField
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideDate) {
me.getDateField().hide();
}
me.callParent();
},
getValue: function () {
var me = this;
var dateTime = me.combineDateTime(me.getDate(), me.getTime());
if (me.utcValue) {
return me.localToUtc(dateTime);
}
return dateTime;
},
setValue: function(value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
if (me.utcValue) {
timeDate = this.utcToLocal(timeDate);
}
me.setDate(timeDate);
me.setTime(timeDate);
}
},
getTimeField : function() {
return this.lookupReference('timeField');
},
getDateField : function() {
return this.lookupReference('dateField');
},
getTime: function() {
return this.getTimeField().getValue();
},
setTime: function(value) {
this.getTimeField().setValue(value);
},
getDate: function() {
return this.getDateField().getValue();
},
setDate: function(value) {
this.getDateField().setValue(value);
},
combineDateTime : function(date, time) {
var year = date.getFullYear();
var month = date.getMonth();
var day = date.getDate();
var hour = time.getHours();
var minute = time.getMinutes();
var second = time.getSeconds();
return new Date(year, month, day, hour, minute, second, 0);
},
utcToLocal : function(utcDate) {
var year = utcDate.getUTCFullYear();
var month = utcDate.getUTCMonth();
var day = utcDate.getUTCDate();
var hour = utcDate.getUTCHours();
var minute = utcDate.getUTCMinutes();
var second = utcDate.getUTCSeconds();
return new Date(year, month, day, hour, minute, second, 0);
},
localToUtc : function(localDate) {
var year = localDate.getFullYear();
var month = localDate.getMonth();
var day = localDate.getDate();
var hour = localDate.getHours();
var minute = localDate.getMinutes();
var second = localDate.getSeconds();
return new Date(Date.UTC(year, month, day, hour, minute, second, 0));
}
});
演示
我正在尝试将 UTC 时间戳转换为 UTC 日期,修改这些日期,并 return selected date/time 的 UTC 时间戳。由于 Ext.form.field.Date
和 Ext.form.field.Time
字段在内部使用本地时间,我必须将时间增加 5 小时并确保日期保持不变,要检索时间戳,我必须反转过程并获得ISO 时间戳(不含毫秒)。
一切似乎都正常,但是当我 select 2015-01-01T01:15:00Z
日期字段设置为第二天时(01/02/2015
;参见 图 #1).我不确定我在哪里没有正确转换日期?
图 #1: 日期设置为第二天。
编辑
经过一番调整后,我的日期似乎是正确的,但现在时间字段出现问题(参见 图 #2)。看起来设置的值已从时间下拉列表中删除。这非常令人困惑。
setValue: function (value) {
// ...
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(me.convertFromUTC(timeDate));
}
// ...
}
图 #2: 时间字段验证失败。
您可以在以下站点访问以下代码的演示:
DateTime.components.DateTimeField
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
ignoreOnSubmit: true,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
minValue: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80,
ignoreOnSubmit: true
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideData) {
me.lookupReference('dateField').hide();
}
me.callParent();
},
getValue: function () {
var me = this,
dateValue = me.getDate(),
timeValue = me.getTime();
if (dateValue != null && timeValue != null) {
dateValue = Ext.Date.add(dateValue, Ext.Date.MILLI, timeValue);
}
return this.convertToUTC(dateValue);
},
setValue: function (value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
// Debug
console.log('Parsed Date: ' + value);
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
timeDate = me.convertFromUTC(timeDate);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(timeDate);
}
},
getInputId: function () {
return null;
},
getTime: function () {
var me = this,
timeValue = me.lookupReference('timeField').getValue();
timeValue.setFullYear(1970, 0, 1);
timeValue = this.convertToUTC(timeValue, this.getDate());
return timeValue.getTime();
},
getDate: function () {
return this.lookupReference('dateField').getValue();
},
setDate: function (value) {
this.lookupReference('dateField').setValue(value);
},
convertToUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.subtract(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
},
convertFromUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.add(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
}
});
完整代码
//////////////////////////////////////////////////////////
// Requires
//////////////////////////////////////////////////////////
Ext.require(['*']);
//////////////////////////////////////////////////////////
// Data
//////////////////////////////////////////////////////////
var timestampData = [
['2014-02-28T08:45:00Z'],
['2015-01-01T01:15:00Z'],
['2014-12-31T11:30:00Z']
];
//////////////////////////////////////////////////////////
// Models
//////////////////////////////////////////////////////////
Ext.define('DateTime.model.Timestamp', {
extend: 'Ext.data.Model',
fields: ['timestamp']
});
//////////////////////////////////////////////////////////
// Stores
//////////////////////////////////////////////////////////
Ext.define('DateTime.store.Timestamp', {
extend : 'Ext.data.ArrayStore',
model: 'DateTime.model.Timestamp',
autoLoad: true,
autoSync: true,
proxy: {
type: 'memory'
}
});
//////////////////////////////////////////////////////////
// Mixins
//////////////////////////////////////////////////////////
Ext.define('DateTime.mixin.CommonUtils', {
dateToISOString: function (date) {
var pad = function (number) {
return ('00' + number).slice(-2);
};
return date.getUTCFullYear() + '-'
+ pad(date.getUTCMonth() + 1) + '-'
+ pad(date.getUTCDate()) + 'T'
+ pad(date.getUTCHours()) + ':'
+ pad(date.getUTCMinutes()) + ':'
+ pad(date.getUTCSeconds()) + 'Z';
}
});
//////////////////////////////////////////////////////////
// Components
//////////////////////////////////////////////////////////
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
ignoreOnSubmit: true,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
minValue: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80,
ignoreOnSubmit: true
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideData) {
me.lookupReference('dateField').hide();
}
me.callParent();
},
getValue: function () {
var me = this,
dateValue = me.getDate(),
timeValue = me.getTime();
if (dateValue != null && timeValue != null) {
dateValue = Ext.Date.add(dateValue, Ext.Date.MILLI, timeValue);
}
return this.convertToUTC(dateValue);
},
setValue: function (value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
// Debug
console.log('Parsed Date: ' + value);
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
timeDate = me.convertFromUTC(timeDate);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(timeDate);
}
},
getInputId: function () {
return null;
},
getTime: function () {
var me = this,
timeValue = me.lookupReference('timeField').getValue();
timeValue.setFullYear(1970, 0, 1);
timeValue = this.convertToUTC(timeValue, this.getDate());
return timeValue.getTime();
},
getDate: function () {
return this.lookupReference('dateField').getValue();
},
setDate: function (value) {
this.lookupReference('dateField').setValue(value);
},
convertToUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.subtract(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
},
convertFromUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.add(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
}
});
//////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////
Ext.define('DateTime.view.MainView', {
extend: 'Ext.panel.Panel',
xtype: 'mainView',
alias: 'widget.mainview',
mixins: {
utils: 'DateTime.mixin.CommonUtils'
},
title: 'Date-Time Field Example',
referenceHolder: true,
layout: {
type: 'border',
//padding: 5
},
initComponent: function () {
var me = this;
me.items = [{
region: 'north',
xtype: 'grid',
itemId: 'timestampList',
store: Ext.create('DateTime.store.Timestamp', {
data : timestampData
}),
cls: 'timestamp-list',
multiSelect: false,
hideHeaders : true,
viewConfig: {
emptyText: 'No images to display'
},
columns: [{
dataIndex: 'timestamp',
text: 'Timestamp',
flex: 1
}]
}, {
region: 'center',
xtype: 'panel',
layout: {
type: 'vbox'
},
bodyPadding: 8,
items: [{
xtype: 'container',
layout: 'hbox',
margin: '8 0 0 0',
items: [{
xtype: 'textfield',
reference: 'txtTimestampIn',
fieldLabel: 'Timestamp In'
}, {
xtype: 'button',
itemId: 'btnSetTime',
text: 'Set Time',
margin: '0 0 0 12'
}]
}, {
xtype: 'container',
layout: 'hbox',
margin: '8 0 0 0',
items: [{
xtype: 'datetimefield',
name: 'startDate',
itemId: 'startDate',
reference: 'startDate',
dateConfig: {
fieldLabel: 'Start'
},
listeners: {
afterrender: {
fn: me.dateTimeField_onComplete,
scope: me
}
}
}, {
xtype: 'button',
itemId: 'btnExportTime',
text: 'Get Time',
margin: '0 0 0 12'
}]
}, {
xtype: 'textfield',
reference: 'txtTimestampOut',
fieldLabel: 'Timestamp Out',
margin: '8 0 0 0'
}]
}],
me.callParent();
},
dateTimeField_onComplete: function (field, eOpts) {
var me = this,
timestamp = timestampData[0][0];
field.setValue(timestamp);
}
});
////////////////////////////////////////////////////////////
// Controllers
////////////////////////////////////////////////////////////
Ext.define('DateTime.controller.MainController', {
extend: 'Ext.app.Controller',
views: ['DateTime.view.MainView'],
mixins: {
utils: 'DateTime.mixin.CommonUtils'
},
refs: [{
ref: 'mainView',
selector: 'mainView'
}],
init: function () {
var me = this;
me.control({
'#startDate': {
dateFieldChange: me.handleDateChange
},
'#btnSetTime': {
click: me.handleSetTime
},
'#btnExportTime': {
click: me.handleExportTime
},
'#timestampList' : {
selectionchange: me.handleChangeTimestamp
}
});
},
handleDateChange: function (field, newValue, oldValue) {
// Do nothing...
},
handleSetTime: function (button, e, eOpts) {
var me = this,
view = me.getMainView(),
timestampIn = view.lookupReference('txtTimestampIn');
view.lookupReference('startDate').setValue(timestampIn.getValue());
me.handleExportTime();
},
handleExportTime: function (button, e, eOpts) {
var me = this,
toISOStr = me.mixins.utils.dateToISOString,
view = me.getMainView(),
timestampIn = view.lookupReference('txtTimestampOut');
timestampIn.setValue(toISOStr(view.lookupReference('startDate').getValue()));
},
handleChangeTimestamp: function(grid, selected, eOpts) {
var me = this,
view = me.getMainView(),
timestamp = selected[0].data.timestamp;
view.lookupReference('txtTimestampIn').setValue(timestamp);
me.handleSetTime();
}
});
//////////////////////////////////////////////////////////
// Applications
//////////////////////////////////////////////////////////
Ext.define('DateTime.app.DateTimeApp', {
extend: 'Ext.app.Application',
name: 'DateTimeApp',
controllers: ['DateTime.controller.MainController'],
launch: function () {
Ext.create('Ext.Viewport', {
layout: 'fit',
flex: 1,
items: [{
xtype: 'mainview'
}]
});
}
});
//////////////////////////////////////////////////////////
// Startup
//////////////////////////////////////////////////////////
Ext.onReady(function () {
Ext.application('DateTime.app.DateTimeApp');
});
看来我想通了,虽然还有一个问题。选择的时间没有出现在下拉列表中......它只是没有出现这很奇怪。如果有人有任何建议,请在下方发表评论,或添加您自己的答案。
无论如何,如果有人需要 UTC 日期时间字段,就在这里。我清理了一下。我完全重构了问题中的代码,因此时区信息无关紧要。日期明确地从 UTC 转换为本地时间,反之亦然。这样就不用计算了。
Ext.ux.form.field.DateTimeField
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideDate) {
me.getDateField().hide();
}
me.callParent();
},
getValue: function () {
var me = this;
var dateTime = me.combineDateTime(me.getDate(), me.getTime());
if (me.utcValue) {
return me.localToUtc(dateTime);
}
return dateTime;
},
setValue: function(value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
if (me.utcValue) {
timeDate = this.utcToLocal(timeDate);
}
me.setDate(timeDate);
me.setTime(timeDate);
}
},
getTimeField : function() {
return this.lookupReference('timeField');
},
getDateField : function() {
return this.lookupReference('dateField');
},
getTime: function() {
return this.getTimeField().getValue();
},
setTime: function(value) {
this.getTimeField().setValue(value);
},
getDate: function() {
return this.getDateField().getValue();
},
setDate: function(value) {
this.getDateField().setValue(value);
},
combineDateTime : function(date, time) {
var year = date.getFullYear();
var month = date.getMonth();
var day = date.getDate();
var hour = time.getHours();
var minute = time.getMinutes();
var second = time.getSeconds();
return new Date(year, month, day, hour, minute, second, 0);
},
utcToLocal : function(utcDate) {
var year = utcDate.getUTCFullYear();
var month = utcDate.getUTCMonth();
var day = utcDate.getUTCDate();
var hour = utcDate.getUTCHours();
var minute = utcDate.getUTCMinutes();
var second = utcDate.getUTCSeconds();
return new Date(year, month, day, hour, minute, second, 0);
},
localToUtc : function(localDate) {
var year = localDate.getFullYear();
var month = localDate.getMonth();
var day = localDate.getDate();
var hour = localDate.getHours();
var minute = localDate.getMinutes();
var second = localDate.getSeconds();
return new Date(Date.UTC(year, month, day, hour, minute, second, 0));
}
});