Soru Gün ışığından yararlanma saati ve saat dilimi en iyi uygulamaları [kapalı]


Bu soruyu ve gün ışığından yararlanma saati ile uğraşmak için kesin bir kılavuz olan, özellikle de gerçek değişimlerle başa çıkmak için verdiğim yanıtı umuyoruz.

Ekleyecek bir şeyiniz varsa lütfen

Birçok sistem doğru zamana bağlı kalıyor, problem gün ışığından dolayı zamanla değişiyor - saati ileri veya geri hareket ettirmek.

Örneğin, siparişin zamanına bağlı olan bir sipariş alma sisteminde iş kuralları vardır - eğer saat değişirse, kurallar net olmayabilir. Siparişin süresi nasıl devam etmeli? Elbette sonsuz sayıda senaryo var - bu sadece açıklayıcı bir şey.

  • Gün ışığından yararlanma konusunda nasıl karar verdiniz?
  • Hangi varsayımlar çözümünüzün bir parçası? (burada bağlamı arıyor)

Önemli olarak, daha fazla değilse:

  • Ne denediniz ki işe yaramadı?
  • Neden işe yaramadı?

Programlama, işletim sistemi, veri kalıcılığı ve konunun diğer ilgili yönleri ile ilgilenirim.

Genel cevaplar harika, ancak özellikle sadece bir platformda mevcutsa ayrıntıları görmek isterim.


1886


Menşei


@abatishchev - Bu şekilde GETDATE() SQL'de UTC olacak DateTime.Now). Ve sunucu herhangi bir otomatik DST değişikliği ile etkilenmez. - Oded
@Oded: "sunucuda" eklenip eklenmeyeceğini kabul edebilirim. Ama yine de bu yerel zamana ihtiyacı olan başka uygulamaları etkileyebilir. Bu ve diğer nedenlerle Utc zamanını açıkça talep etmenin daha iyi olduğunu düşünüyorum. - abatishchev
UTC, GMT'ye tercih edilir, çünkü her ikisi de daha kesin olarak tanımlanmıştır ve GMT tanımları bazı işletim sistemlerinde karmaşıktır. İnsanların "GMT" ve "UTC" terimlerini birbirlerinin yerine kullanabilecekleri gibi kabul etmeleri yaygındır, ancak bunlar tamamen değildir. Hemen hemen tüm yazılım / sistemler için UTC'yi kullanın. Görmek stackoverflow.com/questions/2292334/... - Chris Johnson
@JoshStodola - Jon Skeet's 'Cevap'. - Kenny Evitt
@Oded sunucunun UTC'de olacağını düşünemezsiniz, saat diliminin "UTC" olduğu ancak DST'nin uygulandığı üretim sunucularını gördüm, bu yüzden aslında yarısından fazlası UTC + 1 idi. @Abatishchev ile açık ve kullanmak için katılıyorum DateTime.UtcNow ve GETUTCDATE()Ayrıca, bunun hakkında düşündüğünüz diğer devleri de gösterir. - ono2012


Cevaplar:



Cevapların ve diğer verilerin özeti: (lütfen sizinkini ekleyin)

Yap:

  • Zamanında kesin bir anı ifade ettiğinizde, zamanı, gün ışığından etkilenmeyen bir standart haline göre sürün. (GMT ve UTC, bu bağlamda eşdeğerdir, ancak UTC teriminin kullanılması tercih edilir. UTC'nin aynı zamanda Zulu dili veya Z zaman.)
  • Bunun yerine, yerel bir zaman değerini kullanarak bir zamana devam etmeyi seçerseniz, bu zaman dilimi için UTC'den yerel zaman ofseti ekleyin (bu uzaklık yıl boyunca değişebilir), böylece zaman damgası daha sonra açık bir şekilde yorumlanabilir.
  • Bazı durumlarda saklamanız gerekebilir her ikisi de UTC zamanı ve eşdeğer yerel saat. Genellikle bu iki ayrı alanla yapılır, ancak bazı platformlar datetimeoffset Her ikisini de tek bir alanda depolayabilen tip.
  • Zaman damgalarını sayısal değer olarak depolarken Unix zaman - o zamandan beri tam saniye sayısı 1970-01-01T00:00:00Z (atlama saniye hariç). Daha yüksek hassasiyete ihtiyacınız varsa, bunun yerine milisaniye kullanın. Bu değer, her zaman dilimi ayarlaması olmaksızın her zaman UTC'ye dayalı olmalıdır.
  • Daha sonra zaman damgasını değiştirmeniz gerekebiliyorsa, orijinal saat dilimi kimliğini ekleyin, böylece ofsetin kaydedilen orijinal değerden değişmiş olabileceğini belirleyebilirsiniz.
  • Gelecekteki olayları zamanlarken, genellikle ofsetin değişmesi için ortak olduğu için UTC yerine yerel saat tercih edilir. Cevap gör, ve Blog yazısı.
  • Doğum günleri ve yıldönümleri gibi tüm tarihleri ​​saklarken, UTC'ye veya başka bir zaman dilimine dönüştürmeyin.
    • Mümkün olduğunda, bir gün içermeyen bir tarih-sadece veri tipinde saklayın.
    • Böyle bir tür mevcut değilse, değeri yorumlarken daima saati göz ardı ettiğinizden emin olun. Günün saatinin göz ardı edileceğinden emin olamıyorsanız, o gün için daha güvenli bir temsilci saati olarak 00:00 gece yarısı yerine 12:00 öğlen seçin.
  • Saat dilimi ofsetlerinin her zaman tam sayı bir saat olmadığını unutmayın (örneğin, Hint Standart Saati UTC + 05: 30 ve Nepal UTC + 05: 45 kullanır).
  • Java kullanıyorsanız, kullanın java.time Java 8 için veya kullanım Joda zamanı Java 7 veya daha düşük.
  • Kullanıyorsanız .AĞkullanmayı düşünün Noda zaman.
  • Noda Time olmadan .NET kullanıyorsanız, bunu düşünün. DateTimeOffset genellikle daha iyi bir seçimdir DateTime.
  • Perl kullanıyorsanız, kullanın DateTime.
  • Python kullanıyorsanız, kullanın pytz veya dateutil.
  • JavaScript kullanıyorsanız, kullanın moment.js ile an-saat dilimi uzantı.
  • PHP> 5.2 kullanıyorsanız, tarafından sağlanan yerel saat dilimi dönüşümlerini kullanın. DateTime, ve DateTimeZone sınıflar. Kullanırken dikkatli olun DateTimeZone::listAbbreviations() - cevaba bakınız. PHP'yi güncel güncel verilerle saklamak için periyodik olarak yükleyin Timezonedb PECL paketi; cevaba bakınız.
  • C ++ kullanıyorsanız, doğru şekilde kullanan bir kütüphane kullandığınızdan emin olun. IANA zaman dilimi veritabanı. Bunlar arasında cctz, Yoğun bakım, ve Howard Hinnant'ın "tz" kütüphanesi.
    • Kullanmayın artırmak saat dilimi dönüşümleri için. Süre API'sı standart IANA (aka "zoneinfo") tanımlayıcılarını desteklediği iddiaları, bu hamle onları haritalar POSIX tarzı verilere, her bölgenin sahip olabileceği zengin tarih değişimini dikkate almadan. (Ayrıca, dosya bakımdan düşmüştür.)
  • Çoğu iş kuralı UTC veya GMT yerine sivil zamanı kullanır. Bu nedenle, uygulama mantığını uygulamadan önce UTC zaman damgalarını yerel bir saat dilimine dönüştürmeyi planlayın.
  • Saat dilimlerinin ve ofsetlerinin sabit olmadığını ve değişebileceğini unutmayın. Örneğin, tarihsel olarak ABD ve İngiltere aynı tarihleri ​​“ileriye doğru” ve “geri dönüş” olarak kullandılar. Ancak, 2007'de ABD, saatlerin değiştiği tarihleri ​​değiştirdi. Bu, yılın 48 haftası için Londra saati ile New York saati arasındaki farkın 5 saat ve 4 hafta boyunca (ilkbaharda 3, sonbaharda 1) 4 saat olduğu anlamına geliyor. Birden fazla bölgeyi içeren tüm hesaplamalarda bu gibi öğelerin farkında olun.
  • Zamanın türünü (gerçek olay zamanı, yayın süresi, göreceli zaman, geçmiş zaman, tekrarlanan zaman) düşünün, doğru alma için hangi öğeleri (zaman damgası, saat dilimi ofseti ve saat dilimi adı) saklamanız gerekir - bkz. "Zaman Türleri" bu cevap.
  • İşletim sisteminizi, veritabanınızı ve uygulama tzdata dosyalarınızı senkronize olarak, aralarında ve dünyanın geri kalanı arasında tutun.
  • Sunucularda, donanım saatlerini ve OS saatlerini yerel bir saat dilimi yerine UTC olarak ayarlayın.
  • Önceki mermi noktasından bağımsız olarak, Web siteleri de dahil olmak üzere sunucu tarafı kodu asla Sunucunun yerel saat diliminin özellikle herhangi bir şey olmasını bekler. cevaba bakınız.
  • Uygulama kodunuzda, yapılandırma dosyası ayarları veya varsayılanları yerine, global olarak değil, durum bölgeleri bazında çalışmayı tercih edin.
  • kullanım NTP tüm sunucularda hizmetler.
  • Kullanıyorsanız FAT32zaman damgalarının yerel saatlerde, UTC’de değil, saklandığını unutmayın.
  • Yinelenen olaylarla (örneğin haftalık TV şovu) uğraşırken, zamanın DST ile değiştiğini ve saat dilimlerinde farklı olacağını unutmayın.
  • Her zaman tarih-saat değerlerini sorgula alt sınır dahil, üst sınır özel (>=, <).

Yapma:

  • Gibi bir "saat dilimi" karıştırmayın America/New_York gibi bir "saat dilimi ofseti" ile -05:00. Onlar iki farklı şey. Görmek zaman dilimi etiketi wiki.
  • JavaScript kullanmayın Date ECMAScript 5.1 ve daha düşük olan eski web tarayıcılarında tarih ve saat hesaplamaları gerçekleştirecek nesne tasarım hatası Bu, gün ışığından yararlanma saatini yanlış kullanabilir. (Bu ECMAScript 6 / 2015'te düzeltildi).
  • Müşterinin saatine asla güvenme. Çok yanlış olabilir.
  • İnsanlara "her zaman UTC'yi her yerde kullan" deme. Bu yaygın tavsiye, bu belgede daha önce açıklanan çeşitli geçerli senaryolardan sıkışıktır. Bunun yerine, birlikte çalıştığınız veriler için uygun zaman referansını kullanın. (Zaman damgası UTC kullanabilir, ancak gelecekteki zaman planlaması ve sadece tarih değerleri olmamalıdır.)

Test yapmak:

  • Test ederken, Batı, Doğu, Kuzey ve Güney Hem yarımküreler (aslında dünyanın her bir çeyreğinde, yani 4 bölge), hem DST devam ediyor, hem de (8 verir) ve DST kullanmayan bir ülke (tüm bölgeleri kapsayacak şekilde diğer 4, toplamda 12).
  • DST'nin test geçişi, yani şu anda yaz saatindeyken, kışın bir zaman değeri seçin.
  • UTC + 12 olan bir saat dilimi, DST ile yerel zaman yapma gibi sınır durumlarını test etme Yazın UTC + 13 ve kışın UTC + 13 olan yerlerde bile
  • Tüm üçüncü taraf kitaplıklarını ve uygulamalarını sınayın ve saat dilimi verilerini doğru şekilde işlediğinden emin olun.
  • En azından yarım saatlik zaman dilimlerini test edin.

Referans:

Diğer:

  • Temsilcinizi DST olan iğrençliği sona erdirmek için lobi yapın. Her zaman umut edebiliriz ...
  • Lobi için Dünya Standart Saati

803



GMT'yi kullanmak sorunu çözmüyor, yine de anlamaya ihtiyacınız var. ne uygulamak için doğru delta ve tüm karmaşıklığın bulunduğu yer burası. Delta, farklı bölgelerdeki kullanıcılar tarafından kullanılan sistemlerde (farklı gün ışığından yararlanma programlarıyla) veya tarihsel / gelecekteki verileri gösteren sistemlerde karar vermek için karmaşık olabilir. - ckarras
Tüm uygulamanın yapması gereken, geçerli yerel saati görüntülemekse doğrudur. Ancak, örneğin, Avustralya'da 2 Nisan 2006'da Kanada'da bir işlemin tarihini / saatini görüntülemesi gereken bir sunucumuz varsa (Bu, Kanada'da gün ışığından yararlanma değiştirme kurallarının değişmesinden önceki son yıldı) - bir OS çağrınız var mı? Bu DateTime yapabilir ("2006/04/02 14: 35Z") ToLocalTime () .DahatSavingRules ("Kanada", 2006)? - ckarras
Evet, Windows - SystemTimeToTzSpecificLocation'da böyle bir işletim sistemi çağrısı var. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx - Michael Madsen
@tchrist Belki de ısrar ederseniz yapabilirsiniz. - Peter Ajtai
Gelecekteki tarihleri ​​(sadece yarın) UTC'ye dönüştürmeyi unutmayın her zaman Birşey kaybetmek. Örneğin, bu dönüşümü yapmak için bilinen bir ofset kullandınız, ancak tarih gelecekte olduğu için, bu kuralları belirleyen grubun bu kuralları değiştirmesi her zaman bir şanstır. Ayrıca, bazı gelecek tarihleri ​​UTC'ye dönüştürmek neredeyse imkansızdır çünkü gün ışığından yararlanma saati o yıla kadar bilinmemektedir (bazı ülkeler tarihleri ​​her yıl, 10 yıldan fazla değil veya herhangi bir kural temelinde). - eselk


Yukarıdaki cevaplara ne ekleyebileceğimi bilmiyorum, ama benden birkaç puan:

Zaman türleri

Dikkate almanız gereken dört farklı zaman vardır:

  1. Etkinlik zamanı: örneğin, uluslararası bir spor müsabakasının gerçekleştiği zaman veya bir koronasyon / ölüm / vb. Bu, olayın saat dilimine ve izleyiciye bağlı değildir.
  2. Televizyon zamanı: Örneğin, belirli bir TV programı tüm dünyada saat 9'da yerel saatte yayınlanmaktadır. Web sitenizdeki sonuçları (örneğin Amerikan Idol'ü) yayınlamayı düşünürken önemli
  3. Göreceli zaman: örn: Bu sorunun 21 saat içinde açık bir kelle kapanışı vardır. Bu görüntülemesi kolay
  4. Tekrar eden süre: ör.: DST değiştiğinde bile her Pazartesi günü saat 9'da bir TV programı açılır.

