Geçerli saati yazdırın ... artık saniye sayısı dikkate alınarak


9

(Not: ilişkili olmasına rağmen, bu meydan okuma kopyası değil bu bir onların kez otomatik olarak artık saniye belirleyen ziyade hardcoding gerektirdiğinden ve bir kopya değil bu bir zorluk çoğu artık ikinci baskının eğri olmadan zamanının belirlenmesi geldiği için Çoğu zaman API'ların varsayılan olarak yapmadığı bir şeydir. Bu nedenle, bir çözümün bir çözümden bu zorluklardan herhangi birine göre farklı görünmesi muhtemeldir.)

2016'nın sonuna geliyoruz, ancak çoğu insanın beklediğinden biraz daha uzun sürecek. İşte bu yıl ekstra saniyemizi kutlamak için bir meydan okuma.

Geçerli saati UTC olarak saat, dakika, saniye olarak girin. (Örneğin, gün ortası için geçerli çıktı biçimleri şunları içerir 12:00:00ve [12,0,0]burada biçimlendirme çok önemli değildir.)

Ancak, bir bükülme var: Programınız artık saniyeler hem geçmiş hem de gelecek uygun şekilde işlemelidir . Bu, programınızın bazı çevrimiçi veya otomatik olarak güncellenen / güncellenebilir kaynaklardan artık saniye listesi alması gerektiği anlamına gelir. İsterseniz bunu elde etmek için İnternet'e bağlanabilirsiniz. Ancak, yalnızca bu zorluğun önündeki bir URL'ye bağlanabilirsiniz (başka bir deyişle programınızın başka bir yerden indirilmesi gerekmez) ve geçerli saati belirlemek için bağlantıyı kullanamazsınız (özellikle: herhangi bir erişim girişimi olsa bile programınız çalışmalıdır İnternet 24 saate kadar eski bir sayfa döndürür).

Çoğu işletim sisteminin şu andaki varsayılan API'leri, başka türlü karıştırılabilecek programlardan gizlenmek için artık saniye civarında zaman sarsacaktır. Bu nedenle, bu zorluğun ana zorluğu, bunu geri almak için bir yöntem veya API bulmak ve UTC'de değiştirilmemiş gerçek zamanı bulmaktır.

Teorik olarak, programınız sonsuz hızlı bir bilgisayarda çalışıyorsa ve kesinlikle çalıştırmak için sıfırdan fazla zaman almaması gerekiyorsa, tam olarak doğru olmalıdır. (Elbette, uygulamada, programınız kusurlu bir bilgisayarda çalışacak ve muhtemelen anında çalışmayacaktır. Sonuçları geçersiz kılmak konusunda endişelenmenize gerek yoktur, ancak programınızın doğruluğu için buna bağlı olmamalıdır. )

Programınız, sistem saatinin hangi saat dilimine ayarlandığından bağımsız olarak çalışmalıdır. (Bununla birlikte, hangi saat diliminin kullanıldığına dair işletim sisteminden veya ortamdan bilgi isteyebilir ve yanıtın doğru olduğunu varsayabilir.)

Olarak , en kısa program kazanır. İyi şanslar!


Yanıtlar:


2

PowerShell , 161 bayt

(('{0:H:m:s}','23:59:60')[(($d=[datetime]::UtcNow).Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

Çevrimiçi deneyin! (burada çalışmıyor, TIO'nun tanımadığı anlaşılıyor irmve iwrbelki de bir güvenlik özelliği?)

Mantık Testi (Sabit Kodlanmış Tarih):

(('{0:H:m:s}','23:59:60')[(($d=[datetime]'1/1/2017 00:00:00').Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

notlar

Normal ifade dizesinde bir değişmez TABve değişmez bir linebreak ( 0xA) vardır, böylece onlardan kaçmak zorunda kalmadım (her biri 1 bayt kaydedildi).

açıklama

İetf dosyasında verilen süreler (artık saniye), NTP çağından bu yana saniye cinsindendir 1/1/1900 00:00:00. Windows'da, bir "kene" sadece saniyenin on milyonda biridir (10.000.000 keneler / sn).

Bir tamsayı eklerseniz [datetime], tamsayı değerini keneler olarak sayar, bu yüzden NTP çağının sabit kodlu onay değerini kullanıyorum, ardından geçerli UTC zamanının (orijinal değeri aynı anda atanmış olan onay değerinden çıkarıyorum) için $d).

Bu kodlanmış kene değerini daha küçük yapmak için, bazı sıfırları (9 tanesi) alıp 98'e böldüm, sonra 98e9(98 * 10 9 ) ile çarptım .

Bu çıkarımın sonucu, NTP döneminden bu yana kenelerdeki değerdir. Bu, NTP çağından bu yana saniye cinsinden (bir çeşit) değeri elde etmek için bölünür 1e8( 1e9bir anda net olacak nedenlerden dolayı değil ). Aslında 10 kat daha küçük olacak.

Belgeyi önce satırlara bölmek yerine IETF'den almak, sonra zaman damgalarıyla satırları işlemek, hem satır sonlarına hem de TABkarakterlere bölmeye karar verdim , çünkü zaman damgasından sonra gelen şey bu. Dosyadaki tek bir hatalı satır nedeniyle, bu tek başına istemediğimiz ek bir zaman damgası içerir. Çizgi şöyle görünür:

#@	3707596800

Bu nedenle, normal ifadeyi, bu satırı hariç tutmak için çalışan bölmeye [^@]\t( @a tarafından takip edilmeyen herhangi bir karakter) bölünecek şekilde değiştirdim TAB, ancak aynı zamanda 0her zaman damgasındaki sonuncuyu tüketiyor .

Ben bölün yüzden 1e8değil 1e9eksik hesabına, 0.

Geçerli zaman damgası, kısaltılmış artık saniye zaman damgaları listesinde var olup olmadığını kontrol eder. Açıkladığım tüm bu süreç dizi erişimcisi içinde [], bu nedenle elde edilen [bool]değer bir 0( $false) veya 1( $true) ile birleştirilir. Dizine eklediğimiz dizi iki öğe içeriyor: zamanı görüntülemek için bir biçim dizesi ve bir sabit kod 23:59:60. Yukarıda belirtilen karşılaştırmanın doğruluğu hangisinin seçileceğini belirler ve bu parametre olarak -fönceden atanmış geçerli tarihe sahip format operatörüne beslenir $d.


Bu bir saniye saniye sonra ne yazdırır? Mantığı artık saniyeler içinde takip edebilirim, ama her iki tarafta da mantığı takip edebileceğimden emin değilim. (Windows doğal olarak hem saniye hem de sonraki saniyeyi 00:00:00 olarak görüntülüyor mu?)

@ ais523 artık saniye sonra sistem zamanı ne olursa olsun saniye görüntüler. Windows artık saniye hakkında bir şey bilmiyor, bu nedenle bir senkronizasyon veya manuel ayar ile düzeltilinceye kadar saat 1 saniye hızlı olacak. Gereksinimler göz önüne alındığında, bunun için gerçekten ayarlayamıyorum, çünkü yasaklanan harici bir zaman kaynağı kullanmadan sistem saatinin doğru olup olmadığını belirlemek mümkün değildir. Yapabileceğim en iyi şey, NTP senkronizasyonunu zaman yazdırdıktan sonra zorlayan bir kod eklemektir, elbette başarısız bile olabilir (ağ hatası, zaman kaynağı ayarlanmamış, vb.).
Briantist
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.