不同时区的Javascript日期格式

时间:2010-04-10 13:21:27

标签: javascript

我是一名Java开发人员,我习惯使用SimpleDateFormat类,它允许我通过设置时区将任何日期格式化为任何格式。

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println(sdf.format(date)); // Prints date in Los Angeles

sdf.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
System.out.println(sdf.format(date)); // Prints same date in Chicago

SimpleDateFormat是一个非常简洁的Java解决方案,但遗憾的是我在Javascript中找不到任何类似的替代方案。

我正在 Javascript 中扩展Date原型以完全相同。我有Unix格式的日期,但我想在不同的时区格式化它们。

Date.prototype.format = function(format, timezone) {
    // Now what?
    return formattedDate;
}

我正在寻找一种巧妙的方法,而不是黑客。

由于

8 个答案:

答案 0 :(得分:4)

我认为接受的答案不正确。有一种格式化时区的方法。

console.log(new Date().toLocaleDateString('en-US', {timeZone: 'America/Denver'}))
// 11/13/2018
console.log(new Date().toLocaleTimeString('en-US', {timeZone: 'America/Denver'}))
// 2:30:54 PM
console.log(new Date().toLocaleTimeString('en-US', {timeZone: 'America/New_York'}))
// 4:31:26 PM

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString

答案 1 :(得分:3)

JavaScript没有构建支持其他时区而不是本地时区。您只能以当地时间或UTC时间表示日期。无法更改Date对象的时区偏移量。

因此,没有“整洁”的方法来解决你的问题。

答案 2 :(得分:2)

普通日期的ISO扩展格式为YYYY-MM-DD,时间为hh:mm:ss。这两种格式都可以在世界范围内明确地理解。

另见: http://jibbering.com/faq/#dates

答案 3 :(得分:1)

不要写自己的东西;得到datejs:http://www.datejs.com/

您可以在执行环境中找出时区偏移量设置的内容,如下所示:

var local = new Date();
var utc = Date.UTC(local.getFullYear(), local.getMonth(), local.getDate(), local.getHours(), local.getMinutes(), local.getSeconds(), local.getMilliseconds());
var tz = (utc - local.getTime()) / (60 * 60 * 1000);

答案 4 :(得分:1)

如果您只是通过原始TZ,那么调整小时数并不复杂。 我的下面的例子当然是缩写的。根据您处理的模式数量,您可能需要很长时间。

Date.prototype.format = function(format, tzAdjust) {
    // adjust timezone
    this.setHours(this.getHours()+tzAdjust)
    // pad zero helper - return "09" or "12"
    var two = function(s){ return s+"".length==1 ? "0"+s : s+""; }
    // replace patterns with date numbers
    return format.replace(/dd|MM|yyyy|hh|mm|ss/g, function(pattern){
        switch(pattern){
            case "d" : return this.getDate();
            case "dd" : return two(this.getDate());
        }
    });
}

答案 5 :(得分:1)

尝试(略微有点)改进mwilcox的建议:

Date.prototype.format = function(format, tzAdjust) {

    // get/setup a per-date-instance tzDate object store
    var tzCache = this.__tzCache = this.__tzCache || (this.__tzCache = {});

    // fetch pre-defined date from cache 
    var tzDate = tzCache[tzAdjust];
    if ( !tzDate )
    {
      // on miss - then create a new tzDate and cache it
      tzDate = tzCache[tzAdjust] = new Date( this );
      // adjust by tzAdjust (assuming it's in minutes 
      // to handle those weird half-hour TZs :) 
      tzDate.setUTCMinutes( tzDate.getUTCMinutes()+tzAdjust );
    }

    return format.replace(/dd|MM|yyyy|hh|mm|ss/g, function(pattern){
               // replace each format tokens with a value 
               // based on tzDate's corresponding UTC property
             });
}

答案 6 :(得分:1)

您显然在一个问题中提出两个问题,即格式和时区。他们需要单独处理。格式化是非常简单的,如果没有其他答案可以做到这一点,你将不得不更具体。

对于时间和时区,如果您的服务器将UTC时间(最好是UNIX时间,以毫秒为单位)注入JavaScript,您可以将其与客户端计算机上的时间进行比较,从而计算出多远来自UTC客户端。然后你可以计算你想要的任何时区的时间。

编辑:我实际上并不知道JavaScript在UTC时间内建立,直到我在互联网上查看,整洁。

无论如何,我想这是你想要的:

Date.prototype.format=function(format,timezone){
    var obj=new Date(this.getTime()+this.getTimezoneOffset()*60000+timezone*3600000);
    var two=function(s){
        return s<10?"0"+s:s+"";
    }
    return format.replace(/dd|MM|yyyy|hh|mm|ss/g, function(pattern){
        switch(pattern){
            case "dd" : return two(obj.getDate());
            case "MM" : return two(obj.getMonth()+1);
            case "yyyy" : return obj.getFullYear();
            case "hh" : return two(obj.getHours());
            case "mm" : return two(obj.getMinutes());
            case "ss" : return two(obj.getSeconds());
        }
    });
}

如果需要,您可以添加更多模式。

答案 7 :(得分:0)

由于我的要求是打字稿解决方案,但我在这里偶然发现我使用this answer编写了打字稿功能。

基于上面的回答,打字稿中的一个函数可以将时间戳记或日期对象转换为格式化的本地时间字符串。

const formatDateString = (date_or_ts:Date|number):string=>{
    let obj:Date;

    if(typeof date_or_ts === "number"){
        obj = new Date(date_or_ts*1000);
        // obj=new Date(obj.getTime()+obj.getTimezoneOffset()*60000+timezone*3600000);
    }else{
        obj = date_or_ts;
    }
    const format = "dd-MM-yyyy hh:mm:ss";
    let two=function(s:number){
        return s<10?"0"+s:s+"";
    }
    return format.replace(/dd|MM|yyyy|hh|mm|ss/g, function(pattern){
        const months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
        switch(pattern){
            case "dd" : return two(obj.getDate()).toString();
            case "MM" : return months[obj.getMonth()];
            case "yyyy" : return obj.getFullYear().toString();
            case "hh" : return two(obj.getHours()).toString();
            case "mm" : return two(obj.getMinutes()).toString();
            case "ss" : return two(obj.getSeconds()).toString();
            default: return "";
        }
    });
}