【问题标题】:Javascript date object without time zone没有时区的Javascript日期对象
【发布时间】:2017-02-19 17:59:12
【问题描述】:

我最近为基于云的系统实现了一个基于 webview 的移动应用程序,但遇到了一个令人沮丧的问题。

我们将日期存储在数据库中,格式如下:

2016-10-11T11:09:00

在桌面应用程序中正确显示为 2016/10/11 11:09:00

但是,在移动应用程序中(我们使用 phonegap,因此它基于 HTML + JS),当我通过 PHP 调用从数据库中获取此日期字符串并使用 'new Date("2016-10 -11T11:09:00")',它会显示时区转换,例如,如果我在 GMT + 2 时,它将是 2016/10/11 13:09:00 .

如何防止这种情况发生?

每当我在视图上显示日期时,我都会使用 date.toString("yyyy/MM/dd HH:mm:ss") 格式。

此外,在跨多个平台存储和显示日期时间方面,我愿意接受任何建议。我发现这种 yyyy-mm-ddThh:mm:ss 格式非常好并且被广泛使用,直到我遇到了这个 javascript 问题。

(据你所知,我不是 javascript 或 HTML 专家)

LE:我不想将日期转换为 UTC 字符串,我希望实际的 Date 对象与数据库值保持一致,因为我通过 AngularJS 将它连接到 HTML 日期时间选择器。

【问题讨论】:

  • 我刚刚在 Chrome 开发者工具中尝试了 new Date("2016-10-11T11:09:00Z") 和 new Date("2016-10-11T11:09:00") ,他们给出了同样的事情。
  • 这正是我所说的...... Chrum 没有区别,但 Firefox 和 Edge 确实有区别 - 除非您的本地时间是 UTC
  • 哦,对了,我在你编辑评论之前就开始回复了。 “Z”在移动应用 web 视图中也无济于事
  • 如果您的应用程序在全球范围内使用,您可能希望将 UTC 存储在您的数据库中,并以用户的本地时区呈现时间,不是吗?

标签: javascript html cordova date datetime


【解决方案1】:

您真正想要实现的目标是什么?如果您想始终显示时间戳,因为它们忽略了时区信息,那么当这些时间戳可能会向某些用户显示未来时间时,您可能会让用户感到非常困惑。例如:有人修改数据,美国西海岸的另一个用户查看数据并看到指向未来的时间戳。

也许您想使用的是 Data.toUTCString(),它显示时间戳,以便您将 GMT 作为时区。然后很明显,对于用户来说,这个时间戳不在他们的时区。此外,您可能希望将时区信息附加到时间戳字符串中,以便正确进行转换。如果您的时间戳采用 UTC(或祖鲁时间),您可以在字符串末尾添加“Z”。 RFC 2822 第 3.3 节定义日期和时间 应该 表示本地时间,但至少对于 node.js,如果您将时区信息排除在外,它似乎表示 UTC 时间。因此,添加时区信息将使您的生活更轻松(如果您在存储在数据库中的字符串中添加时区信息会更好)。

举个例子:

var timestamp = "2016-10-11T11:09:00";
var d = new Date(timestamp);
// or
d = new Date(timestamp + "Z");

// Then showing the date
d.toString();
// or without the converting it to user's local timezone
d.toUTCString();

我希望这会有所帮助。

【讨论】:

  • 感谢您的建议,但我想要实现的是,将删除 Date 对象的时区偏移量。此 toUTCString() 函数仅在我想将其转换为字符串时才有帮助。我需要日期对象与数据库中的值保持一致,因为我在 HTML 时间输入中显示它。
  • 然后你需要将时区信息添加到你从数据库中获取的字符串中,期望你得到一个字符串。日期对象总是有时区信息,你不应该试图绕过这个。
  • 我做了一个快速测试,所以我用 Firefox 和 node.js 运行了 'new Date("2016-10-11T13:00:00")' 并且结果不同。 Node.js 将日期字符串视为 UTC 时间戳,而 Firefox 将其视为本地时间(按照 RFC 2822 的建议)。就像我之前说的,Date 总是有时区信息。如果您将其从日期字符串中省略,则取决于客户端实现它们将返回什么。
【解决方案2】:

您可以使用这个小功能来获取结果

function getCorrectString(dateTimeString){
     var a  = new Date(dateTimeString);
     return a.getFullYear()+'/'
     +('00'+(a.getMonth()+1)).substring(('00'+(a.getMonth()+1)).length-2) +'/'
     +('00'+a.getDate()).substring(('00'+a.getDate()).length-2)+' '
     +('00'+a.getHours()).substring(('00'+a.getHours()).length-2)+':'
     +('00'+a.getMinutes()).substring(('00'+a.getMinutes()).length-2)+':'
     +('00'+a.getSeconds()).substring(('00'+a.getSeconds()).length-2);
}

getCorrectString('2016-10-11T11:09:00')

//result :
//"2016/10/11 11:09:00"

【讨论】:

    【解决方案3】:

    遇到了同样的问题。以yyyy-mm-ddThh:mm:ss 格式存储,但需要在客户端将其转换为日期以进行倒数计时器计算(需要创建第二个日期 -> 减去差异 -> 创建倒数计时器)。逻辑在浏览器中是正确的,在 Ionic2/cordova 应用程序 webviews 中不正确且不一致。有趣的是:我的妻子和我都有相同的手机品牌/型号,而且她的日期会与我的不同(!)。

    尚未经过广泛测试,但这里有一个小函数,它接受字符串并返回日期...在我的手机和浏览器上始终如一地工作:

    const someDateStrFromServer: string = "2017-08-26T15:30:25";
    const date: Date = DateUtils.overrideTimezone(someDateStringFromServer);
    
    // these methods are in Class DateUtils {}
    // input: string, output: Date
    public static overrideTimezone(dateStr: string): Date {
        const date: Date = new Date(dateStr);
        const hours: number = date.getHours();
        const tIndex: number = dateStr.indexOf("T");
        const dateStrHours: number = +(dateStr.slice(tIndex + 1, tIndex + 3));
        const tzOffset =  DateUtils.getTimezoneOffset("h");
    
        // compares hours sliced from string and hours from date. if different,
        // then I know timezone was calculated into the Date
    
        if (dateStrHours === hours) return date;  // everything's OK
    
        // webview factored in timezone, so add it back to correct
        else return new Date(date.setHours(date.getHours() + tzOffset));
    
    }
    
    // can scale it to include "ms", "s", "m", etc
    public static getTimezoneOffset(unit = "h") {
        switch(unit) {
            case "h": 
                return (new Date()).getTimezoneOffset() / 60;
            default:
                return (new Date()).getTimezoneOffset() / 60;
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用Moment.js 并定义自己的自定义日期格式化程序:

      var formatter= 'YYYY-MM-DD[T]HH:mm:ss';
      var date = new Date('July 17, 2018 03:24:00');
      var time = moment(date).format(formatter);
      console.log('Time: ',time);
      

      小提琴:https://jsfiddle.net/mkotsollaris/3krdttm3/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-22
        • 2013-07-06
        • 2013-10-29
        • 1970-01-01
        • 2015-12-10
        • 2019-06-05
        • 1970-01-01
        • 2012-12-01
        相关资源
        最近更新 更多