Tarih / alternatif zaman da var. Bunlar sinir bozucu çünkü standart zamana geri dönmeyebilirler. Örn: Julian tarihleri, Saturn, The Klingon takvimindeki Ay takvimi ile tarihler.

UTC'de başlangıç ​​/ bitiş zaman damgasının saklanması iyi çalışır. 1 için, etkinlikle birlikte saklanan bir etkinlik zaman dilimi adı + ofsetine ihtiyacınız vardır. 2 için, her bölge için saklanan yerel bir zaman tanımlayıcısına ve her görüntüleyici için saklanan bir yerel saat dilimi adı + ofsetine ihtiyacınız vardır (bunu bir crunch'daysanız IP'den türetmek mümkündür). 3 için, UTC saniye içinde saklayın ve saat dilimlerine gerek yok. 4, global veya yerel bir etkinlik olup olmamasına bağlı olarak 1 veya 2 özel bir durumdur, ancak aynı zamanda anda oluşturuldu zaman damgası, bu olayın oluşturulmasından önce veya sonra bir saat dilimi tanımının değişip değişmediğini anlayabilirsiniz. Tarihi verileri göstermeniz gerekiyorsa bu gereklidir.

Depolama süreleri

  • UTC’de her zaman sakla
  • Ekranda yerel saate dönüştürme (yerel veri, kullanıcıya bakarak belirlenir)
  • Bir zaman dilimini saklarken, adı, zaman damgası ve ofset gerekir. Bu durum hükümetler bazen kendi saat dilimlerinin anlamlarını değiştirdiği için zorunludur (örneğin: ABD hükümeti DST tarihlerini değiştirdi) ve uygulamanızın işleri incelikle ele alması gerekiyor ... Örneğin: LOST bölümlerinin DST kurallarının hem öncesi hem de sonrası olduğu kesin zaman damgası değişti.

Ofsetler ve isimler

Yukarıdakilerin bir örneği:

