关于javascript:将UTC Epoch转换为本地日期

Convert UTC Epoch to local date

我已经为此斗争了一段时间了。我正在尝试将epoch转换为日期对象。这个时代是用UTC发给我的。每当你经过一个纪元,它就假定它是局部纪元。我尝试创建一个UTC对象,然后使用setTime()将其调整到适当的时代,但唯一有用的方法是toUTCString(),字符串对我没有帮助。如果我把这个字符串传递到一个新的日期,它应该注意到它是UTC,但它不是。

1
new Date( new Date().toUTCString() ).toLocaleString()

我的下一个尝试是尝试获得本地当前纪元和UTC当前纪元之间的差异,但我也不能得到。

1
new Date( new Date().toUTCString() ).getTime() - new Date().getTime()

它只给了我很小的差别,小于1000,以毫秒为单位。

有什么建议吗?


我想我有一个更简单的解决方案——将初始日期设置为epoch并添加UTC单位。假设您有一个以秒为单位存储的UTC epoch变量。埃多克斯1〔0〕怎么样。要将其转换为本地时区中的正确日期:

1
2
3
var utcSeconds = 1234567890;
var d = new Date(0); // The 0 there is the key, which sets the date to the epoch
d.setUTCSeconds(utcSeconds);

d现在是(在我的时区)设置为Fri Feb 13 2009 18:31:30 GMT-0500 (EST)的日期。


很简单,new Date()只需要几毫秒,例如

1
2
new Date(1394104654000)
> Thu Mar 06 2014 06:17:34 GMT-0500 (EST)


为了记录日志,我使用了moment.js库来完成这项工作,我使用它来格式化文件。

1
2
moment.utc(1234567890000).local()
>Fri Feb 13 2009 19:01:30 GMT-0430 (VET)


纪元时间是从1970年1月1日开始的秒数。date.getTime()从1970年1月1日返回毫秒,所以……如果您有一个epoch时间戳,将其转换为一个javascript时间戳,乘以1000。

1
2
3
4
5
6
7
8
9
10
11
   function epochToJsDate(ts){
        // ts = epoch timestamp
        // returns date obj
        return new Date(ts*1000);
   }

   function jsDateToEpoch(d){
        // d = javascript date obj
        // returns epoch timestamp
        return (d.getTime()-d.getMilliseconds())/1000;
   }


1
2
3
4
5
 function ToLocalDate (inDate) {
    var date = new Date();
    date.setTime(inDate.valueOf() - 60000 * inDate.getTimezoneOffset());
    return date;
}


以上答案由@djechlin补充

1
2
d = '1394104654000';
new Date(parseInt(d));

将纪元时间转换为人类可读的日期。别忘了,这类历元时间必须是整数。


您只是要求将UTC字符串转换为"本地"字符串吗?你可以这样做:

1
2
3
4
5
6
7
var utc_string = '2011-09-05 20:05:15';
var local_string = (function(dtstr) {
    var t0 = new Date(dtstr);
    var t1 = Date.parse(t0.toUTCString().replace('GMT', ''));
    var t2 = (2 * t0) - t1;
    return new Date(t2).toString();
})(utc_string);


我找到的最简单的解决方案是:

1
2
var timestamp = Date.Now()    
var normalisedTime = new Date(timestamp)

注意,在new Date(timestamp)声明的末尾没有* 1000作为这个(无论如何对我来说!)似乎总是给出错误的日期,即不是给出2019年,而是给出51015年,所以请记住。


epoch time(即unix epoch time)几乎总是1970年1月1日00:00:00(UTC时间)后过期的秒数,而不是这里的某些答案所暗示的毫秒数。

https://en.wikipedia.org/wiki/unixu时间

因此,如果给您一个unix epoch时间值,它可能以秒为单位,看起来类似于1547035195。如果要让这个人在javascript中可读,需要将值转换为毫秒,并将该值传递给Date(value)构造函数,例如:

1
2
3
4
const unixEpochTimeMS = 1547035195 * 1000;
const d = new Date(unixEpochTimeMS);
// Careful, the string output here can vary by implementation...
const strDate = d.toLocaleString();

您不需要在接受的答案中执行d.setUTCMilliseconds(0)步骤,因为javascript Date(value)构造函数以毫秒(而不是本地时间)为单位获取UTC值。

https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_-objects/date语法

还要注意,您应该避免使用采用字符串日期时间表示的Date(...)构造函数,这是不推荐的(请参见上面的链接)。


以[ms]为单位将当前纪元时间转换为24小时时间。您可能需要指定禁用12小时格式的选项。

1
2
3
$ node.exe -e"var date = new Date(Date.now()); console.log(date.toLocaleString('en-GB', { hour12:false } ));"

2/7/2018, 19:35:24

或作为JS:

1
2
3
4
5
6
var date = new Date(Date.now());
console.log(date.toLocaleString('en-GB', { hour12:false } ));
// 2/7/2018, 19:35:24

console.log(date.toLocaleString('en-GB', { hour:'numeric', minute:'numeric', second:'numeric', hour12:false } ));
// 19:35:24

注:这里使用en-GB,只是(随机)选择一个24小时格式的地点,它不是你的时区!


如果您更喜欢在不使用诸如moment.js之类的库的情况下,解析从UTC到本地时间的时间戳和日期转换,请查看下面的选项。

对于使用UTC时间戳的应用程序,可能需要考虑本地时区和夏令时(如果适用),在浏览器中显示日期。即使在同一时区,编辑处于不同夏令时的日期也很棘手。

