简体   繁体   English

不同时区的Javascript DateFormat

[英]Javascript DateFormat for different timezones

I'm a Java developer and I'm used to the SimpleDateFormat class that allows me to format any date to any format by settings a timezone.我是一名 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 is a pretty neat solution in Java but unfortunately I can't find any similar alternative in Javascript. SimpleDateFormat 是一个非常简洁的 Java 解决方案,但不幸的是我在 Javascript 中找不到任何类似的替代方案。

I'm extending the Date prototype in Javascript to do exactly the same.我在Javascript 中扩展 Date 原型来做完全相同的事情。 I have dates in Unix format but I want to format them in different timezones.我有 Unix 格式的日期,但我想将它们格式化为不同的时区。

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

I'm looking for a neat way to do this rather than a hack.我正在寻找一种巧妙的方法来做到这一点而不是黑客。

Thanks谢谢

There is a way to format for time zones.有一种格式化时区的方法。

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/toLocaleDateString

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

The ISO Extended format for common date is YYYY-MM-DD, and for time is hh:mm:ss.通用日期的 ISO 扩展格式为 YYYY-MM-DD,时间为 hh:mm:ss。 Either format can be understood, unambiguously, worldwide.任何一种格式都可以在世界范围内明确地被理解。

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

Don't write your own stuff;不要写自己的东西; just get datejs: http://www.datejs.com/只需获取 datejs: http ://www.datejs.com/

You can figure out what the timezone offset is set to in the execution environment like this:您可以像这样找出在执行环境中设置的时区偏移量:

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);

If you're just passing the raw TZ there's nothing really complicated about adjusting the hours.如果您只是通过原始 TZ,则调整时间并不复杂。 My example below is of course abbreviated.我下面的例子当然是缩写的。 Yours may get quite long depending on how many patterns you'd handle.根据您处理的模式数量,您的可能会变得很长。

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());
        }
    });
}

Attempting to (ever so slightly) improve upon mwilcox's suggestion:尝试(稍微)改进 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
             });
}

You are clearly asking two questions in one, formatting and time zone.您显然是在问两个问题,格式和时区。 They need to be addressed separately.它们需要分别处理。 Formatting is pretty trivial, if none of the other answers will do for that you will have to be more specific.格式化非常简单,如果其他答案都不起作用,您将必须更具体。

As for the time and time zone, if you have your server inject the UTC time, preferably as UNIX time in milliseconds, into the JavaScript, you can compare that to the time on the client machine, and thus work out how far from UTC the client is.至于时间和时区,如果您让您的服务器将 UTC 时间(最好是以毫秒为单位的 UNIX 时间)注入 JavaScript,您可以将其与客户端机器上的时间进行比较,从而计算出与 UTC 相差多远客户是。 Then you can calculate the time of any time zone you want.然后你可以计算你想要的任何时区的时间。

Edit: I actually didn't know JavaScript also had built in UTC time until I checked on the internet, neat.编辑:我实际上不知道 JavaScript 也内置了 UTC 时间,直到我在互联网上查看,整洁。

In any case, I suppose this is want you want:无论如何,我想这是你想要的:

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());
        }
    });
}

You can add in more patterns if you need.如果需要,您可以添加更多模式。

JavaScript does not have build in support for other time zone than the local one. JavaScript 没有对本地时区以外的其他时区的内置支持。 You can only express a date in local time or in UTC time.您只能以本地时间或 UTC 时间表示日期。 There is no way to change the time zone offset of a Date object.无法更改 Date 对象的时区偏移量。

Thus, there is no "neat" way to solve your problem.因此,没有“简洁”的方法可以解决您的问题。

This is an old question, but since I found it:这是一个老问题,但自从我发现它:

As mentioned, there's nothing reasonable built-in.如前所述,没有任何合理的内置。

As for libs, there is Moment Timezone for Moment.js .至于库, Moment.jsMoment 时区

Here is a JSfiddle with an example: http://jsfiddle.net/kunycrkb/这是一个带有示例的 JSfiddle: http : //jsfiddle.net/kunycrkb/

The same code inline:内联相同的代码:

var m = moment("2014-06-01T13:05:00Z");
var f = "HH:mm z";

$("#results").text(m.tz("UTC").format(f) + " is " + m.tz("EST").format(f) +  "!");

Since my requirement was a typescript solution but I stumbled here I used this answer to write my typescript function.由于我的要求是一个打字稿解决方案,但我在这里偶然发现了这个答案来编写我的打字稿功能。

Based on answer above, a function in typescript which converts a timestamp or a date object into a formatted local time string.基于上面的答案,打字稿中的一个函数将时间戳或日期对象转换为格式化的本地时间字符串。

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 "";
        }
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM