Menampilkan tanggal / waktu dalam format lokal pengguna dan waktu offset

167

Saya ingin server selalu menyajikan tanggal dalam UTC dalam HTML, dan meminta JavaScript di situs klien untuk mengubahnya menjadi zona waktu lokal pengguna.

Bonus jika saya bisa menampilkan dalam format tanggal lokal pengguna.

kch
sumber

Jawaban:

165

Tampaknya cara yang paling mudah untuk memulai dengan tanggal UTC adalah dengan membuat Dateobjek baru dan menggunakansetUTC… metode untuk mengaturnya ke tanggal / waktu yang Anda inginkan.

Lalu bermacam-macam toLocale…String metode akan memberikan keluaran lokal.

Contoh:

// This would come from the server.
// Also, this whole block could probably be made into an mktime function.
// All very bare here for quick grasping.
d = new Date();
d.setUTCFullYear(2004);
d.setUTCMonth(1);
d.setUTCDate(29);
d.setUTCHours(2);
d.setUTCMinutes(45);
d.setUTCSeconds(26);

console.log(d);                        // -> Sat Feb 28 2004 23:45:26 GMT-0300 (BRT)
console.log(d.toLocaleString());       // -> Sat Feb 28 23:45:26 2004
console.log(d.toLocaleDateString());   // -> 02/28/2004
console.log(d.toLocaleTimeString());   // -> 23:45:26

Beberapa referensi:

kch
sumber
1
Di Firefox, toLocateDateString()kembalikan sesuatu yang terlihat seperti 'Minggu, 12 Januari 2014' ..
BlueRaja - Danny Pflughoeft
1
Hmm ya, ini masalah yang cukup serius. Menggunakan metode ini tidak akan berfungsi jika Anda ingin tanggal terlihat sama di seluruh browser. Adakah alternatif yang diketahui?
Josh Mc
6
Versi single-line dari inisialisasi di atas:var d = new Date(Date.UTC(2004,1,29,2,45,26));
m1kael
4
Mungkin patut dipertimbangkan bahwa Chrome (per v35) tidak memperhitungkan lokal pengguna dalam toLocaleString()fungsi.
benno
8
Saya minta maaf tetapi metode ini tidak bekerja di bawah (Saya di Australia), ketika saya menjalankan kode di atas tanggal ditampilkan dalam format AS. Lebih jauh MDN mengatakan 'lokal yang digunakan dan bentuk string yang dikembalikan sepenuhnya tergantung pada implementasi'.
tgrrr
65

Untuk proyek baru, cukup gunakan moment.js

Pertanyaan ini cukup lama, jadi moment.js tidak ada pada waktu itu, tetapi untuk proyek-proyek baru, itu sangat menyederhanakan tugas seperti ini.

Sebaiknya parsing string tanggal Anda dari UTC sebagai berikut (buat string yang kompatibel dengan ISO-8601 di server untuk mendapatkan hasil yang konsisten di semua browser):

var m = moment("2013-02-08T09:30:26Z");

Sekarang cukup gunakan mdalam aplikasi Anda, moment.js default ke zona waktu lokal untuk operasi tampilan. Ada banyak cara untuk memformat nilai tanggal dan waktu atau mengekstrak bagiannya.

Anda bahkan dapat memformat objek momen di lokal pengguna seperti ini:

m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us

Untuk mengubah objek moment.js menjadi zona waktu yang berbeda (yaitu bukan yang lokal atau UTC), Anda memerlukan ekstensi zona waktu moment.js . Halaman itu juga memiliki beberapa contoh, cukup mudah digunakan.

theDmi
sumber
Bagaimana Anda menggabungkan semua ini? m.utcOffset (offset) .format ('LLL') tampaknya tidak berfungsi.
Bart
Haruskah Luxon atau Day.js menjadi perpustakaan yang disarankan sekarang?
Homer
1
Saya sarankan menambahkanFor old projects, just use jQuery
Xenos
Tidak bekerja pada chrome - masih menunjukkan am / pm meskipun waktu diatur ke 24h dalam pengaturan lokal komputer
vir kami
20

Anda dapat menggunakan new Date().getTimezoneOffset()/60zona waktu. Ada juga toLocaleString()metode untuk menampilkan tanggal menggunakan lokal pengguna.

Berikut daftar lengkapnya : Bekerja dengan Tanggal

