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

Date 使用Dojo处理(生日)日期和时区,date,timezone,dojo,Date,Timezone,Dojo,我有一个简单的小部件,它有: <input class="input" id="${id}_dateOfBirth" name="dateOfBirth" data-dojo-type="dijit/form/DateTextBox" /> 这很糟糕,因为离实际日期还有8个小时 基本上,我需要一种方法让DateTextBox显示来自服务器的日期,有效地忽略浏览器的时区。在对Dojo的源代码进行了大量的黑客攻击和分析后,我提出了以下建议: var UTCDateTextBox = d

我有一个简单的小部件,它有:

<input class="input" id="${id}_dateOfBirth" name="dateOfBirth" data-dojo-type="dijit/form/DateTextBox" />
这很糟糕,因为离实际日期还有8个小时


基本上,我需要一种方法让DateTextBox显示来自服务器的日期,有效地忽略浏览器的时区。

在对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,而不是分配1979年12月25日星期二08:00:00 GMT+0800(WST),它将分配1979年12月25日星期二00:00:00 GMT+0800(WST)。基本上,日期在本地转换为UTC中的任何日期

  • 解析该值时,它将从1979年12月25日星期二00:00:00 GMT+0800(WST)更改为1979年12月25日星期二08:00:00 GMT+0800(WST)

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

因为我只处理日期,如果服务器有1979-12-31T23:00:00Z(这是一个错误:对于生日,时间实际上被忽略,不重要),则会发生以下情况:

  • 设置该值时,ISO为1979-12-31T23:00:00.000Z。因此,1980年1月1日星期二07:00:00 GMT+0800(WST)改为1979年12月31日星期一23:00:00 GMT+0800(WST)。这意味着将正确的日期放入日期文本框(1979年12月31日)

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


如果有更好的解决方案,请让我知道。坦白地说,我希望有,因为这一个感觉像一个骗局位

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));
        }
    });
});
对于我的用例,我发现我不需要重写
\u setValueAttr()
。在上述实现中,当对从
\u getValueAttr()
返回的日期对象调用
getutcxx()
toitString()
toJSON()
时,将返回带有零时间元素的正确UTC日期


希望这能有所帮助。

哦,我的天哪,要么我的答案(仍然有效)是“正确”的答案,要么没有人用Dojo的日期选择器记录出生日期!我认为没有一种规范的方法可以在不扩展日历(就像您所做的那样)或在序列化日期之前操纵日期的情况下做到这一点。在我自己的项目中,我也以类似的方式处理它,但仍然没有投票,这意味着实际上没有多少人关心这个问题。哦,好吧,美塞苔丝干得好。我需要一个UTC文本框,用于度假租赁网站上的“季节性”日期范围。我用黑客已经很久了。这是个更好的主意。当我回家测试这个解决方案时,我会测试它并接受这个答案。谢谢我已经在我们的应用程序中使用了这个小部件。
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));
        }
    });
});