432

我正在寻找一种将一个时区中的日期转换为另一个时区的函数。

它需要两个参数,

  • 日期(格式为“2012/04/10 10:10:30 +0000”)
  • 时区字符串(“亚洲/雅加达”)

http://en.wikipedia.org/wiki/Zone.tab中描述了时区字符串

是否有捷径可寻?

4

29 回答 29

341

这是单线:

function convertTZ(date, tzString) {
    return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {timeZone: tzString}));   
}

// usage: Asia/Jakarta is GMT+7
convertTZ("2012/04/20 10:10:30 +0000", "Asia/Jakarta") // Tue Apr 20 2012 17:10:30 GMT+0700 (Western Indonesia Time)

// Resulting value is regular Date() object
const convertedDate = convertTZ("2012/04/20 10:10:30 +0000", "Asia/Jakarta") 
convertedDate.getHours(); // 17

// Bonus: You can also put Date object to first arg
const date = new Date()
convertTZ(date, "Asia/Jakarta") // current date-time in jakarta.

   

这是MDN 参考

请注意警告:上面的函数依赖于解析 toLocaleString 结果来工作,该结果是在en-USlocale 中格式化的日期字符串,例如"4/20/2012, 5:10:30 PM". 每个浏览器可能不接受en-US其 Date 构造函数的格式化日期字符串,并且可能会返回意外结果(它可能会忽略夏令时)。

目前所有现代浏览器都接受这种格式并正确计算夏令时,它可能不适用于旧浏览器和/或外来浏览器。

旁注:如果现代浏览器具有 toLocaleDate 功能会很棒,所以我们不必使用这个 hacky 工作。

于 2019-01-10T10:54:24.663 回答
139

对于moment.js用户,您现在可以使用moment-timezone。使用它,您的函数将如下所示:

function toTimeZone(time, zone) {
    var format = 'YYYY/MM/DD HH:mm:ss ZZ';
    return moment(time, format).tz(zone).format(format);
}
于 2013-09-04T11:26:19.743 回答
123

大多数浏览器都支持带参数的toLocaleString函数,较旧的浏览器通常会忽略参数。

const str = new Date().toLocaleString('en-US', { timeZone: 'Asia/Jakarta' });
console.log(str);

于 2014-08-29T00:08:50.980 回答
98

无耻地盗取自:http ://www.techrepublic.com/article/convert-the-local-time-to-another-time-zone-with-this-javascript/6016329

/** 
 * function to calculate local time
 * in a different city
 * given the city's UTC offset
 */
function calcTime(city, offset) {

    // create Date object for current location
    var d = new Date();
   
    // get UTC time in msec
    var utc = d.getTime();
   
    // create new Date object for different city
    // using supplied offset
    var nd = new Date(utc + (3600000*offset));
   
    // return time as a string
    return "The local time in " + city + " is " + nd.toLocaleString();
}

此函数通过提供城市/国家名称和偏移值来计算时区值很有用

于 2012-04-10T11:40:54.663 回答
55

好的,找到了!

我正在使用timezone-js。这是代码:

var dt = new timezoneJS.Date("2012/04/10 10:10:30 +0000", 'Europe/London');
dt.setTimezone("Asia/Jakarta");

console.debug(dt); //return formatted date-time in asia/jakarta
于 2012-04-10T12:51:12.270 回答
30

如果您不想导入一些大型库,您可以使用Intl.DateTimeFormat将 Date 对象转换为不同的时区。

// Specifying timeZone is what causes the conversion, the rest is just formatting
const options = {
  year: '2-digit', month: '2-digit', day: '2-digit',
  hour: '2-digit', minute: '2-digit', second: '2-digit',
  timeZone: 'Asia/Jakarta',
  timeZoneName: 'short'
}
const formatter = new Intl.DateTimeFormat('sv-SE', options)
const startingDate = new Date("2012/04/10 10:10:30 +0000")