pel
sumber
toLocaleString sangat tidak bisa diandalkan untuk menyajikan tanggal dalam format yang mungkin diharapkan pengguna. Bahkan di mana ISO 402 didukung, itu masih sangat tidak dapat diandalkan dan mendasarkan format pada bahasa, bukan lokal.
RobG
@RobG apa solusinya alih-alih toLocaleString?
user924
@ user924 — Anda dapat menggunakan perpustakaan, ada banyak pilihan. Masalah dengan toLocaleString adalah implementasi yang berbeda memberikan hasil yang berbeda dengan tingkat dukungan yang berbeda untuk berbagai bahasa dan wilayah. Misalnya bahasa default sistem saya bukan en-US tetapi format default untuk toLocaleString untuk beberapa browser adalah format AS, yang lain menghargai bahasa sistem saya. Itu sama dengan nama zona waktu, hanya lebih buruk karena tidak dibakukan sama sekali. :-(
RobG
7

Setelah objek tanggal Anda dibuat, inilah cuplikan untuk konversi:

Fungsi ini mengambil objek Tanggal berformat UTC dan string format.
Anda akan membutuhkan Date.strftimeprototipe.

function UTCToLocalTimeString(d, format) {
    if (timeOffsetInHours == null) {
        timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1);
    }
    d.setHours(d.getHours() + timeOffsetInHours);

    return d.strftime(format);
}
simianarmy
sumber
6
dari mana Anda strftime?
Anuj Pandey
Apakah pengaturan jam berpengaruh pada bagian Hari / Tanggal / Tahun dari objek Tanggal? Sepertinya tidak.
ChristoKiwi
1
@ ChristoKiwi — nilai yang diteruskan ke setHours diharapkan berupa bilangan bulat getTimezoneOffset()/60dapat mengembalikan sebagian kecil (mis. India offset +05: 30 akan mengembalikan 5,5). Desimal terpotong. Jika tidak, pengaturan jam memperbarui nilai lain (atur jam ke 48 dan lihat apa yang terjadi).
RobG
7

Di JS tidak ada cara sederhana dan lintas platform untuk memformat waktu tanggal lokal, di luar konversi setiap properti seperti yang disebutkan di atas.

Ini adalah hack cepat yang saya gunakan untuk mendapatkan YYYY-MM-DD lokal. Perhatikan bahwa ini adalah peretasan, karena tanggal akhir tidak akan memiliki zona waktu yang benar lagi (jadi Anda harus mengabaikan zona waktu). Jika saya membutuhkan hal lain lagi, saya menggunakan moment.js.

var d = new Date();    
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000)
var yyyymmdd = t.toISOString().slice(0,0); 
// 2017-05-09T08:24:26.581Z (but this is not UTC)

The d.getTimezoneOffset () mengembalikan offset zona waktu dalam beberapa menit, dan d.getTime () dalam ms, maka x 60.000.

Jeremy Chone
sumber
1
@ VG Saya menambahkan beberapa info tentang dari mana 60k berasal. Semoga bantuan ini.
Jeremy Chone
5

Inilah yang saya gunakan dalam proyek sebelumnya:

var myDate = new Date();
var tzo = (myDate.getTimezoneOffset()/60)*(-1);
//get server date value here, the parseInvariant is from MS Ajax, you would need to do something similar on your own
myDate = new Date.parseInvariant('<%=DataCurrentDate%>', 'yyyyMMdd hh:mm:ss');
myDate.setHours(myDate.getHours() + tzo);
//here you would have to get a handle to your span / div to set.  again, I'm using MS Ajax's $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');
Menandai
sumber
4
Ini dengan hal-hal khusus ASP.NET.
ZiggyTheHamster
Offset zona waktu bahkan tidak perlu kelipatan satu jam, jadi getTimezoneOffset()/60akan sering mengembalikan nilai desimal. Ini terutama berlaku untuk tanggal sebelum 1900, di mana banyak tempat memiliki offset dalam hitungan menit dan detik. Selain itu, Tanggal javascript sekarang diperlukan untuk mendukung offset historis. Misalnya pada tahun 1890 offset di Moskow adalah +2: 30: 17. Lihat Peramban, zona waktu, Kesalahan Chrome 67 .
RobG
3

The .getTimezoneOffset()Metode melaporkan zona waktu offset dalam menit, penghitungan "ke arah barat" dari zona waktu GMT / UTC, mengakibatkan nilai offset yang negatif dengan apa yang umumnya terbiasa. (Contoh, waktu New York akan dilaporkan +240 menit atau +4 jam)

Untuk mendapatkan offset zona waktu normal dalam jam, Anda perlu menggunakan:

var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60

Detail penting:
Perhatikan bahwa penghematan waktu siang hari diperhitungkan dalam hasil - jadi apa yang diberikan metode ini adalah offset waktu sebenarnya - bukan offset zona waktu geografis yang sebenarnya .

