使用Dojo处理(生日)日期和时区

时间:2014-01-31 23:21:18

标签: date timezone dojo

我有一个简单的小部件:

<input class="input" id="${id}_dateOfBirth" name="dateOfBirth" data-dojo-type="dijit/form/DateTextBox" />

请注意,这是生日。所以,它意味着保持相同的,无论你在哪里(时区都不应该发生)。如果您出生于1月10日凌晨3:00在英格兰,并从纽约查看您的个人信息,您仍然希望看到1月10日,而不是第9个!

我现在在GMT + 8。 当我提交这个表单时,这实际上是在我放入1970年1月1日时到达服务器:

dateOfBirth: "1969-12-31T16:00:00.000Z"     

哪个不好,因为它比实际日期短8小时。

基本上,我需要一种方法让DateTextBox将的日期显示为来自服务器,实际上忽略了浏览器的时区。

2 个答案:

答案 0 :(得分:4)

FWIW,这是我的UTCDateTextBox变体:

define([
    "dojo/_base/declare",
    "dijit/form/DateTextBox"
], function(declare, DateTextBox) {
    function isValidDate(value) {
        return value instanceof Date && isFinite(value.getTime());
    }
    function toUTCDate(value) {
        if (isValidDate(value)) {
            value = new Date(
                Date.UTC(value.getFullYear(), value.getMonth(), value.getDate())
            );
        }
        return value;
    }
    return declare(DateTextBox, {
        _getValueAttr : function() {
            return toUTCDate(this.inherited("_getValueAttr", arguments));
        }
    });
});

对于我的用例,我发现我不需要覆盖_setValueAttr()。通过上述实现,当从getUTCXXX()返回的日期对象上调用toUTCString()toISOString()toJSON()_getValueAttr()时,正确的UTC日期归零时间元素被返回。

希望这有帮助。

答案 1 :(得分:2)

经过大量黑客攻击和分析Dojo的源代码后,我想出了这个:

var UTCDateTextBox = declare( 'UTCDateTextBox', [ DateTextBox ], { 


  _getValueAttr: function(){ 
    var ov = this.inherited(arguments); 
    if( ov ){ 
      ov.setTime( ov.getTime() - ov.getTimezoneOffset() * 60 * 1000 ); 
    } 
    return ov; 

  }, 

  _setValueAttr: function( value, priorityChange, formattedValue){ 

    var v = stamp.fromISOString( value ); 
    if( v ){ 
      v.setTime( v.getTime() + v.getTimezoneOffset() * 60 * 1000 );                         
      value = v; 
    } 

    this.inherited(arguments); 
  }

}); 

基本上:

  • 设置值后,会添加时区差异。这意味着如果服务器有1979-12-25T00:00:00.000Z,而不是分配Tue Dec 25 1979 08:00:00 GMT + 0800(WST),它将分配Tue Dec 25 1979 00:00:00 GMT +0800(WST)。基本上,日期将本地转换为UTC中的任何日期。

  • 当解析该值时,它将从Tue Dec 25 1979 00:00:00 GMT + 0800(WST)更改为Tue Dec 25 1979 08:00:00 GMT + 0800(WST)

  • 更改的值是提交给服务器的值。因此,无论将在哪个时区进行编辑,它都是正确的。

由于我只处理日期,如果服务器有1979-12-31T23:00:00Z(这是一个错误:对于生日,时间实际上被忽略而且无关紧要),这将发生:

  • 设定值时,ISO为1979-12-31T23:00:00.000Z。所以,Tue Jan 01 1980 07:00:00 GMT + 0800(WST)改为1979年12月31日星期一23:00:00 GMT + 0800(WST)。这意味着正确的日期被放入日期文本框(31/12/1979)。

  • 当从文本框中解析出值时,Mon Dec 31 1979 00:00:00 GMT + 0800(WST)将于1979年12月31日星期一08:00:00 GMT + 0800(WST)。因此,服务器将保存1979-12-31T00:00:00Z - 这也是正确的日期!

如果有更好的解决方案,请告诉我。坦率地说,我希望有一个感觉像是作弊的