Tarih / saati kullanıcının yerel ayar biçiminde ve saat ofsetinde görüntüleme


167

Sunucunun her zaman HTML'de UTC'de tarihler sunmasını ve istemci sitesinde JavaScript'i kullanıcının yerel saat dilimine dönüştürmesini istiyorum.

Kullanıcının yerel tarih biçiminde çıktı alabilirsem bonus.

Yanıtlar:


165

Bir UTC tarihiyle başlamanın en kusursuz yolu yeni bir Datenesne oluşturmak ve setUTC…bunu istediğiniz tarihe / saate ayarlamak için yöntemleri kullanmaktır .

Sonra çeşitli toLocale…Stringyöntemler yerel çıktı sağlayacaktır.

Misal:

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

Bazı referanslar:


1
Firefox'ta, toLocateDateString()
'12

1
Hmm evet, bu oldukça ciddi bir problem. Tarihin tarayıcılarda aynı görünmesini istiyorsanız bu yöntemleri kullanmak işe yaramaz. Bilinen alternatifler var mı?
Josh Mc

6
Yukarıdaki başlatmanın tek satırlı sürümü:var d = new Date(Date.UTC(2004,1,29,2,45,26));
m1kael

4
Chrome'un (v35 itibariyle), kullanıcının toLocaleString()işlevlerdeki yerel ayarını dikkate almadığını düşünmeye değer olabilir .
benno

8
Üzgünüm ama bu yöntem (Avustralya'da değilim) altında çalışmıyor, yukarıdaki kodu çalıştırdığımda tarih ABD biçiminde görüntülenir. Ayrıca MDN , 'kullanılan yerel ayar ve döndürülen dizenin biçimi tamamen uygulamaya bağlıdır' diyor.
tgrrr

65

Yeni projeler için moment.js'yi kullanın

Bu soru oldukça eski, bu yüzden moment.js o sırada yoktu, ancak yeni projeler için bu gibi görevleri çok basitleştiriyor.

Tarih dizenizi UTC'den aşağıdaki gibi ayrıştırmak en iyisidir ( tüm tarayıcılarda tutarlı sonuçlar elde etmek için sunucuda ISO-8601 uyumlu bir dize oluşturun ):

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

Şimdi muygulamanızda kullanın , moment.js, görüntüleme işlemleri için varsayılan olarak yerel saat dilimini kullanır. Tarih ve saat değerlerini biçimlendirmenin veya bölümlerini ayıklamanın birçok yolu vardır .

Hatta bir moment nesnesini kullanıcıların yerel ayarında şu şekilde biçimlendirebilirsiniz:

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

Bir moment.js nesnesini farklı bir saat dilimine (yani ne yerel ne de UTC) dönüştürmek için moment.js saat dilimi uzantısına ihtiyacınız olacaktır . Bu sayfanın bazı örnekleri de var, kullanımı oldukça basit.


Tüm bunları nasıl birleştiriyorsunuz? m.utcOffset (offset) .format ('LLL') çalışmıyor.
Bart

Luxon veya Day.js önerilen kitaplık mı olmalı ?
Homer

1
Ben eklemeyi öneririmFor old projects, just use jQuery
Xenos

Krom üzerinde çalışmıyor - bilgisayarın yerel ayarlarında zaman 24 saat olarak ayarlanmış olmasına rağmen hala am / pm gösteriyor
vir us

20

new Date().getTimezoneOffset()/60Saat dilimi için kullanabilirsiniz . toLocaleString()Kullanıcının yerel ayarını kullanarak bir tarih görüntüleme yöntemi de vardır .

İşte tüm liste: Tarihlerle Çalışma


toLocaleString , tarihleri ​​kullanıcının beklediği biçimde sunmak için son derece güvenilir değildir. ISO 402'nin desteklendiği yerlerde bile, hala çok güvenilmezdir ve formatı bir yerel ayara değil bir dile dayandırır.
RobG

@RobG yerine çözüm toLocaleStringnedir?
user924

@ user924 — bir kütüphane kullanabilirsiniz, aralarından seçim yapabileceğiniz çok şey vardır. ToLocaleString ile ilgili sorun , farklı uygulamaların farklı diller ve bölgeler için farklı destek seviyeleriyle farklı sonuçlar vermesidir . Örneğin, sistemimin varsayılan dili en-US değil ancak bazı tarayıcılar için toLocaleString için varsayılan biçim ABD biçimidir, diğerleri ise sistem dilime saygı duyar . Saat dilimi adları ile aynı, sadece standartlaştırılmadıklarından daha kötü. :-(
RobG

7

Tarih nesnenizi oluşturduktan sonra, dönüşüm için bir snippet:

İşlev UTC formatlı bir Date nesnesi ve format dizesi alır.
Bir Date.strftimeprototipe ihtiyacınız olacak .

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

    return d.strftime(format);
}

6
strftime nereden geldin
Anuj Pandey

Saat ayarının bir Date nesnesinin Gün / Tarih / Yıl bölümleri üzerinde herhangi bir etkisi var mı? Öyle görünmüyor.
ChristoKiwi

1
@ ChristoKiwi - setHours'a iletilen değerin bir tamsayı olması beklenir getTimezoneOffset()/60(örneğin, +05: 30 Hindistan ötelemesi 5.5 değerini döndürür). Ondalık sayılar kesilir. Aksi takdirde, saatlerin ayarlanması diğer değerleri günceller (saatleri 48 olarak ayarlayın ve ne olduğunu görün).
Rob

7

JS'de, her bir mülkü yukarıda belirtildiği gibi dönüştürmenin dışında, yerel tarih saatini biçimlendirmenin basit ve çapraz platform yolları yoktur.

İşte yerel YYYY-AA-GG almak için kullandığım hızlı bir kesmek. Nihai tarih artık doğru saat dilimine sahip olmayacağından, bunun bir saldırı olduğunu unutmayın (bu nedenle saat dilimini yok saymanız gerekir). Başka bir şeye ihtiyacım olursa moment.js kullanıyorum.

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)