const dateInNewTimezone = formatter.format(startingDate) 
console.log(dateInNewTimezone) // 12-04-10 17:10:30 GMT+7

偏移量、夏令时和过去的变化将为您处理。

于 2018-04-04T09:55:53.323 回答
11

知道了!

想要强制显示的日期=服务器日期,无论本地设置 (UTC)。

我的服务器是GMT-6 --> new Date().getTimezoneOffset()= 360

myTZO = 360;
myNewDate = new Date(myOldDateObj.getTime() + (60000*(myOldDateObj.getTimezoneOffset()-myTZO)));
alert(myNewDate);
于 2015-02-17T01:19:51.190 回答
7

您可以使用 toLocaleString() 方法来设置时区。

new Date().toLocaleString('en-US', { timeZone: 'Indian/Christmas' })

对于印度,您可以使用“印度/圣诞节”,以下是各个时区,

"Antarctica/Davis",
    "Asia/Bangkok",
    "Asia/Hovd",
    "Asia/Jakarta",
    "Asia/Phnom_Penh",
    "Asia/Pontianak",
    "Asia/Saigon",
    "Asia/Vientiane",
    "Etc/GMT-7",
    "Indian/Christmas"
于 2018-07-10T08:13:17.487 回答
3

这是我的代码,它运行良好,你可以试试下面的演示:

$(document).ready(function() {
   //EST
setInterval( function() {
var estTime = new Date();
 var currentDateTimeCentralTimeZone = new Date(estTime.toLocaleString('en-US', { timeZone: 'America/Chicago' }));
var seconds = currentDateTimeCentralTimeZone.getSeconds();
var minutes = currentDateTimeCentralTimeZone.getMinutes();
var hours =  currentDateTimeCentralTimeZone.getHours()+1;//new Date().getHours();
 var am_pm = currentDateTimeCentralTimeZone.getHours() >= 12 ? "PM" : "AM";

if (hours < 10){
     hours = "0" + hours;
}

if (minutes < 10){
     minutes = "0" + minutes;
}
if (seconds < 10){
     seconds = "0" + seconds;
}
    var mid='PM';
    if(hours==0){ //At 00 hours we need to show 12 am
    hours=12;
    }
    else if(hours>12)
    {
    hours=hours%12;
    mid='AM';
    }
    var x3 = hours+':'+minutes+':'+seconds +' '+am_pm
// Add a leading zero to seconds value
$("#sec").html(x3);
},1000);


});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<p class="date_time"><strong id="sec"></strong></p>
</body>
</html>

于 2018-10-16T09:50:36.823 回答
3

如果您只需要转换时区,我已经上传了一个精简版时刻时区,只有最低限度的功能。它的 ~1KB + 数据:

S.loadData({
    "zones": [
        "Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|11e6",
        "Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1GQg0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|40e5",
    ],
    "links": [
        "Europe/Paris|Europe/Madrid",
    ]
});

let d = new Date();
console.log(S.tz(d, "Europe/Madrid").toLocaleString());
console.log(S.tz(d, "Australia/Sydney").toLocaleString());
于 2017-04-22T16:19:53.147 回答
3

使用 ,设置变量yearmonth并用符号day分隔,加上 a和HH:mm:ss模式中的时间,然后是字符串的末尾(在我的情况下,时区是)。然后将此字符串用作日期构造函数的参数。-T+01:00+1

// desired format: 2001-02-04T08:16:32+01:00
dateAndTime = year+"-"+month+"-"+day+"T"+hour+":"+minutes+":00+01:00";

var date = new Date(dateAndTime );
于 2016-09-26T13:33:05.570 回答
3

我应该注意,我在可以使用哪些外部库方面受到限制。moment.js 和 timezone-js 不是我的选择。