Futbol dünya kupası finalleri oyunu   Güney Afrika'da oldu (UTC + 2 - SAST)   11 Temmuz 2010 saat 19:00 UTC.

Bu bilgi ile, Güney Afrika zaman dilimi tanımı değişse bile 2010 WCS finallerinin ne zaman gerçekleştiğini kesin olarak belirleyebiliriz. ve Görüntüleyenlere, yerel saat dilimlerinde, veritabanını sorguladıkları sırada görüntüleyebilir.

Sistem zamanı

Ayrıca, işletim sisteminizi, veritabanınızı ve uygulama tzdata dosyalarınızı birbiriyle ve dünyanın geri kalanıyla senkronize halde tutmanız ve yükseltme yaptığınızda kapsamlı bir şekilde test etmeniz gerekir. Bağlı olduğunuz bir üçüncü taraf uygulamasının TZ değişikliğini doğru bir şekilde işlemediğinden duyulmamış.

Donanım saatlerinin UTC olarak ayarlandığından ve dünyanın her yerinden sunucu çalıştırıyorsanız, işletim sistemlerinin UTC'yi de kullanacak şekilde yapılandırıldığından emin olun. Bu, saatlik döndürülen apache günlük dosyalarını birden çok saat dilimi içinde sunuculardan kopyalamanız gerektiğinde görünür. Dosya isimlerine göre sıralamak sadece tüm dosyalar aynı zaman dilimi ile adlandırılmışsa çalışır. Aynı zamanda, bir kutudan diğerine ssh olduğunuzda ve zaman damgalarını karşılaştırmanız gerektiğinde kafanızda matematik yapmak zorunda olmadığınız anlamına da gelir.

Ayrıca, tüm kutularda ntpd'yi çalıştırın.

Müşteriler

İstemci makineden aldığınız zaman damgasını asla geçerli olmadığından emin olmayın. Örneğin, Tarih: HTTP üstbilgileri veya javascript Date.getTime() aramak. Bunlar, opak tanımlayıcılar olarak kullanıldığında veya aynı istemcide tek bir oturum sırasında matematik yaparken, ancak bu değerleri sunucuda sahip olduğunuz bir şeyle çapraz referans vermeye çalışmadığınızda sorun değildir. İstemcileriniz NTP'yi çalıştırmaz ve BIOS saatlerinde mutlaka çalışan bir pil bulundurmayabilir.

önemsiz şeyler

Son olarak, hükümetler bazen çok tuhaf şeyler yapacaklar:

Hollanda'da standart zaman   tam 19 dakika ve 32.13 saniye   1909-05-01 tarihinden itibaren yasalarca UTC'den önce   1937-06-30 arası. Bu saat dilimi   tam olarak kullanılarak temsil edilemez   HH: MM formatı.

Tamam, bitti sanırım.


288



Bu cevabın bazı harika noktaları var, özellikle de bu konuya dikkat çekmek istedim "Tekrar eden zaman: ör.: Her Pazartesi Pazartesi günü saat 9'da, DST değiştiğinde bile." DB'de UTC'de saklanma süreleri ve sonra ekran için dönüştürme işlemi Saat dilimleri ile uğraşmanın zor taraflarını bir sürü. Ancak, DST engellerini aşan "tekrarlayan olaylar" ele almak çok daha zorlaşıyor. - Jared Hales
Trivia için +1. İçeriği ilgi çekici tutmak, bu görevi daha keyifli hale getirerek üretkenliği artırır :) - Chris
Bu cevapta çok iyi şeyler var ama birkaç sorun. 1) Birçok zaman dilimi kısaltmaları belirsizdir. buraya bakın  2) Not her zaman UTC'de depolamak ister misiniz? Çoğu zaman - evet, ama bağlam önemlidir. Senin şartlarda televizyon zamanı UTC'de depolanmaz. Aynı zamanda, bazen yerel yasalara aykırı olmayan veya yerel zamanı saklamayan politikasına aykırıdır. DateTimeOffset (veya eşdeğer) kullanışlı gelir. Aksi halde, iyi bir şekilde yazılır. - Matt Johnson
Hollanda trivia okunaklı görünüyor. ietf.org/rfc/rfc3339.txt bölüm 5.8. Yarı yolda birisi bacağımızı çekiyordu. - ruffin
Hükümetler için garip şeyler yapmak için başka bir örnek: timeanddate.com/news/time/turkey-scraps-dst-2016.html - Ad Infinitum


Bu önemli ve şaşırtıcı derecede zor bir sorundur. Gerçek şu ki, devam eden zaman için tamamen tatmin edici bir standart yoktur. Örneğin, SQL standardı ve ISO formatı (ISO 8601) açıkça yeterli değildir.

Kavramsal bakış açısına göre, genellikle iki tip zaman-tarih verisi ile ilgilenir ve bunları ayırt etmek uygundur (yukarıdaki standartlar yoktur):fiziksel zaman" ve "sivil zaman".

Zamanın “fiziksel” bir anı, fiziğin uğraştığı sürekli evrensel zaman çizelgesindeki bir noktadır (tabi ki göreliliği göz ardı ederek). Bu kavram, UTC'de yeterince kodlanmış olabilir, örneğin (eğer atlama saniyeleri yoksayabilirsiniz).

