Saat dilimi javascript olmadan ayrıştırma tarihi


147

JavaScript'te saat dilimi olmadan tarihi ayrıştırmak istiyorum. Denedim:

new Date(Date.parse("2005-07-08T00:00:00+0000"));

İade Cum 08 Temmuz 2005 02:00:00 GMT + 0200 (Orta Avrupa Yaz Saati)

new Date(Date.parse("2005-07-08 00:00:00 GMT+0000"));

Aynı sonucu döndürür

new Date(Date.parse("2005-07-08 00:00:00 GMT-0000"));

Aynı sonucu döndürür

Zamanı ayrıştırmak istiyorum:

  1. Zaman dilimi olmadan.

  2. Yapıcı Date.UTC veya yeni Tarihi (yıl, ay, gün) çağırmadan.

  3. Tarih yapıcısına basit bir dize (prototip yaklaşımları olmadan).

  4. Ürün Datenesnesine ihtiyacım var, değil String.


3
Sadece btw'yi atlayabilir Date.parseve dizeyi doğrudan yapıcıya iletebilirsiniz Date.
Bergi

1
Neden buna ihtiyacınız olduğundan emin değilim ama eminim Date her zaman kullanıcının yerel saat dilimi vardır. JavaScript'inizin Date için bir sarmalayıcı nesnesi kullanmanız gerekenden başka zaman dilimleriyle çalışmasını istiyorsanız, belki de bu sizin için işe yarayacaktır: github.com/mde/timezone-js
HMR

1
Ne yazık ki, DateMongoDB tarihleri ​​karşılaştırmak için doğru nesneyi elde etmek için nesne kopyalamak zorunda kaldı :new Date(dateStart.getFullYear(), dateStart.getMonth(), dateStart.getDate())
Athlan

Bir tarihi zaman olmadan ayrıştırmak istiyorsanız, hangi saat dilimini kabul etmek istediğinizi belirtmeniz gerekir, çünkü "2005-07-08" farklı saat dilimlerindeki farklı şeyler anlamına gelir. Mayıs 2020'den itibaren, MDN belgeleri uygulamadaki farklılıklar nedeniyle bu tarihte ayrıştırma özelliklerine karşı tavsiyede bulunmaktadır. Ancak, Date.parse ("2005-07-08") kullanıldığında, muhtemelen 00:00 UTC saati döndürülür. date-fns Öte yandan, aynı tarih dizesini ayrıştırırken 00:00 yerel saat dönecektir
Andy

Yanıtlar:


106

Tarih doğru şekilde ayrıştırılır, yalnızca yerel saat diliminize dönüştüren toString olur:

let s = "2005-07-08T11:22:33+0000";
let d = new Date(Date.parse(s));

// this logs for me 
// "Fri Jul 08 2005 13:22:33 GMT+0200 (Central European Summer Time)" 
// and something else for you

console.log(d.toString()) 

// this logs
// Fri, 08 Jul 2005 11:22:33 GMT
// for everyone

console.log(d.toUTCString())

Javascript Date nesnesi zaman damgalarıdır - çağdan beri yalnızca birkaç milisaniye içerirler. Bir Date nesnesinde saat dilimi bilgisi yoktur. Bu zaman damgasının hangi takvim tarihini (gün, dakika, saniye) temsil ettiği yorumlama konusudur ( to...Stringyöntemlerden biri ).

Yukarıdaki örnek, tarihin doğru bir şekilde ayrıştırıldığını gösterir - yani, aslında GMT'de "2005-07-08T11: 22: 33" e karşılık gelen bir milisaniye içerir.


4
Ne yazık ki ben String değil Date nesnesi üretmek zorunda.
Athlan

@Athlan: bazı açıklamalar ekledi.
georg

1
Ben kontrol etmiştim. Ben MongoDB sorgu içine çözümlü tarihi geçmiş new Date(Date.parse("2005-07-08T11:22:33+0000"))ve tarih yapıcısı aracılığıyla kopyalanan: new Date(dateStart.getFullYear(), dateStart.getMonth(), dateStart.getDate()). Her iki çözüm, farklı sonuçlar, ikinci doğru! Cevabınız yararlıydı , hunlock.com/blogs/Javascript_Dates-The_Complete_Reference içinde az önce bahsedildi . Yukarı.
Athlan

Benim için mükemmel çalıştı - .toUTCString () bana verilen orijinal dize doğru zaman verdi bilet oldu. yani yeni Tarih ("2016-08-22T19: 45: 00.0000000"). toUTCString ()
Michael Giovanni Pumo