D.getTimezoneOffset (), saat dilimi uzaklığını dakika cinsinden döndürür ve d.getTime (), ms cinsindendir, dolayısıyla x 60.000'dir.


1
@VG 60k'nın nereden geldiği hakkında biraz daha bilgi ekledim. Umarım bu yardım.
Jeremy Chone

5

Geçmiş projelerde kullandıklarım:

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

4
Bu ASP.NET'e özgü şeyler için geçerlidir.
ZiggyTheHamster

Saat dilimi ofsetleri bir saatin katları olmak zorunda değildir, bu nedenle getTimezoneOffset()/60genellikle ondalık bir değer döndürür. Bu, özellikle birçok yerin dakikalar ve saniyeler içinde ofsetleri olduğu 1900'den önceki tarihler için geçerlidir. Ayrıca, javascript Tarihlerinin artık geçmiş ofsetleri desteklemesi gerekiyor. Örneğin 1890'da Moskova'daki ofset +2: 30: 17 idi. Bkz. Tarayıcılar, saat dilimleri, Chrome 67 Hatası .
RobG

3

.getTimezoneOffset()Yöntem bir yaygın alışık olduğu şeye negatif olan bir ofset değerini ortaya çıkarır GMT / UTC saat dilimine birkaç dakika mesafede bulunan sayma "Westwards" ofset dilimini bildirir. (Örnek, New York zamanının +240 dakika veya +4 saat olduğu rapor edilir)

Saat cinsinden normal bir saat dilimi farkı elde etmek için şunları kullanmanız gerekir:

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

Önemli ayrıntı:
Gün ışığından yararlanma zamanının sonuca katıldığını unutmayın - bu nedenle bu yöntemin size sağladığı gerçek zaman dilimi farkı değil , gerçekten de zaman farkıdır.


3

PHP kod tarihi ile böyle bir şey kullandım ..

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

Buna böyle diyebiliriz

var localdateObj = getLocalDate('2015-09-25T02:57:46');

Soru PHP ile değil JavaScript ile ilgiliydi.
pipedreambomb

5
Yanıt sadece javascripttir, Sunucu tarihinin UTC olduğu söylenir. böylece sunucu herhangi bir dilde olabilir. bu yüzden sadece PHP için cevap verdim
hriziya

3

Şimdiye kadar cevapları karıştırıyorum ve ekliyorum, çünkü hepsini okumak ve kullanıcının yerel saat dilimi biçiminde db'den bir tarih saati dizesi görüntülemek için bir süre daha araştırmak zorunda kaldım.

Datetime dizesi bir python / django db biçiminde gelir: 2016-12-05T15: 12: 24.215Z

JavaScript'te tarayıcı dilinin güvenilir bir şekilde algılanması tüm tarayıcılarda çalışmıyor gibi görünüyor ( tarayıcı dili tercihini tespit etmek için JavaScript'e bakın ), bu yüzden tarayıcı dilini sunucudan alıyorum.

Python / Django: istek tarayıcı dilini bağlam parametresi olarak gönder:

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

HTML: gizli bir girişe yazın:

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

JavaScript: gizli girişin değerini alın, örneğin en-GB, en-US; q = 0,8, en; q = 0,6 / ve ardından listedeki ilk dili yalnızca değiştir ve normal ifade ile al

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

JavaScript: datetime'a dönüştürün ve formatlayın:

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

Bkz. Https://developer.mozilla.org/tr/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

Sonuç (tarayıcı dili en-gb'dir): 05/12/2016, 14:58


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


Referans için: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… (Davam için optionsparçaya ihtiyacım vardı )
Xenos

2

Karşılaştığım en iyi çözüm [time display = "llll" datetime = "UTC TIME" /] Etiketleri oluşturmak ve kullanıcının zamanına göre ayrıştırmak ve görüntülemek için javascript (jquery) kullanmaktır.

http://momentjs.com/ Moment.js

zamanı güzel gösterecektir.


2

GMT'den saat dilimi uzaklığını dakikalar içinde bildiren aşağıdakileri kullanabilirsiniz:

new Date().getTimezoneOffset();

Not: - bu işlev negatif bir sayı döndürür.



1

Tarihi yerel tarihe dönüştürmek için toLocaleDateString () yöntemini kullanın.

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

Saati yerel saate dönüştürmek için toLocaleTimeString () yöntemini kullanın.

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);

-12

Yerel ayarların nasıl yapılacağını bilmiyorum, ancak javascript bir istemci tarafı teknolojisidir.

usersLocalTime = new Date();

istemcinin saat ve tarihini içerecektir (tarayıcıları tarafından bildirildiği gibi ve uzandıkları bilgisayar). Sunucunun zamanını yanıta dahil etmek ve zaman-dengelemeyi tahmin etmek için bazı basit matematik işlemleri yapmak önemsiz olmalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.