Bir "medeni" zaman, medeni normları izleyen bir tarih-saat özelliğidir: Burada bir zaman noktası bir dizi datetime alanıyla (Y, M, D, H, MM, S, FS) artı bir TZ (timezone spesifikasyonu) ile belirtilir. (aynı zamanda bir "takvim", aslında; ama tartışmayı Gregoryen takvimi ile sınırlandırdığımızı varsayalım). Bir zaman dilimi ve bir takvim, (prensip olarak) bir sunumdan diğerine eşlenmesini sağlar. Ancak, sivil ve fiziksel zaman aralıkları temelde farklı büyüklükte tiplerdir ve kavramsal olarak ayrı tutulmalı ve farklı şekilde ele alınmalıdırlar (bir benzetme: bayt dizileri ve karakter dizileri).

Bu konu kafa karıştırıcıdır çünkü bu tür olayları birbirinin yerine kullanacağımızdan ve medeni zamanların siyasi değişimlere maruz kalmasından dolayı. Problem (ve bu kavramları ayırt etme ihtiyacı), gelecekteki olaylar için daha belirgindir. Örnek (benim tartışmamdan alınmıştır İşte.

John, takviminde, datetime'da bir etkinlik için bir hatırlatma kaydeder 2019-Jul-27, 10:30:00, TZ =Chile/Santiago(GMT-4'ü dengeleyen, bu nedenle UTC'ye karşılık gelir 2019-Jul-27 14:30:00). Ama bir gün Gelecekte ülke, TZ ofsetini GMT-5'e değiştirmeye karar verdi.

Şimdi, gün geldiğinde ... bu hatırlatıcıyı tetiklemeli

A) 2019-Jul-27 10:30:00 Chile/Santiago  = UTC time 2019-Jul-27 15:30:00 ?

veya

B) 2019-Jul-27 9:30:00 Chile/Santiago  = UTC time 2019-Jul-27 14:30:00 ?

John'un kavramsal olarak ne anlama geldiğini bilemezse doğru bir cevap yoktur. Takvimi anlattığında lütfen 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

"Sivil tarih zamanı" demek istedi ("benim şehrimdeki saatler söylediğinde" 10:30 ") Bu durumda, A) doğru cevaptır.

Veya "fiziksel bir zaman anı" anlamına geliyordu. evrenin zaman çizgisi, "Bir sonraki güneş tutulması" derken olur. Bu durumda, B) doğru olanıdır.

Birkaç Tarih / Zaman API'si bu ayrımı doğru yapar: aralarında, JodatimeBir sonraki (üçüncü!) Java DateTime API'sinin (JSR 310) temelini oluşturur.


81



API'larda ele alınmadığı düşünülen bir başka nokta, zaman ve zaman dilimi verildiğinde bile, en az iki makul anlamın sözgelimi, örn. "13: 00: 00EDT". Doğu Gün Işığı Zamanı olduğuna inanılan yerel saatle 1: 00'de meydana gelmiş olduğu bilinen bir şey veya Doğu Saati'nin saat 13: 00'e çarptığı anda meydana gelmiş olduğu bilinen bir şeye atıfta bulunabilir. Doğu Gün Işığından yararlanan bir yerde meydana geldi. Saat dilimi bilgisinin yanlış olabileceği birçok zaman damgası varsa (örneğin, dijital kamera dosyaları) ... - supercat
... doğru yerel zamanları mı yoksa küresel zamanı mı yansıttığını bilmek, bunların nasıl düzeltileceğinin belirlenmesinde önemli olabilir. - supercat
Açıkçası John, A) istiyor çünkü insanlar şu anda DST veya saat dilimi ne olursa olsun, saat 8: 30'da çalışmaya gidiyor. DST'ye giderlerse, DST'den çıktıklarında saat 8: 30'da işe gidecekler, iş saat 8: 30'a gidecekler. Ülke başka bir saat dilimine geçmeye karar verirse, gün 8: 30'da işe giderler. - Gianluca Ghettini


Endişelerin açık ve net bir şekilde ayrılmasını sağlayın - kullanıcılarla tam olarak hangi katmanla etkileşim kurduğunu bilmek ve standart gösterim için (UTC) tarih saatini değiştirmek zorundadır. UTC olmayan tarih-saat tanıtımı (Kullanıcıları yerel saat dilimini takip eder), UTC zamanı model (arka uç ve orta katmanlar için benzersiz kalır).

Ayrıca, gerçek hedef kitlenizin ne olduğuna, nelere hizmet etmek zorunda kalmayacağınıza ve çizgiyi nerede çizeceğinize karar verin. Gerçekten önemli müşterilere sahip değilseniz ve ardından yalnızca bu bölge için ayrı ayrı kullanıcı sunucularını dikkate almadıkça egzotik takvimlere dokunmayın.

Kullanıcının konumunu edinebilir ve koruyabilirseniz, sistematik tarih-zaman dönüşümü için konum kullanın (.NET kültürü ya da bir SQL tablosu), ancak kullanıcılarınız için tarih-saat kritikse, son kullanıcının geçersiz kılma seçimlerini yapması için bir yol sağlar.

Geçmiş denetim yükümlülükleri varsa dahil (tam olarak ne zaman Jo yılında AZ 2 Eylül önce bir fatura ödeme zaman söylüyorum) sonra hem UTC hem de yerel saati koru kayıt için (dönüşüm tablolarınız zamanla değişecektir).

Toplu olarak gelen veriler için zaman referans zaman dilimini tanımlayın - gibi dosyalar, web hizmetleri vb. East Coast şirketinin CA'da veri merkezi olduğunu söyleyin - bir veya diğerini varsaymak yerine standart olarak ne kullandığını sormalısınız.

Tarih-zamanın metinsel gösterimlerine yerleştirilmiş zaman dilimi ofsetlerine güvenmeyin ve ayrıştırmayı ve takip etmeyi kabul etme. Bunun yerine, daima saat dilimi ve / veya referans bölgesinin açık bir şekilde tanımlanmasını isteyin.. PST offset ile kolayca zaman alabilir, ancak zaman aslında EST'dir, çünkü istemcinin referans zamanı ve kayıtları PST'de olan bir sunucuya gönderilmiştir.