38
JavaScript tarih ve saatlerindeki tüm kötülüklerin kökü ilk cümlede bulunur ... Sadece yerel saat diliminize dönüştürdüğünü söylemek ... Bunun tek sorumluluğu nerede? toString yöntemi sonucu dize etmeli ve dönüştürmemelidir. Tarih dönüştürülmesini istiyorsanız, bunu yapmak için başka yöntemler olmalıdır.
demir

109

Bende aynı sorun var. Dize olarak bir tarih alıyorum, örneğin: '2016-08-25T00: 00: 00', ancak Date nesnesi doğru zamanda olması gerekir. String nesnesine dönüştürmek için getTimezoneOffset kullanın:

var date = new Date('2016-08-25T00:00:00')
var userTimezoneOffset = date.getTimezoneOffset() * 60000;
new Date(date.getTime() - userTimezoneOffset);

getTimezoneOffset()eter negatif veya pozitif değer döndürür. Bu, dünyanın her yerinde çalışmak için çıkarılmalıdır.


6
Ben de aynı sorunu var ve yararlı buldum. Ancak, bunun gün ışığından yararlanma saati nedeniyle saat dilimi dengelemelerini gerçekleştirmediğini buldum. Örnek: PST'deyim, böylece GMT'deki şu anki dengelemem (Mart ayında) -8: 00, ancak Mayıs ayında -7: 00 olurdu. Benim çözümüm hesaplamak olduvar userTimezoneOffset = date.getTimezoneOffset()*60000;
mmh02 10:17

3
Tam bir aptal olmadıkça, bu aslında yanlış zamanı döndürür. getTimezoneOffset()dakika sayısını düşündüğünüz ters yönde döndürür - saat dilimim şu anda UTC-4'tür, ancak getTimezoneOffset()pozitif 240 döndürür. Bu nedenle userTimezoneOffset, çıkartılmalı date.getTime(), eklenmemelidir.
vaindil

1
Çıkarmanız gereken @vaindil ile anlaşacağım. wakwa'nın çözümü yalnızca Greenwich'in doğru tarafı olduğunuzda çalışır. Wakwas düzeltmelidir.
Janne Harju

1
Ah! çok erken konuştu. Çoğu zaman diliminde işe yaramıyor. GMT zamanı ile AEST ve CEST zamanlarını dengelerken yanlış bir tarih verdiğini onaylayabilirim.
saran3h

1
@vaindil şimdi sonuç aynı new Date('2016-08-25T00:00:00Z')olduğunu düşünüyorum noktası manipüle olduğunu new Date('2016-08-25T00:00:00Z')böylece yerel zaman 0:00 ile görüntülenir, ancak bu kod kaçırdıZ
barbsan

14

Aynı soruna rastladım ve üzerinde çalıştığım eski bir proje ve bu sorunu nasıl ele aldıkları hakkında sakat bir şey hatırladım. O zaman anlamadım ve problemle karşılaşıncaya kadar gerçekten umursamadım

var date = '2014-01-02T00:00:00.000Z'
date = date.substring(0,10).split('-')
date = date[1] + '-' + date[2] + '-' + date[0]

new Date(date) #Thu Jan 02 2014 00:00:00 GMT-0600

Herhangi bir nedenle '01 -02-2014 'olarak tarih geçilirse saat dilimi sıfıra ayarlanır ve kullanıcının saat dilimi yoksayılır. Bu, Date sınıfında bir fluke olabilir, ancak bir süre önce vardı ve bugün var oldu. Ve çapraz tarayıcı çalışıyor gibi görünüyor. Kendiniz deneyin.

Bu kod, zaman dilimlerinin çok önemli olduğu ancak tarihe bakan kişinin tam olarak tanıtıldığı anı umursamadığı küresel bir projede uygulanmaktadır.


Bence kasıtlı çünkü "Z", JS'nin sonradan dönüştürdüğü UTC'yi belirtir, ancak hiçbir zaman dilimi göz önüne alındığında, bu işlemin kullanıcının saat dilimini varsayar. Gerçi bazı onay veya daha iyi bir açıklama almak isterdim.
dlsso

