Chuyển đổi UTC Epoch sang ngày địa phương


272

Tôi đã chiến đấu với điều này một chút bây giờ. Tôi đang cố gắng chuyển đổi epoch thành một đối tượng ngày. Kỷ nguyên được gửi cho tôi trong UTC. Bất cứ khi nào bạn vượt qua new Date()một kỷ nguyên, nó sẽ thừa nhận đó là kỷ nguyên địa phương. Tôi đã thử tạo một đối tượng UTC, sau đó sử dụng setTime()để điều chỉnh nó theo đúng thời gian, nhưng phương pháp duy nhất có vẻ hữu ích là toUTCString()và các chuỗi không giúp tôi. Nếu tôi chuyển chuỗi đó sang một ngày mới, nó sẽ nhận thấy rằng đó là UTC, nhưng nó không.

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

Nỗ lực tiếp theo của tôi là cố gắng để có được sự khác biệt giữa kỷ nguyên hiện tại địa phương và kỷ nguyên hiện tại UTC, nhưng tôi cũng không thể có được điều đó.

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

Nó chỉ mang lại cho tôi những khác biệt rất nhỏ, dưới 1000, tính bằng mili giây.

Bất kỳ đề xuất?


11
Thời gian kỷ nguyên được định nghĩa là một phần nghìn giây kể từ ngày 1970 trong UTC . Không có thứ gọi là kỷ nguyên địa phương! Không chắc chắn tôi hiểu vấn đề của bạn.
Chetan Sastry

Có lẽ múi giờ trên máy tính không chính xác, dẫn đến một giá trị UTC khác?
kijin

2
Bạn phải đặt đồng hồ theo giờ UTC, nếu bạn muốn 'xem' thời gian UTC khi bạn sử dụng toLocaleString (). Nửa đêm UTC là 7 giờ tối EST. Nếu bạn sử dụng Ngày mới (). ToString () thay vì localeString, bạn sẽ nhận được một cái gì đó như: 'Thứ Sáu ngày 07 tháng 1 năm 2011 07:00:00 GMT-0500', bao gồm phần bù.
kennebec

Câu trả lời:


462

Tôi nghĩ rằng tôi có một giải pháp đơn giản hơn - đặt ngày ban đầu thành epoch và thêm các đơn vị UTC. Giả sử bạn có var var UTC được lưu trữ trong vài giây. Thế còn 1234567890. Để chuyển đổi ngày đó thành một ngày thích hợp trong múi giờ địa phương:

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 bây giờ là một ngày (trong múi giờ của tôi) được đặt thành Fri Feb 13 2009 18:31:30 GMT-0500 (EST)


189
FWIW, các đối tượng Date có thể được khởi tạo với mili giây. Vì vậy, var d = new Date(utcSeconds * 1000)nên mang lại kết quả tương tự.
xe đạp

54
var d = new Date(1234567890000)trả về kết quả tương tự
Matjaz Lipus 6/214