53





Olson hakkında bilmen gerekiyor tz veritabanı, mevcut ftp://elsie.nci.nih.gov/pub  http://iana.org/time-zones/. Dünyadaki farklı ülkelerde kış ve yaz (standart ve gün ışığından yararlanma) zamanları arasında geçiş yapmak için (ve / veya), son dakika değişiklikleriyle uğraşmak için yılda birkaç kez güncellenir. 2009 yılında, son sürüm 2009'du; 2010 yılında, 2010n idi; 2011 yılında 2011n; Mayıs 2012 sonunda, 2012c sürümü oldu. Verileri ve gerçek zaman dilimi verilerini, iki ayrı arşivde (tzcode20xxy.tar.gz ve tzdata20xxy.tar.gz) yönetmek için bir kod kümesi bulunduğunu unutmayın. Hem kod hem de veri kamu malıdır.

Bu, Amerika / Los_Angeles (ve ABD / Pasifik gibi eşanlamlılar) gibi saat dilimi isimlerinin kaynağıdır.

Farklı bölgeleri takip etmeniz gerekiyorsa, o zaman Olson veritabanına ihtiyacınız var. Başkalarının da önerdiği gibi, verileri sabit bir biçimde de saklamak istersiniz - UTC, normalde seçili olanıdır - verilerin oluşturulduğu zaman diliminin kaydıyla birlikte. Zaman ve saat dilimi ismindeki UTC'den farkı ayırt etmek isteyebilirsiniz; Bu daha sonra bir fark yaratabilir. Ayrıca, şu anda 2010-03-28T23: 47: 00-07: 00 (ABD / Pasifik) olduğunu bilmek, PST'de muhtemelen belirtilmiş olan 2010-11-15T12: 30 değerini yorumlamakta size yardımcı olabilir veya olmayabilir (30). Pasifik Standart Saati) yerine PDT (Pasifik Yaz Saati).

Standart C kütüphanesi arayüzleri, bu tür şeylerle çok yararlı değildir.


Olson verileri, kısmen de olsa, A D Olson'un emekli olacağı ve kısmen de telif hakkı ihlali nedeniyle koruyucular aleyhinde bir (artık işten çıkarılmamış) hukuk davası olduğu için hareket etti. Saat dilimi veritabanı şimdi gözetimi altında yönetiliyor IANA, Internet Assigned Numbers Authority ve ön sayfada bir bağlantı var. 'Zaman Dilimi Veritabanı'. Tartışma posta listesi şimdi tz@iana.org; ilan listesi tz-announce@iana.org.


38



Olson veritabanı içerir tarihi Veriler, DST'yi işlemek için özellikle yararlı kılar. Örneğin, ABD’de 31 Mart 2000’e karşılık gelen bir UTC değerinin DST’de olmadığını, ancak ABD’de 31 Mart 2008’e karşılık gelen bir UTC değerinin olduğunu bilmektedir. - Josh Kelley
Unicode Consortium, Olson tome bölge kimlikleri ve Windows saat dilimi kimlikleri arasında bir eşlemeyi korur: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/... - Josh Kelley
Unicode Consortium'un sayfası için güncellenmiş link: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/... - Span
Olson dosyalarının ayrıştırılması hakkında bilgi nereden bulunabilir? Bunu bir db tablosuna derlemek istiyorum, ancak dosyaları nasıl okumam gerektiğini anlayamıyorum - shealtiel
@gidireich: ana bilgi verilerle bulunur ve anlaşılması kolay değildir. Bunun için ana dokümantasyonda zic.8 adam sayfası (veya zic.8.txt). İhtiyacınız olacak tzcode2011i.tar.gz dosya, ya da tzdata2011i.tar.gz bu bilgiyi almak için dosya. - Jonathan Leffler


Genel olarak, yerel zaman ofseti dahil (DST ofset dahil) depolanan zaman damgalarında: Eğer daha sonra zaman damgasını orijinal saat diliminde (ve DST ayarında) görüntülemek isterseniz, tek başına UTC yeterli olmaz.

Ofsetin her zaman bir tam sayı saat olmadığını unutmayın (ör. Hint Standart Saati UTC + 05: 30'dur).

Örneğin, uygun formatlar bir tuple (unix zamanı, dakika cinsinden uzaklık) veya ISO 8601.


24



Gösterge için ofset mükemmeldir. Değişiklik yapmak isterseniz, ofset hala yeterli değil. Saat dilimini de bilmek zorundasınız çünkü yeni değer farklı bir ofset gerektirebilir. - Matt Johnson


"Bilgisayar zamanı" ve "insan zamanı" sınırlarını geçmek bir kabus. Ana hat, saat dilimlerini ve gün ışığından yararlanma saatlerini yöneten kurallar için bir standart olmadığıdır. Ülkeler diledikleri zaman dilimlerini ve DST kurallarını istedikleri zaman değiştirebilirler.

Bazı ülkeler örn. İsrail, Brezilya, her yıl, gün ışığından yararlanma saatlerine sahip olacağına karar verir, bu nedenle (eğer) DST'nin yürürlüğe gireceği zamanı önceden bilmek imkansızdır. Diğerleri, DST'nin ne zaman yürürlükte olduğu (ish) kurallarına sahiptir. Diğer ülkeler DST'yi hiç kullanmaz.

Saat dilimlerinin GMT'den tam saat farkı alması gerekmez. Nepal +5,45. Hatta +13 olan zaman dilimleri vardır. Bu şu demek oluyor:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

hepsi aynı zamanda, henüz 3 farklı gün!

Ayrıca, saat dilimlerinin kısaltmaları ve DST'de nasıl değiştikleri konusunda net bir standart yoktur;

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

En iyi tavsiye, mümkün olduğunca yerel zamanlardan uzak kalmak ve yapabileceğiniz UTC'ye sadık kalmaktır. Sadece mümkün olan en son anda yerel zamanlara dönüş.

Test yaparken, hem DST'nin devam ettiği, hem de DST kullanmayan bir ülke (toplamda 6) ile Batı ve Doğu yarıküredeki ülkeleri test ettiğinizden emin olun.


22



İsrail'e ilişkin - bu yarısı doğrudur. DST değişiminin zamanı, Julian takviminde belirli bir tarih olmamasına rağmen - İbranice takvimine dayanan bir kural var (2014'te bir değişiklik oldu). Her neyse, genel fikir doğrudur - bu şeyler bir süre sonra değişebilir ve değişebilir - Yaron U.
Ayrıca, AST = Atlantik Standart Saati. 'En iyi tavsiyeye' gelince, bir başlangıç ​​noktası olarak, ama bu sayfanın geri kalanını okumalı ve biraz dua etmeli ve bir süreliğine haklı olabilirsin. - DavidWalley