7
Sakat davranışı kısa çizgilere bağlıdır. Chrome, Firefox ve IE11, 31 Mayıs 2014 00:00:00 GMT-0600 (Mountain Daylight Time) `olarak yorumlanır 2014/5/31ve 2014/05/31şu anki saat dilimimdir . 2014-05-31Çizgilerle ... tüm tarayıcılar 30 Mayıs 2014 Cuma olarak yorumlanır 18:00:00 GMT-0600 (Dağ Yaz Saati). Garip bir şekilde, 2014-5-31Chrome Cumartesi'yi, Firefox Cuma'yı döndürüyor ve IE11, tarihin geçersiz olduğunu söylüyor. date.replace('-','/')Hile yapacak bir şey gibi görünüyor .
atheaos

6

DateNesnenin kendisi zaten zaman dilimi içerecektir ve döndürülen sonuç varsayılan bir şekilde dizeye dönüştürme etkisidir. Yani saat dilimi olmadan bir tarih nesnesi oluşturamazsınız . Ama yapabileceğiniz şey, Datekendinizinkini yaratarak nesnenin davranışını taklit etmektir . Ancak, moment.js gibi kütüphanelere teslim edilmesi daha iyidir .


2
Ne yazık ki ben String değil Date nesnesi üretmek zorunda.
Athlan

3

basit çözüm

const handler1 = {
  construct(target, args) {
    let newDate = new target(...args);
    var tzDifference = newDate.getTimezoneOffset();
    return new target(newDate.getTime() + tzDifference * 60 * 1000);
  }
};

Date = new Proxy(Date, handler1);

3

Javascript tarih sadece içinde basit tutuyor. böylece tarih ve saat verileri UTC unix çağında (milisaniye veya ms) saklanır.

Dünyadaki herhangi bir saat diliminde değişmeyen "sabit" bir zamana sahip olmak istiyorsanız, UTC'deki saati geçerli yerel saat diliminize uyacak şekilde ayarlayabilir ve kaydedebilirsiniz. Ve geri alırken, yerel saat diliminizde hangi olursa olsun, onu kaydedilene göre ayarlanmış UTC saatini gösterecek ve "sabit" saati almak için yerel saat dilimi uzaklığını ekleyecektir.

Tarihi kaydetmek için (ms cinsinden)

toUTC(datetime) {
  const myDate = (typeof datetime === 'number')
    ? new Date(datetime)
    : datetime;

  if (!myDate || (typeof myDate.getTime !== 'function')) {
    return 0;
  }

  const getUTC = myDate.getTime();
  const offset = myDate.getTimezoneOffset() * 60000; // It's in minutes so convert to ms
  return getUTC - offset; // UTC - OFFSET
}

Tarihi almak / göstermek için (ms cinsinden)

fromUTC(datetime) {
  const myDate = (typeof datetime === 'number')
    ? new Date(datetime)
    : datetime;

  if (!myDate || (typeof myDate.getTime !== 'function')) {
    return 0;
  }

  const getUTC = myDate.getTime();
  const offset = myDate.getTimezoneOffset() * 60000; // It's in minutes so convert to ms
  return getUTC + offset; // UTC + OFFSET
}

O zaman yapabilirsin:

const saveTime = new Date(toUTC(Date.parse("2005-07-08T00:00:00+0000")));
// SEND TO DB....

// FROM DB...
const showTime = new Date(fromUTC(saveTime));

2

Bu kodu kullanabilirsiniz

var stringDate = "2005-07-08T00:00:00+0000";
var dTimezone = new Date();
var offset = dTimezone.getTimezoneOffset() / 60;
var date = new Date(Date.parse(stringDate));
date.setHours(date.getHours() + offset);

1
Bunun gün ışığından yararlanma tasarrufunu hesaba kattığına inanmıyorum
Daniel Thompson

2

Gerçekten tarihi görüntülerken bir biçimlendirme sorunu olduğundan (örneğin yerel saatte görüntüler), biçimlendirmeyi daha açık ve daha fazla çıktı seçeneği sağlamak için yeni (ish) Intl.DateTimeFormat nesnesini kullanmayı seviyorum :

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };

const dateFormatter = new Intl.DateTimeFormat('en-US', dateOptions);
const dateAsFormattedString = dateFormatter.format(new Date('2019-06-01T00:00:00.000+00:00'));

console.log(dateAsFormattedString) // "June 1, 2019"

Gösterildiği gibi, saat dilimi 'UTC' olarak ayarlandığında yerel dönüşümler gerçekleştirilmez. Bir bonus olarak, daha parlak çıktılar oluşturmanıza da izin verir. Mozilla'dan Intl.DateTimeFormat nesnesi hakkında daha fazla bilgi edinebilirsiniz - Intl.DateTimeFormat .

Düzenle:

Aynı işlevsellik yeni bir Intl.DateTimeFormatnesne oluşturmadan da elde edilebilir . Yerel ayar ve tarih seçeneklerini doğrudan toLocaleDateString()işleve aktarmanız yeterlidir .

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };
const myDate = new Date('2019-06-01T00:00:00.000+00:00');
today.toLocaleDateString('en-US', dateOptions); // "June 1, 2019"

1

Sadece genel bir not. esnek kalmanın bir yolu.

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

GetMinutes () kullanabiliriz, ancak ilk 9 dakika için yalnızca bir sayı döndürür.

let epoch = new Date() // Or any unix timestamp

let za = new Date(epoch),
    zaR = za.getUTCFullYear(),
    zaMth = za.getUTCMonth(),
    zaDs = za.getUTCDate(),
    zaTm = za.toTimeString().substr(0,5);

console.log(zaR +"-" + zaMth + "-" + zaDs, zaTm)

Date.prototype.getDate()
    Returns the day of the month (1-31) for the specified date according to local time.
Date.prototype.getDay()
    Returns the day of the week (0-6) for the specified date according to local time.
Date.prototype.getFullYear()
    Returns the year (4 digits for 4-digit years) of the specified date according to local time.
Date.prototype.getHours()
    Returns the hour (0-23) in the specified date according to local time.
Date.prototype.getMilliseconds()
    Returns the milliseconds (0-999) in the specified date according to local time.
Date.prototype.getMinutes()
    Returns the minutes (0-59) in the specified date according to local time.
Date.prototype.getMonth()
    Returns the month (0-11) in the specified date according to local time.
Date.prototype.getSeconds()
    Returns the seconds (0-59) in the specified date according to local time.
Date.prototype.getTime()
    Returns the numeric value of the specified date as the number of milliseconds since January 1, 1970, 00:00:00 UTC (negative for prior times).
Date.prototype.getTimezoneOffset()
    Returns the time-zone offset in minutes for the current locale.
Date.prototype.getUTCDate()
    Returns the day (date) of the month (1-31) in the specified date according to universal time.
Date.prototype.getUTCDay()
    Returns the day of the week (0-6) in the specified date according to universal time.
Date.prototype.getUTCFullYear()
    Returns the year (4 digits for 4-digit years) in the specified date according to universal time.
Date.prototype.getUTCHours()
    Returns the hours (0-23) in the specified date according to universal time.
Date.prototype.getUTCMilliseconds()
    Returns the milliseconds (0-999) in the specified date according to universal time.
Date.prototype.getUTCMinutes()
    Returns the minutes (0-59) in the specified date according to universal time.
Date.prototype.getUTCMonth()
    Returns the month (0-11) in the specified date according to universal time.
Date.prototype.getUTCSeconds()
    Returns the seconds (0-59) in the specified date according to universal time.
Date.prototype.getYear()
    Returns the year (usually 2-3 digits) in the specified date according to local time. Use getFullYear() instead. 

-1

(new Date().toString()).replace(/ \w+-\d+ \(.*\)$/,"")

Bunun çıktısı olacak: Sal 10 Tem 2018 19:07:11

(new Date("2005-07-08T11:22:33+0000").toString()).replace(/ \w+-\d+ \(.*\)$/,"")

Bu çıktı olacak: Cum 08 Temmuz 2005 04:22:33

Not: Döndürülen süre yerel saat diliminize bağlı olacaktır


-1

Benim için çalışan bu problem için bulduğum çözüm bu.


kullanılan kütüphane: düz javascript Date sınıfı ile momentjs.

Adım 1. String tarihini moment nesnesine dönüştür (PS: moment, toDate()yöntem çağrılmadığı sürece orijinal tarih ve saati korur ):

const dateMoment = moment("2005-07-08T11:22:33+0000");

2. Extract Adım hoursve minutesdaha önce oluşturulmuş an nesnesinden değerleri:

  const hours = dateMoment.hours();
  const mins = dateMoment.minutes();

Adım 3. Anı Tarihe Dönüştür (PS: bu, orijinal tarihi tarayıcınızın / makinenizin saat dilimine göre değiştirir, ancak endişelenmeyin ve 4. adımı okuyun):

  const dateObj = dateMoment.toDate();

Adım 4. Adım 2'de çıkarılan saatleri ve dakikaları manuel olarak ayarlayın.

  dateObj.setHours(hours);
  dateObj.setMinutes(mins);

Adım 5. dateObj artık saat dilimi farkı olmadan orijinal Tarihi gösterecektir. Orijinal saati ve dakikayı manuel olarak ayarladığımız için Yaz saati değişikliklerinin bile tarih nesnesi üzerinde herhangi bir etkisi olmaz.

Bu yardımcı olur umarım.


-7

Tarih ayrıştırmada maalesef varsayılan olarak iyi ele alınmayan bazı doğal sorunlar vardır.

-İnsan okunabilir tarihlerin içlerinde zaman dilimi vardır
vardır -Web'de belirsiz olan birçok yaygın tarih biçimi vardır

Bu sorunları kolay ve temiz bir şekilde çözmek için böyle bir işleve ihtiyaç duyulacaktır:

>parse(whateverDateTimeString,expectedDatePattern,timezone)
"unix time in milliseconds"

Bunu aradım ama böyle bir şey bulamadım!

Ben de yarattım: https://github.com/zsoltszabo/timestamp-grabber

Zevk almak!

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.