11
nghĩ rằng có lẽ những người khác có thể nhận được một số sự rõ ràng từ một vài điểm: đối tượng ngày không được thiết lập với múi giờ "được đóng dấu trong đó". nghĩ về nó như không có gì ngoài một con số con số đó là số mili giây kể từ 1970 jan 1 UTC, đến nay (bây giờ cũng ở UTC). Vì vậy, bất cứ khi nào bạn tạo một đối tượng ngày, nó thực sự ở UTC phía sau hậu trường. 2. Để hiển thị ngày đó, bạn có thể hiển thị nó dưới dạng cài đặt ngôn ngữ (toLocaleString () hoặc, trong UTC (toUTCString ()). Bạn không cần phải tự chuyển đổi bất cứ thứ gì. Xây dựng với utc millisec, tất cả đều tốt. chuỗi - miễn là nó ở múi giờ địa phương.
da Bích

2
1234567890000 được đối xử giống như 1234567890, còn gọi là sự cố Y39K ...
muttonUp

1
@muttonUp, với 1000 mulitplication nó hoạt động. Nhưng, 'vấn đề Y39K "google không đưa ra bất kỳ kết quả hợp lệ nào. Mọi URL sẽ hữu ích
P Satish Patro

236

Thật dễ dàng, new Date()chỉ mất một phần nghìn giây, vd

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

6
Đẹp quá Điều này nên được coi là câu trả lời được chấp nhận thực sự.
Nizar B.

Cái này không hoạt động với tôi, nó hoạt động khi bạn có dấu thời gian nhưng với epc utc bạn phải đặt utcseconds bằng tay, câu trả lời chấp nhận là câu trả lời đúng
sameerali

12
Đây là một câu trả lời thích hợp. Ngày mới có thể mất một phần nghìn giây, do đó chỉ cần nhân với 1000 : const d = new Date(epoch * 1000).
vinyll

@sameerali Có lẽ bạn đã gặp một số vấn đề khác với hệ thống của mình hoặc bạn đã nhầm lẫn. Câu trả lời này là câu trả lời đúng. Định nghĩa của kỷ nguyên Unix: số giây trôi qua kể từ UTC nửa đêm ngày 1 tháng 1 . Chỉ cần nhân với 1000 để có được số mili giây trôi qua.
nalply

32

Và chỉ với nhật ký, tôi đã làm điều này bằng thư viện Moment.js , cái mà tôi đang sử dụng để định dạng.

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

1
Khoảnh khắc thật tuyệt, nhưng thật điên rồ khi sử dụng thư viện 1,3 MB để chỉ chuyển đổi một epoch thành một ngày. Không có gì ngạc nhiên khi có rất nhiều ứng dụng nút cồng kềnh ngoài kia.
not2qubit

20

Thời gian kỷ nguyên tính bằng giây từ ngày 1 tháng 1 năm 1970. date.getTime()trả về mili giây từ ngày 1 tháng 1 năm 1970, vì vậy .. nếu bạn có dấu thời gian epoch, hãy chuyển đổi nó thành dấu thời gian javascript bằng cách nhân 1000.

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

Đã tự hỏi những gì trên trái đất đã lên. Rất tốt để biết rằng epochTime! == javascriptTime khi nói đến phân tích ngày. Cảm ơn!
GrayedFox

16
 function ToLocalDate (inDate) {
    var date = new Date();
    date.setTime(inDate.valueOf() - 60000 * inDate.getTimezoneOffset());
    return date;
}

1
Bạn làm cho ngày của tôi. TY. Tôi chỉ thay thế dấu trừ bằng dấu cộng cho công việc của mình.
Ludovic Kuty

5

Để chuyển đổi thời gian kỷ nguyên hiện tại trong [ms] thành thời gian 24 giờ. Bạn có thể cần chỉ định tùy chọn để tắt định dạng 12 giờ .

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

2/7/2018, 19:35:24

hoặc là JS:

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

Lưu ý: Việc sử dụng en-GBở đây, chỉ là sự lựa chọn (ngẫu nhiên) của một địa điểm sử dụng định dạng 24 giờ, đó không phải là múi giờ của bạn!


1
Đây là cách tốt nhất để nhận bất kỳ loại chuyển đổi nào từ phương thức Ngày. Cảm ơn!
SeaWar Warrior404

Điều duy nhất tôi không thích với ở trên, là nó trả về ngày ở định dạng mơ hồ d/m/yyyyhoặc là nó m/d/yyyy? Cách đúng (hợp lý nhất) để hiển thị này phải là : yyyy-mm-dd. Có ai nhận không?
not2qubit

4

Thời gian kỷ nguyên (tức là thời gian Epoch Unix) gần như luôn luôn là số giây đã hết hạn kể từ ngày 1 tháng 1 năm 1970 00:00:00 (giờ UTC), không phải là số mili giây mà một số câu trả lời ở đây đã ngụ ý.

https://en.wikipedia.org/wiki/Unix_time

Do đó, nếu bạn đã được cung cấp một giá trị thời gian Unix Epoch, nó có thể sẽ tính bằng giây và sẽ trông giống như vậy 1547035195. Nếu bạn muốn làm cho con người này có thể đọc được bằng JavaScript, bạn cần chuyển đổi giá trị thành mili giây và chuyển giá trị đó vào hàm Date(value)tạo, ví dụ:

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

Bạn không cần thực hiện d.setUTCMilliseconds(0)bước trong câu trả lời được chấp nhận vì hàm tạo JavaScript Date(value)lấy giá trị UTC tính bằng mili giây (không phải giờ địa phương).

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

Cũng lưu ý rằng bạn nên tránh sử dụng hàm Date(...)tạo có biểu diễn chuỗi thời gian chuỗi, điều này không được khuyến nghị (xem liên kết ở trên).


3

Bạn chỉ yêu cầu chuyển đổi một chuỗi UTC thành một chuỗi "cục bộ"? Bạn có thể làm:

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

3

Bổ sung cho câu trả lời trên của @djechlin

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

chuyển đổi thời gian EPOCH thành ngày có thể đọc được của con người. Chỉ cần đừng quên rằng loại thời gian EPOCH phải là một số nguyên.


3

Giải pháp đơn giản nhất mà tôi tìm thấy cho vấn đề này là:

var timestamp = Date.now(), // returns milliseconds since epoch time
    normalisedTime = new Date(timestamp);

Lưu ý rằng điều này không có phần * 1000cuối của new Date(timestamp)tuyên bố vì điều này (đối với tôi dù thế nào đi nữa!) Dường như luôn đưa ra ngày sai, tức là thay vì đưa ra năm 2019, nó đưa ra năm là 51015, vì vậy hãy ghi nhớ điều đó.


2

Nếu bạn muốn giải quyết dấu thời gian và ngày chuyển đổi từ và sang UTC và giờ địa phương mà không có thư viện như khoảnh khắc.js, hãy xem tùy chọn bên dưới.

Đối với các ứng dụng sử dụng dấu thời gian UTC, bạn có thể cần hiển thị ngày trong trình duyệt xem xét múi giờ địa phương và tiết kiệm ánh sáng ban ngày khi áp dụng. Chỉnh sửa một ngày trong một thời gian tiết kiệm ánh sáng ban ngày khác nhau mặc dù trong cùng một múi giờ có thể khó khăn.

Các NumberDatephần mở rộng bên dưới cho phép bạn hiển thị và nhận được số ngày trong múi giờ của timestamps. Ví dụ: giả sử bạn đang ở Vancouver, nếu bạn đang chỉnh sửa một ngày vào tháng 7 hoặc tháng 12, điều đó có nghĩa là bạn đang chỉnh sửa một ngày bằng PST hoặc PDT.

Tôi khuyên bạn nên kiểm tra Đoạn mã dưới đây để kiểm tra giải pháp này.

Chuyển đổi từ mili giây

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

Chuyển đổi từ ngày

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

Sử dụng

// Adds the timezone and daylight savings if applicable
(1499670000000).toLocalDate();

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

Xem nó cho chính mình


Đây là câu trả lời thực tế. Làm việc như một cơ duyên đối với tôi. Đặt Ngày mới (0) và thêm mili giây cũng giống như Ngày mới (mili giây)
Jersey_Guy

1

BIÊN TẬP

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

EDIT cố định


Tôi đã trải qua điều này trong ví dụ thứ hai của tôi. Sự khác biệt mà nó mang lại cho tôi là ở khoảng giữa 50 và 900, tính bằng milisecond (hiển thị thời gian trong khi xử lý phép tính, không phải là sự khác biệt thực tế)
Shane Reustle

Không ai trong số họ giúp tôi. Họ đang thiếu một phương thức setUTCTime, sẽ rất hoàn hảo: P w3schools.com/jsref/jsref_obj_date.asp
Shane Reustle

Không hoạt động, ít nhất là trên Firefox cho Ubuntu. Mã không nên đặt ngày / tháng / năm sau khi đặt ngày.
Simon Kozlov

@Simon Kozlov Trên thực tế đó là một giả định sai trong đối tượng ngày, setDate và getDate đề cập đến ngày trong tháng và vấn đề là tôi đã sử dụng các hàm như (setUTCDay) không tồn tại, thật ngạc nhiên khi nó được chấp nhận !!
Amjad Masad

@AmjadMasad Câu trả lời của bạn sẽ hữu ích hơn nếu bạn cũng hiển thị đầu ra dự kiến.
not2qubit

0

Xem xét, bạn có epoch_timesẵn,

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


0

@Amjad, ý tưởng tốt, nhưng thực hiện tốt hơn sẽ là:

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

Đầu tiên chuyển đổi nó thành Chuỗi và sau đó thay thế văn bản múi giờ.

function convertUnixTime(time) {
  return new Date(time*1000).toString().replace("GMT+0530 (Sri Lanka Standard Time)","");
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.