我拥有的 js 日期对象是 UTC。我需要在特定时区(在我的情况下为“美国/芝加哥”)中的该日期获取日期和时间。

 var currentUtcTime = new Date(); // This is in UTC

 // Converts the UTC time to a locale specific format, including adjusting for timezone.
 var currentDateTimeCentralTimeZone = new Date(currentUtcTime.toLocaleString('en-US', { timeZone: 'America/Chicago' }));

 console.log('currentUtcTime: ' + currentUtcTime.toLocaleDateString());
 console.log('currentUtcTime Hour: ' + currentUtcTime.getHours());
 console.log('currentUtcTime Minute: ' + currentUtcTime.getMinutes());
 console.log('currentDateTimeCentralTimeZone: ' +        currentDateTimeCentralTimeZone.toLocaleDateString());
 console.log('currentDateTimeCentralTimeZone Hour: ' + currentDateTimeCentralTimeZone.getHours());
 console.log('currentDateTimeCentralTimeZone Minute: ' + currentDateTimeCentralTimeZone.getMinutes());

UTC 目前比“美国/芝加哥”早 6 小时。输出是:

currentUtcTime: 11/25/2016
currentUtcTime Hour: 16
currentUtcTime Minute: 15

currentDateTimeCentralTimeZone: 11/25/2016
currentDateTimeCentralTimeZone Hour: 10
currentDateTimeCentralTimeZone Minute: 15
于 2016-11-25T16:26:21.897 回答
1

Provide the desired time zone, for example "Asia/Tehran" to change the current time to that timezone. I used "Asia/Seoul".

You can use the following codes. change the style if you need to do so.

please keep in mind that if you want to have h:m:s format instead of HH:MM:SS, you'll have to remove "function kcwcheckT(i)".

function kcwcheckT(i) {
  if (i < 10) {
    i = "0" + i;
  }
  return i;
}
function kcwt() {
var d = new Date().toLocaleString("en-US", {timeZone: "Asia/Seoul"});
d = new Date(d);
  var h = d.getHours();
  var m = d.getMinutes();
  var s = d.getSeconds();
  h = kcwcheckT(h);
  m = kcwcheckT(m);
  s = kcwcheckT(s);
  document.getElementById("kcwcurtime").innerHTML = h + ":" + m + ":" + s;
  var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
document.getElementById("kcwcurday").innerHTML = days[d.getDay()]
}
kcwt();
window.setInterval(kcwt, 1000);
@import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap');