Már Örlygsson
sumber
3

Dengan tanggal dari kode PHP saya menggunakan sesuatu seperti ini ..

function getLocalDate(php_date) {
  var dt = new Date(php_date);
  var minutes = dt.getTimezoneOffset();
  dt = new Date(dt.getTime() + minutes*60000);
  return dt;
}

Kita bisa menyebutnya seperti ini

var localdateObj = getLocalDate('2015-09-25T02:57:46');
hriziya
sumber
Pertanyaannya adalah tentang JavaScript, bukan PHP.
pipedreambomb
5
Jawabannya hanya dalam javascript, Disebutkan dalam pertanyaan bahwa tanggal server adalah dalam UTC. jadi server bisa dalam bahasa apa saja. jadi saya jawab untuk PHP saja
hriziya
3

Saya mencampur jawaban sejauh ini dan menambahkannya, karena saya harus membaca semuanya dan menyelidiki tambahan untuk sementara waktu untuk menampilkan string waktu tanggal dari db dalam format zona waktu lokal pengguna.

String datetime berasal dari python / django db dalam format: 2016-12-05T15: 12: 24.215Z

Deteksi bahasa browser yang andal dalam JavaScript tampaknya tidak berfungsi di semua browser (lihat JavaScript untuk mendeteksi preferensi bahasa browser ), jadi saya mendapatkan bahasa browser dari server.

Python / Django: kirim bahasa browser permintaan sebagai parameter konteks:

language = request.META.get('HTTP_ACCEPT_LANGUAGE')
return render(request, 'cssexy/index.html', { "language": language })

HTML: tulis di input tersembunyi:

<input type="hidden" id="browserlanguage" value={{ language }}/>

JavaScript: dapatkan nilai input tersembunyi mis. En-GB, en-US; q = 0.8, en; q = 0.6 / dan kemudian ambil bahasa pertama dalam daftar hanya melalui ganti dan ekspresi reguler

const browserlanguage = document.getElementById("browserlanguage").value;
var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/, "$1");

JavaScript: konversikan ke datetime dan formatlah:

var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);

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

Hasilnya adalah (bahasa browser adalah en-gb): 05/12/2016, 14:58

Anja
sumber
3

// new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
var serverDate = new Date(2018, 5, 30, 19, 13, 15); // just any date that comes from server
var serverDateStr = serverDate.toLocaleString("en-US", {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
})
var userDate = new Date(serverDateStr + " UTC");
var locale = window.navigator.userLanguage || window.navigator.language;

var clientDateStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric'
});

var clientDateTimeStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
});

console.log("Server UTC date: " + serverDateStr);
console.log("User's local date: " + clientDateStr);
console.log("User's local date&time: " + clientDateTimeStr);

Sergey
sumber
Untuk referensi: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… (Saya membutuhkan optionsbagian untuk kasus saya)
Xenos
2

Solusi terbaik yang pernah saya temui adalah membuat tag [time display = "llll" datetime = "UTC TIME" /], dan menggunakan javascript (jquery) untuk mem-parsing dan menampilkannya relatif terhadap waktu pengguna.

http://momentjs.com/ Moment.js

akan menampilkan waktu dengan baik.

Daniel
sumber
2

Anda dapat menggunakan yang berikut ini, yang melaporkan zona waktu offset dari GMT dalam beberapa menit:

new Date().getTimezoneOffset();

Catatan: - fungsi ini mengembalikan angka negatif.

dave
sumber
1

getTimeZoneOffset () dan toLocaleString bagus untuk pekerjaan tanggal dasar, tetapi jika Anda membutuhkan dukungan zona waktu nyata, lihat TimeZone.js mde .

Ada beberapa opsi lagi yang dibahas dalam jawaban untuk pertanyaan ini

Aeon
sumber
1

Untuk mengonversi tanggal ke tanggal lokal, gunakan metode toLocaleDateString ().

var date = (new Date(str)).toLocaleDateString(defaultlang, options);

Untuk mengonversi waktu ke waktu lokal, gunakan metode toLocaleTimeString ().

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
Pembuat kode
sumber
-12

Tidak tahu bagaimana melakukan lokal, tetapi javascript adalah teknologi sisi klien.

usersLocalTime = new Date();

akan memiliki waktu dan tanggal klien di dalamnya (seperti yang dilaporkan oleh browser mereka, dan dengan ekstensi komputer tempat mereka duduk). Seharusnya sepele untuk memasukkan waktu server dalam respons dan melakukan beberapa matematika sederhana untuk menebak-mengimbangi waktu.

japollock
sumber