PHP için:

PHP> 5.2'deki DateTimeZone sınıfı, başkalarının bahsettiği Olson DB'ye dayanmaktadır, bu yüzden PHP'de değil, PHP'de zaman dilimi dönüşümleri yapıyorsanız, (anlaşılması zor) Olson dosyaları ile çalışmaktan muaf olursunuz.

Ancak, PHP, Olson DB kadar sık ​​güncellenmez, bu yüzden sadece PHP'lerin saat dilimi dönüşümleri, eski DST bilgileriyle sizi bırakabilir ve verilerinizin doğruluğunu etkileyebilir. Bu sık sık gerçekleşmesi beklenmez, ancak olabilir ve irade Dünya çapında büyük kullanıcı tabanınız varsa gerçekleşir.

Yukarıdaki sorunla başa çıkmak için timezonedb pecl paketi, bu fonksiyon PHP'nin zaman dilimi verilerini güncellemektir. Bu paketi güncellendiği sıklıkta yükleyin. (Bu paket güncellemelerinin Olson güncellemelerini tam olarak takip edip etmediğinden emin değilim, ancak en azından Olson güncellemelerine çok yakın bir frekansta güncellenmektedir.)


18





Tasarımınız buna uygunsa, hep birlikte yerel zaman dönüşümünü önlemek! 

Bazılarının bunun kulağa çılgınca gelebileceğini biliyorum ama UX'i düşünün: kullanıcılar yakın bir tarihte (bugün, dün, gelecek Pazartesi) mutlak tarihlerden (2010.09.17, Cuma 17 Eylül) daha hızlı işliyorlar. Ve daha fazla düşündüğünüzde, zaman dilimlerinin doğruluğu (ve DST) daha önemlidir. now()Bu nedenle, tarihleri ​​/ datetimes'ları +/- 1 veya 2 hafta boyunca göreceli bir biçimde ifade ederseniz, tarihlerin geri kalanı UTC olabilir ve kullanıcıların% 95'ine çok fazla önem vermez.

Bu şekilde, tüm tarihleri ​​UTC'de saklayabilir ve UTC'de göreceli karşılaştırmaları gerçekleştirebilir ve kullanıcı UTC tarihlerini Bağıl Tarih Eşiğinizin dışında gösterebilirsiniz.

Bu ayrıca kullanıcı girdisi için de geçerli olabilir (ancak genellikle daha sınırlı bir şekilde). Yalnızca {Dün, Bugün, Yarın, Sonraki Pazartesi, Sonraki Perşembe} 'deki bir açılır menüden seçim yapmak, kullanıcı için bir tarih seçiciden çok daha basit ve kolaydır. Tarih toplayıcıları, form doldurmanın en acı verici bileşenlerinden bazılarıdır. Elbette bu tüm durumlar için işe yaramayacaktır, ancak bunu çok güçlü kılmak için biraz akıllıca bir tasarıma sahip olduğunu görebilirsiniz.


15



+1 İlginç bir fikir. UTC güzel bir şey olabilir; - Jon Onstott


Ben denemedim, çekici buluyorum zaman dilimi ayarlamaları için bir yaklaşım şöyle olacaktır:

  1. Her şeyi UTC'de saklayın.

  2. Tablo oluştur TZOffsets üç sütunlu: RegionClassId, StartDateTime ve OffsetMinutes (int, dakikalar içinde).

Tabloda, tarih ve saatlerin bir listesini saklayın ne zaman Yerel zaman değişti ve ne kadar. Tablodaki bölgelerin sayısı ve tarih sayısı, dünyanın hangi tarih aralığını ve desteklemeniz gereken alanlarına bağlı olacaktır. Tarihin geleceği bazı pratik sınırlara da dahil etmesine rağmen, bunu "geçmiş" tarih olarak düşünün.

Herhangi bir UTC saatinin yerel saatini hesaplamanız gerektiğinde, şunu yapın:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

Uygulamanızda bu tabloyu önbelleğe almak ve veritabanına vurmak yerine sorguları yapmak için LINQ veya benzer araçları kullanmak isteyebilirsiniz.

Bu verilerden damıtılabilir kamu malı tz veritabanı.