.kcwsource {color:#040505;cursor: pointer;display:block;width: 100%;border: none;border-radius:5px;text-align:center;padding: 5px 10px 5px 10px;}
.kcwsource p {font-family: 'Nunito', sans-serif;}


.CurTbx {color:#040505;cursor: pointer;display:block;width: 100%;border: none;border-radius:5px;text-align:center;padding: 5px 10px 5px 10px;}
.kcwcstyle {font-family: 'Nunito', sans-serif; font-size: 22px;display: inline-block;}
.kcwcurstinf {font-family: 'Nunito', sans-serif; font-size: 18px;display: inline-block;margin: 0;}
.kcwcurday {margin: 0;}
.kcwcurst {margin: 0 10px 0 5px;}

/*Using the css below you can make your style responsive!*/

@media (max-width: 600px){
  .kcwcstyle {font-size: 14px;}
  .kcwcurstinf {font-size: 12px;}
}
<div class="kcwsource"><p>This Pen was originally developed for <a href="http://kocowafa.com" target="_blank">KOCOWAFA.com</a></p></div>
<div class="CurTbx"><p class="kcwcurst kcwcstyle" id="kcwcurday"></p><p class="kcwcurst kcwcstyle" id="kcwcurtime"></p><p class="kcwcurstinf">(Seoul, Korea)</p></div>

于 2020-08-14T03:52:37.570 回答
1

看了很多,包括这个页面的链接,我发现了这篇很棒的文章,使用时刻时区:

https://www.webniraj.com/2016/11/23/javascript-using-moment-js-to-display-dates-times-in-users-timezone/

总结一下:

获取用户的时区

var tz = moment.tz.guess();
console.info('Timezone: ' + tz);

返回例如:时区:欧洲/伦敦

设置默认用户时区

moment.tz.setDefault(tz);

设置自定义时区

moment.tz.setDefault('America/Los_Angeles');

将日期/时间转换为本地时区,假设原始日期/时间为 UTC

moment.utc('2016-12-25 07:00').tz(tz).format('ddd, Do MMMM YYYY, h:mma');

返回时间:2016 年 12 月 25 日,星期日,上午 7:00

将日期/时间转换为洛杉矶时间

moment.utc('2016-12-25 07:00').tz('America/Los_Angeles').format('ddd, Do MMMM YYYY, h:mma');

返回:2016 年 12 月 24 日星期六晚上 11:00

将洛杉矶时间转换为伦敦时间

moment.tz('2016-12-25 07:00', 'America/Los_Angeles').tz('Europe/London').format( 'ddd, Do MMMM YYYY, h:mma' );

返回:2016 年 12 月 25 日星期日下午 3:00

于 2018-09-13T12:08:46.597 回答
1

您也可以尝试将日期时区转换为印度:

var indianTimeZoneVal = new Date().toLocaleString('en-US', {timeZone: 'Asia/Kolkata'});
var indainDateObj = new Date(indianTimeZoneVal);
indainDateObj.setHours(indainDateObj.getHours() + 5);
indainDateObj.setMinutes(indainDateObj.getMinutes() + 30);
console.log(indainDateObj);
于 2016-09-29T07:15:29.780 回答
1

做起来很简单:

const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(timeZone);

var d = new Date();
console.log(d.toLocaleString('en-US', { timeZone }));

于 2020-12-06T06:51:16.697 回答
1

您也可以使用 https://www.npmjs.com/package/ctoc_timezone

它有很多简单的实现和格式定制。

更改 toTimeZone 中的格式:

CtoC.toTimeZone(new Date(),"EST","Do MMM YYYY hh:mm:ss #{EST}");

输出 :

28th Feb 2013 19:00:00 EST

您可以在文档中探索多种功能。

于 2018-11-01T06:49:44.927 回答
1

我不知道将日期对象转换为任何时区的简单方法,但是如果要将其转换为本地时区,则可以将其转换Date.prototype.getTime()为相应的毫秒数,然后再转换回来。

date = new Date('2016-05-24T13:07:20');
date = new Date(date.getTime());

例如,如果您像我一样在奥地利(现在是夏天) ,date.getHours()现在将返回15而不是返回。13

我已经读到各种日期时间函数可能在某些浏览器中表现出非标准行为,所以首先测试一下。我可以确认它在 Chrome 中有效。

于 2016-05-24T13:22:59.940 回答
1

我最近在 Typescript 中这样做了:

// fromTimezone example : Europe/Paris, toTimezone example: Europe/London
private calcTime( fromTimezone: string, toTimezone: string, dateFromTimezone: Date ): Date {
  const dateToGetOffset = new Date( 2018, 5, 1, 12 );

  const fromTimeString = dateToGetOffset.toLocaleTimeString( "en-UK", { timeZone: fromTimezone, hour12: false } );
  const toTimeString = dateToGetOffset.toLocaleTimeString( "en-UK", { timeZone: toTimezone, hour12: false } );

  const fromTimeHours: number = parseInt( fromTimeString.substr( 0, 2 ), 10 );
  const toTimeHours: number = parseInt( toTimeString.substr( 0, 2 ), 10 );

  const offset: number = fromTimeHours - toTimeHours;

  // convert to msec
  // add local time zone offset
  // get UTC time in msec
  const dateFromTimezoneUTC = Date.UTC( dateFromTimezone.getUTCFullYear(),
    dateFromTimezone.getUTCMonth(),
    dateFromTimezone.getUTCDate(),
    dateFromTimezone.getUTCHours(),
    dateFromTimezone.getUTCMinutes(),
    dateFromTimezone.getUTCSeconds(),
  );

  // create new Date object for different city
  // using supplied offset
  const dateUTC = new Date( dateFromTimezoneUTC + ( 3600000 * offset ) );

  // return time as a string
  return dateUTC;
}

我使用“en-UK”格式,因为它很简单。可能是“en-US”或任何工作。

如果第一个参数是您的语言环境时区,第二个参数是您的目标时区,它将返回一个具有正确偏移量的 Date 对象。

于 2018-05-29T15:57:14.160 回答
0

您可以使用一个名为timezones.json的 npm 模块。它基本上由一个 json 文件组成,其中包含有关夏令时和偏移信息的对象。

对于asia/jakarta,它将能够返回此对象:

{
  "value": "SE Asia Standard Time",
  "abbr": "SAST",
  "offset": 7,
  "isdst": false,
  "text": "(UTC+07:00) Bangkok, Hanoi, Jakarta",
  "utc": [
    "Antarctica/Davis",
    "Asia/Bangkok",
    "Asia/Hovd",
    "Asia/Jakarta",
    "Asia/Phnom_Penh",
    "Asia/Pontianak",
    "Asia/Saigon",
    "Asia/Vientiane",
    "Etc/GMT-7",
    "Indian/Christmas"
  ]
}

你可以在这里找到它:

https://github.com/dmfilipenko/timezones.json

https://www.npmjs.com/package/timezones.json

希望它有用

于 2016-07-25T06:04:21.760 回答
0

使用luxon库:

import { DateTime } from "luxon";

// Convert function:
const convertTz = (datetime, fromTz, toTz, format='yyyy-MM-dd HH:mm:ss') => {
  return DateTime.fromFormat(datetime, format, { zone: fromTz }).setZone(toTz).toFormat(format);
}

// Use it like this:
console.log(convertTz('2021-10-03 19:00:00', 'Europe/Lisbon', 'America/New_York'));

于 2021-11-03T23:13:16.820 回答
0

有服务器问题选择 gmt+0000 标准时区您可以通过在 javascript 中使用库 moment-timezone 来更改它

const moment = require("moment-timezone")
const dateNew = new Date()
const changeZone = moment(dateNew);
changeZone.tz("Asia/Karachi").format("ha z");
// here you can paste "your time zone string"
于 2020-12-21T06:48:22.953 回答
0

这在 React Native Application 中对我有用。

import moment from 'moment-timezone'

function convertTZ(date, tzString) {
  const formatedDate = moment(date).tz(tzString).format()
  return formatedDate
}

export {convertTZ}
于 2022-02-28T15:29:17.460 回答
0

熟悉 java 8java.time包的人,或者joda-time可能会喜欢这个新的孩子:js-joda库。

安装

npm install js-joda js-joda-timezone --save

例子

<script src="node_modules/js-joda/dist/js-joda.js"></script>
<script src="node_modules/js-joda-timezone/dist/js-joda-timezone.js"></script>
<script>
var dateStr = '2012/04/10 10:10:30 +0000';
JSJoda.use(JSJodaTimezone);
var j = JSJoda;
// https://js-joda.github.io/js-joda/esdoc/class/src/format/DateTimeFormatter.js~DateTimeFormatter.html#static-method-of-pattern
var zonedDateTime = j.ZonedDateTime.parse(dateStr, j.DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss xx'));
var adjustedZonedDateTime = zonedDateTime.withZoneSameInstant(j.ZoneId.of('America/New_York'));
console.log(zonedDateTime.toString(), '=>', adjustedZonedDateTime.toString());
// 2012-04-10T10:10:30Z => 2012-04-10T06:10:30-04:00[America/New_York]
</script>

在真正的 Java 本质中,它非常冗长,哈哈。但是,作为一个移植的 java 库,特别是考虑到他们移植了 1800'ish 测试用例,它也可能非常准确地工作。

计时操作很难。这就是为什么许多其他库在边缘情况下存在缺陷的原因。Moment.js 似乎得到了正确的时区,但我见过的其他 js 库,包括timezone-js,似乎并不值得信赖。

于 2017-12-14T00:14:19.063 回答
0

只需设置您想要的国家时区,您就可以轻松地在 html 中显示它每分钟后使用 SetInteval() 函数更新。函数 formatAMPM() 管理 12 小时格式和 AM/PM 时间显示。

$(document).ready(function(){
        var pakTime = new Date().toLocaleString("en-US", {timeZone: "Asia/Karachi"});
        pakTime = new Date(pakTime);

        var libyaTime = new Date().toLocaleString("en-US", {timeZone: "Africa/Tripoli"});
        libyaTime = new Date(libyaTime);



         document.getElementById("pak").innerHTML = "PAK  "+formatAMPM(pakTime);
         document.getElementById("ly").innerHTML = "LY   " +formatAMPM(libyaTime);

        setInterval(function(today) {
            var pakTime = new Date().toLocaleString("en-US", {timeZone: "Asia/Karachi"});
            pakTime = new Date(pakTime);

            var libyaTime = new Date().toLocaleString("en-US", {timeZone: "Africa/Tripoli"});
            libyaTime = new Date(libyaTime);


           document.getElementById("pak").innerHTML = "PAK  "+formatAMPM(pakTime);
           document.getElementById("ly").innerHTML = "LY  " +formatAMPM(libyaTime);

        },10000);

         function formatAMPM(date) {
            var hours = date.getHours();
            var minutes = date.getMinutes();
            var ampm = hours >= 12 ? 'pm' : 'am';
            hours = hours % 12;
            hours = hours ? hours : 12; // the hour '0' should be '12'
            minutes = minutes < 10 ? '0'+minutes : minutes;
            var strTime = hours + ':' + minutes + ' ' + ampm;
            return strTime;
        }


    });
于 2020-04-04T12:01:46.220 回答
0

所有这些答案都有些多余,但这对我来说可以获取具有特定小时偏移量的当前 Date 对象。

 function hourToMs(hour)
    {
        return hour * 60 * 1000 * 60;
    }
    
    function minToMs(min)
    {
        return min * 60 * 1000;
    }
    
    function getCurrentDateByOffset(offset)
    {
        // Get the current timezone in milliseconds to reset back to GMT aka +0
        let timezoneOffset = minToMs((new Date()).getTimezoneOffset());
        
        // get the desired offset in milliseconds, invert the value because javascript is dum
        let desiredOffset = hourToMs(offset * -1);
    
        return new Date(Date.now() + timezoneOffset - desiredOffset);
    }
    
    // -6 hours is central timezone
    console.log("The time is: " + getCurrentDateByOffset(-6));

于 2021-03-13T19:15:05.063 回答
0

我在使用Moment Timezone 时遇到问题。我添加这个答案只是为了如果其他人面临同样的问题。所以我有一个日期字符串2018-06-14 13:51:00来自我的API. 我知道这是存储的,UTC但字符串本身并不能说明问题。

我让时刻时区知道,这个日期来自哪个时区:

let uTCDatetime = momentTz.tz("2018-06-14 13:51:00", "UTC").format();
// If your datetime is from any other timezone then add that instead of "UTC"
// this actually makes the date as : 2018-06-14T13:51:00Z

现在我想通过执行以下操作将其转换为特定时区:

let dateInMyTimeZone = momentTz.tz(uTCDatetime, "Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");
// now this results into: 2018-06-14 19:21:00, which is the corresponding date in my timezone.
于 2018-06-06T13:54:04.710 回答
-1

Time Zone Offset for your current timezone

date +%s -d '1 Jan 1970'

For my GMT+10 timezone (Australia) it returned -36000

于 2018-02-15T04:49:47.983 回答
-7

快速而肮脏的手动小时更改器和返回:

return new Date(new Date().setHours(new Date().getHours()+3)).getHours()
于 2019-07-13T04:36:19.367 回答