RFC 2550 , herhangi bir tarihi (evrenin başlangıcından önceki ve hatta evrenin öngörülen geçmişini geçenler bile) destekleyen zaman damgasını gösteren, yer bakımından verimli bir ASCII temsili için (1 Nisan 1999'da yayınlanan) hiciv bir öneridir. RFC 2550 uyumlu bir zaman damgasını hesaplamak için kullanılan algoritma aşağıdaki gibidir (not: tüm aralıklar başlangıcı içerir, ancak sonu hariç tutar - 0 ila 10,000 her şeyin n
olduğu anlamına gelir 0 <= n < 10000
):
- Yıl biçimi
- 0 ila 10,000 arası yıllar: Sıfırlarla bırakılan 4 basamaklı bir ondalık sayı.
- Yıl 10.000 - 100.000: A karakteriyle önceden işaretlenmiş 5 basamaklı bir ondalık sayı.
- Yıl 100,000 için 10 30 : İngilizce alfabesinde büyük ASCII harfi kimin endeks öneki yıla ondalık sayı, 7 C 5 (B 6-basamağı için yıllar ondalık yılda basamak sayısına eşittir, eksi -digit yıllar, vs.)
- 10 30 ila 10 56 yaş : 10,000 ila 10 30 ile aynı format , A ile başlayan harflerin başlaması ve ek olarak bir şapka (
^
) eklenmesi (böylece 10 30 yılı temsil eder^A1000000000000000000000000000000
ve 10 31 yılı temsil edilir). tarafından^B10000000000000000000000000000000
). - Yıl 10 56 10 -e doğru 732 : yıl iki düzeltme imi ve harfler büyük harf iki ASCII öneki. Büyük harfler, yıl içindeki eksi 57 sayısını gösteren taban-26 sayısını oluşturur.
- Yıllar 10 732'den sonra: 10 56 - 10 732 için aynı format kullanılır, gerektiğinde ilave bir şapka ve büyük harf ekleyerek genişletilir.
- BCE yıl (0 Yılından önce): yılın mutlak değerinin yıl dizesini hesaplar. Ardından, tüm harfleri taban-26 tamamlayıcısıyla (A <-> Z, B <-> Y, vb.) Değiştirin, tüm basamakları taban-10 tamamlayıcısıyla (0 <-> 9, 1 <-> 8, vb.) ve şapkaları ünlem işareti (
!
) ile değiştirin . Yıl dizesi 4 veya daha az basamaklıysa (yani -1 ile -10.000 arası), bir eğik çizgi hazırlayın (/
). Yıl dizesi eğik çizgi veya ünlem işareti ile önizlenmemişse, bir yıldız işareti (*
) hazırlayın .
- Aylar, günler, saatler, dakikalar ve saniyeler : bu değerler en fazla sadece 2 hane olduğundan, yıl dizisinin sağına, önem sırasının düşürülmesiyle, gerekirse oluşturmak için sıfırla doldurulmuş olarak eklenirler. 2 basamaklı dizeler.
- Ek hassasiyet : Ek hassasiyet (milisaniye, mikrosaniye, nanosaniye, vb.) Gerekliyse, bu değerler sıfırdan 3 basamağa kadar sola doldurulur (çünkü her değer
1/1000
önceki değere sahiptir ve bu nedenle en fazladır999
) ve önem sırasının düşürülmesiyle, zaman damgasının sonuna eklenmiştir.
Bu biçim, sözcük sıralamanın karşılık gelen zaman damgasının sayısal sıralamasına eşdeğer olma avantajına sahiptir - A zamanı B zamanından önce gelirse, A için zaman damgası sözcüksel sıralama uygulandığında B zaman damgasından önce gelir.
Meydan okuma
Rastgele uzun bir sayısal değer listesi göz önüne alındığında (örneğin azalan önem sırasındaki zaman değerlerine karşılık gelir [year, month, day, hour, minute, second, millisecond]
), karşılık gelen RFC 2550 zaman damgasını gösterir.
kurallar
- Çözümler verilen herhangi bir girdi için çalışmalıdır. Tek sınırlamalar zaman ve boş hafıza olmalıdır.
- Girdi, makul, uygun herhangi bir biçimde alınabilir (örneğin, sayısal bir liste, bir dizge listesi, tek bir rakamsız karakter ile sınırlandırılmış bir dize vb.).
- Girdi her zaman en az bir değer içerecektir (yıl). Ek değerler her zaman azalan önem sırasına göre sıralanır (örneğin, girdi hiçbir zaman bir ay değeri olmayan bir gün değeri veya ardından bir ay değeri izleyen ikinci bir değer içermez).
- Girdi her zaman geçerli bir zaman olacaktır (örneğin, 30 Şubat için hiçbir zaman damgası olmayacak).
- RFC 2550 zaman damgasını hesaplayan yerleşikler yasaktır.
Örnekler
Bu örnekler, girişi tek tek bir dize olarak kullanır, tek tek değerler perio ( .
) ile ayrılır .
1000.12.31.13.45.16.8 -> 10001231134516008
12.1.5.1 -> 0012010501
45941 -> A45941
8675309.11.16 -> C86753091116
47883552573911529811831375872990.1.1.2.3.5.8.13 -> ^B478835525739115298118313758729900101020305008013
4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11 -> ^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711
-696443266.1.3.6.10.15.21.28 -> *V3035567330103061015021028
-5342 -> /4657
-4458159579886412234725624633605648497202 -> !Q5541840420113587765274375366394351502797
Referans uygulaması
#!/usr/bin/env python
import string
# thanks to Leaky Nun for help with this
def base26(n):
if n == 0:
return ''
digits = []
while n:
n -= 1
n, digit = divmod(n, 26)
digit += 1
if digit < 0:
n += 1
digit -= 26
digits.append(digit)
return ''.join(string.ascii_uppercase[x-1] for x in digits[::-1])
year, *vals = input().split('.')
res = ""
negative = False
if year[0] == '-':
negative = True
year = year[1:]
if len(year) < 5:
y = "{0:0>4}".format(year)
elif len(year) <= 30:
y = "{0}{1}".format(string.ascii_uppercase[len(year)-5], year)
else:
b26len = base26(len(year)-30)
y = "{0}{1}{2}".format('^'*len(b26len), b26len, year)
if negative:
y = y.translate(str.maketrans(string.ascii_uppercase+string.digits+'^', string.ascii_uppercase[::-1]+string.digits[::-1]+'!'))
if len(year) == 4:
y = '/' + y
if y[0] not in ['/', '!']:
y = '*' + y
res += y
for val in vals[:5]: #month, day, hour, minute, second
res += '{0:0>2}'.format(val)
for val in vals[5:]: #fractional seconds
res += '{0:0>3}'.format(val)
print(res)
-696443266.1.3.6.10.15.21.28
olmalı*V3035567339896938984978971
?