Bu yaklaşımın avantajları ve dipnotları:

  1. Kurallara hiçbir kod yüklenmez, yeni bölgeler veya tarih aralıkları için ofsetleri kolayca ayarlayabilirsiniz.
  2. Her tarih veya bölgeyi desteklemeniz gerekmez, bunları gerektiği gibi ekleyebilirsiniz.
  3. Bölgeler, doğrudan jeopolitik sınırlara karşılık gelmek zorunda kalmaz ve satırların çoğaltılmasını önlemek için (örneğin, ABD'deki çoğu eyalet DST'yi aynı şekilde ele alır), başka bir tabloda daha geleneksel listelere bağlantı veren geniş bir Bölge Sınıfı girdisine sahip olabilirsiniz. devletler, ülkeler vb.
  4. DST'nin başlangıç ​​ve bitiş tarihinin son birkaç yılda değiştiği ABD gibi durumlar için, bunun üstesinden gelinmesi oldukça kolaydır.
  5. StartDateTime alanı bir zaman da kaydedebildiğinden, 2:00 AM standart değiştirme zamanı kolayca ele alınır.
  6. Dünyanın her yerinde 1 saat DST kullanılıyor. Bu davaları kolayca ele alır.
  7. Veri tablosu çapraz platformdur ve neredeyse herhangi bir veritabanı platformu veya programlama dili kullanan geliştiriciler tarafından kullanılabilecek ayrı bir açık kaynak proje olabilir.
  8. Bu, saat dilimleriyle hiçbir ilgisi olmayan ofsetler için kullanılabilir. Örneğin, zaman zaman Dünya'nın rotasyonu, Gregoryen takvime ve içinde tarihsel düzenlemelere uyum sağlamak için meydana gelen 1 saniyelik ayarlamalar.
  9. Bu bir veritabanı tablosunda olduğundan, standart rapor sorguları, vb. İş mantığı kodu yoluyla bir yolculuk yapmadan veriden yararlanabilir.
  10. Bunu yapmak isterseniz saat dilimi ofsetlerini de kullanır ve bir bölgenin başka bir zaman dilimine atandığı özel geçmiş durumları bile hesaba katar. İhtiyacınız olan tek şey, en az başlangıç ​​tarihi olan her bölgeye bir saat dilimi ofseti atayan başlangıç ​​tarihi. Bu, her bir zaman dilimi için en az bir bölge oluşturmayı gerektirir, ancak aşağıdaki gibi ilginç sorular sormanızı sağlar: "Yuma, Arizona ve Seattle arasındaki yerel saat farkı nedir, Washington, 2 Şubat 1989, saat 05:00?" (Sadece bir SUM () diğerinden çıkarın.

Şimdi, bu yaklaşımın tek dezavantajı veya herhangi bir başkası bu dönüşümler itibaren GMT'ye yerel saat mükemmel değil, çünkü saat başına negatif bir ofset olan herhangi bir DST değişimi tekrarlar belirli bir yerel saat. Bununla başa çıkmanın kolay bir yolu yok, korkarım ki, yerel zamanların saklanmasının bir nedeni de ilk etapta kötü haber.


15



Veritabanı fikriniz zaten Olson Veritabanı olarak uygulandı. Gün ışığından yararlanma saati, gün ışığına özgü saat dilimini belirterek bir çakışma oluştururken sorunu çözmenize yardımcı olabilir. 2:15 EST ve 2:15 EDT farklı zamanlardır. Ofseti belirten diğer yazılarda da belirtildiği gibi belirsizlik de giderir. - BillThor
Kendi veritabanınızı tutmanın en büyük sorunu onu güncel tutmaktır. Olson ve Windows senin için korunuyor. Tablolar güncel olmadığı için kötü DST geçişlerine sahip birden fazla vakayla karşılaştım. Onları tamamen kopyalamak ve bir çerçeve veya işletim sistemi veritabanına güvenmek çok daha güvenilirdir. - Matt Johnson
Kendi veritabanınızı oluşturmayın: her zaman sistemin API'sine güvenin! - Alex


Bunu iki tip sistemde, “vardiya planlama sistemleri (örneğin fabrika çalışanları)” ve “gaz bağımlı yönetim sistemleri” nde gördüm…

23 ve 25 saatlik uzun günler başa çıkacak bir acıdır, yani 8 saat vardiyalar 7 saat veya 9 saat sürmektedir. Sorun şu ki, her müşterinin, hatta müşterinin departmanının, bu özel durumlarda ne yaptıkları konusunda (genellikle belgelemesiz) oluşturdukları farklı kurallara sahip olduğunu göreceksiniz.

Bazı sorular, “raftan” yazılımınız için ödeme yaptıktan sonra müşteriye sorulmamıştır. Yazılım satın alırken bu tür sorunları düşünen bir müşteri bulmak çok nadirdir.

Her durumda, UTC'de zaman kaydetmeli ve tarihi / saati saklamadan önce yerel saate / dönüşüme geçmelisiniz. Bununla birlikte, belirli bir sürenin hangi saatte olduğunu bilmenin bile Yaz saati ve saat dilimleri ile zor olabilir.


12



Kız arkadaşım, hemşire, gece çalışıyor ve DST geçişi sırasında saat dilimini yazmaları gerekiyor. Örneğin, 2AM CDT vs 2AM CDT - Joe Phillips
Evet, bu yaygındır: günlük (günlük) bir ortalamayı hesapladığınızda, 23, 24 veya 25 saatlik günlerle başa çıkmak zorundasınız. Sonuç olarak, hesapladığınızda 1 gün ekle 24 saat eklenmedi! İkincisi, kendi saat dilimi kodunu oluşturmaya çalışmayın; sadece sistem API'sini kullan. Ve dağıtmak için dağıtılan her sistemi güncellemeyi unutmayın. güncel zaman dilimi veritabanı. - Alex