下面的NumberDate扩展允许您在时间戳的时区中显示和获取日期。例如,假设您在温哥华,如果您在7月或12月编辑一个日期,这可能意味着您正在用pst或pdt编辑一个日期。

我建议您检查下面的代码片段来测试这个解决方案。

毫秒转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Number.prototype.toLocalDate = function () {
    var value = new Date(this);

    value.setHours(value.getHours() + (value.getTimezoneOffset() / 60));

    return value;
};

Number.prototype.toUTCDate = function () {
    var value = new Date(this);

    value.setHours(value.getHours() - (value.getTimezoneOffset() / 60));

    return value;
};

从日期转换

1
2
3
Date.prototype.getUTCTime = function () {
    return this.getTime() - (this.getTimezoneOffset() * 60000);
};

用法

1
2
3
4
5
// Adds the timezone and daylight savings if applicable
(1499670000000).toLocalDate();

// Eliminates the timezone and daylight savings if applicable
new Date(2017, 6, 10).getUTCTime();

你自己看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Extending Number

Number.prototype.toLocalDate = function () {
    var value = new Date(this);

    value.setHours(value.getHours() + (value.getTimezoneOffset() / 60));

    return value;
};

Number.prototype.toUTCDate = function () {
    var value = new Date(this);

    value.setHours(value.getHours() - (value.getTimezoneOffset() / 60));

    return value;
};

// Extending Date

Date.prototype.getUTCTime = function () {
    return this.getTime() - (this.getTimezoneOffset() * 60000);
};

// Getting the demo to work
document.getElementById('m-to-local-button').addEventListener('click', function () {
  var displayElement = document.getElementById('m-to-local-display'),
      value = document.getElementById('m-to-local').value,
      milliseconds = parseInt(value);
 
  if (typeof milliseconds === 'number')
    displayElement.innerText = (milliseconds).toLocalDate().toISOString();
  else
    displayElement.innerText = 'Set a value';
}, false);

document.getElementById('m-to-utc-button').addEventListener('click', function () {
  var displayElement = document.getElementById('m-to-utc-display'),
      value = document.getElementById('m-to-utc').value,
      milliseconds = parseInt(value);
 
  if (typeof milliseconds === 'number')
    displayElement.innerText = (milliseconds).toUTCDate().toISOString();
  else
    displayElement.innerText = 'Set a value';
}, false);

document.getElementById('date-to-utc-button').addEventListener('click', function () {
  var displayElement = document.getElementById('date-to-utc-display'),
      yearValue = document.getElementById('date-to-utc-year').value || '1970',
      monthValue = document.getElementById('date-to-utc-month').value || '0',
      dayValue = document.getElementById('date-to-utc-day').value || '1',
      hourValue = document.getElementById('date-to-utc-hour').value || '0',
      minuteValue = document.getElementById('date-to-utc-minute').value || '0',
      secondValue = document.getElementById('date-to-utc-second').value || '0',
      year = parseInt(yearValue),
      month = parseInt(monthValue),
      day = parseInt(dayValue),
      hour = parseInt(hourValue),
      minute = parseInt(minuteValue),
      second = parseInt(secondValue);
 
  displayElement.innerText = new Date(year, month, day, hour, minute, second).getUTCTime();
}, false);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.11/semantic.css" rel="stylesheet"/>


  <p>

</p>
 
  Milliseconds to local date
  <input id="m-to-local" placeholder="Timestamp" value="0" /> <button id="m-to-local-button">Convert</button>
  Set a value

  Milliseconds to UTC date
  <input id="m-to-utc" placeholder="Timestamp" value="0" /> <button id="m-to-utc-button">Convert</button>
  Set a value
 
  Date to milliseconds in UTC
  <input id="date-to-utc-year" placeholder="Year" style="width: 4em;" />
  <input id="date-to-utc-month" placeholder="Month" style="width: 4em;" />
  <input id="date-to-utc-day" placeholder="Day" style="width: 4em;" />
  <input id="date-to-utc-hour" placeholder="Hour" style="width: 4em;" />
  <input id="date-to-utc-minute" placeholder="Minute" style="width: 4em;" />
  <input id="date-to-utc-second" placeholder="Second" style="width: 4em;" />
  <button id="date-to-utc-button">Convert</button>
  Set the values


编辑

1
2
3
4
5
6
7
8
var utcDate = new Date(incomingUTCepoch);
var date = new Date();
date.setUTCDate(utcDate.getDate());
date.setUTCHours(utcDate.getHours());
date.setUTCMonth(utcDate.getMonth());
date.setUTCMinutes(utcDate.getMinutes());
date.setUTCSeconds(utcDate.getSeconds());
date.setUTCMilliseconds(utcDate.getMilliseconds());

编辑固定


考虑到,你已经有了epoch_time

1
2
3
// for eg. epoch_time = 1487086694.213
var date = new Date(epoch_time * 1000); // multiply by 1000 for milliseconds
var date_string = date.toLocaleString('en-GB');  // 24 hour format


@AMJAD,好主意,但实施得不好。尝试

1
2
3
4
5
6
Date.prototype.setUTCTime = function(UTCTimestamp) {
    var UTCDate = new Date(UTCTimestamp);
    this.setUTCFullYear(UTCDate.getFullYear(), UTCDate.getMonth(), UTCDate.getDate());
    this.setUTCHours(UTCDate.getHours(), UTCDate.getMinutes(), UTCDate.getSeconds(), UTCDate.getMilliseconds());
    return this.getTime();
}

首先将其转换为字符串,然后替换时区文本。

1
2
3
function convertUnixTime(time) {
  return new Date(time*1000).toString().replace("GMT+0530 (Sri Lanka Standard Time)","");
}