Serbest biçimli tarihimi oku


10

Aşağıdaki biçimlerden herhangi birinde (aynı programda tümünü işlemesi gerekir) yazılmış bir tarih verildiğinde, geçerli biçimlerde ayrıştırın yyyy/mm/dd date.

17th May 2012
March 14th, 2016
20 February 2014
September 14, 2017
Sunday, June 8, 2015

kurallar

  • Tarihler bazen geçersiz olur, yani. ay için yanlış gün veya bir yıldaki ay sayısı, her iki durumu da ele almalısınız. Ya hata vererek ya da tutarlı bir falsey değeri döndürerek seçim yaparsınız. (Ancak yukarıdaki şablon biçimlerine bağlı kalacaklar)
  • İki basamaklı bir çıktı oluşturmak için 10'dan az gün ve aylar için dolgu kullanılmalıdır.
  • Ay adları her zaman tam adı olacak, üç karakterli karşılıklarına kısaltılmayacak.
  • Yılın her zaman 0000-9999 aralığında olacağını varsayabilirsiniz.
  • Negatif sayıların ele alınması gerekmez.
  • Çıktının herhangi bir biçimde olması, konsola yazdırılması veya bir işlevden döndürülmesi için tam bir program veya işlev oluşturabilirsiniz.
  • Girdi her zaman bir dize olur, çıktı bir dizide tek bir bağımsız değişken olarak almayı kısaltırsa, her zaman bir dize olmalıdır. ["17th May 2012"]bunu yapabilirsiniz ve çıktı aynı olabilir["2012/05/17"]
  • Girişte yazımın doğru olacağını varsayabilirsiniz.

BONUS: çünkü burada bir meydan okumayı sevmeyenler;)

Ayrıca, giriş biçimlerine izin vermeyi başarabiliyorsanız The Fourteenth of March, 2016veya 1'den az olan herhangi bir son bayt sayımı ile kodunuzdan March the Fourteenth, 2016fazladan 20 bayt kaldırabilirsiniz .

Yazım konusunda herhangi bir karışıklığı önlemek için her gün için tam yazılı sayılar.

First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Nineth, Tenth, Eleventh, Twelfth, Thirteenth, Fourteenth, Fifteenth, Sixteenth, Seventeenth, Eighteenth, Nineteenth, Twentieth, Twenty First, Twenty Second, Twenty Third, Twenty Fourth, Twenty Fifth, Twenty Sixth, Twenty Seventh, Twenty Eighth, Twenty Nineth, Thirtieth, Thirty First

Test Durumları

INPUT                           | Output
17th May 2012                   | 2012/05/17
March 14th, 2016                | 2016/03/14
20 February 2014                | 2014/02/20
September 14, 2017              | 2017/09/14
Sunday, June 8, 2015            | 2015/06/08
1st January 1918                | 1918/01/01

The Fourteenth of March, 2016   | 2016/03/14
March the Fourteenth, 2016      | 2016/03/14
November the Seventeenth, 2019  | 2019/11/17
The Thirtieth of April, 2016    | 2016/04/30

30 February 2014                | Invalid
September 99, 2017              | Invalid
Sunday, June8, 2015             | Invalid

The Thirty First of April, 2016 | Invalid


10
" çünkü burada bir meydan okuma sevmez " - bir bonus şeklinde geldiklerinde, çoğunlukla hepimiz sevmiyorum! Ve giriş doğrulaması için boons.
Shaggy

3
Mr.Xcoder Ben bütün zorluk birden çok giriş biçimlerini destekleyen olduğunu düşünüyorum @ .. Şeyler gibi 20 February 2014tarih-ayrıştırıcıları bir çok desteklenen varsayılan, ancak 17thve Sunday, June 8, 2015biraz daha zor (dile bağlı olarak) ayrıştırmak için vardır.
Kevin Cruijssen

1
@ Mr.Xcoder Hiç eğlenceli / sıkıcı, kolay / zor, iyi / kötü kod-golf meydan okuma olduğunu söylemedim. Basitçe, meydan okumada okuduğum şeye dayanarak, çoklu giriş formatı desteğinin meydan okumanın ana hedefi olduğunu belirtiyorum. Beş giriş formatı için bir if-else veya yıl, ay ve günü ayıklamak için bir tür normal ifade olacağını kabul ediyorum (şu anda benim yaklaşımım).
Kevin Cruijssen

3
Haftanın günü her zaman doğru mu? Misiniz Thursday, August 25, 2017geçerli olması? Başvuruların DOW'u görmezden geldiğini görüyorum.
Benjamin Cuningham

Yanıtlar:


4

Raylar, 41 , 37 35 bayt

->x{x.to_date.strftime('%Y/%m/%d')}

Rails için çevrimiçi bir tercüman bilmiyorum, ama işte bu işlemi gösteren bir ekran görüntüsü

resim açıklamasını buraya girin


Çevrimiçi tercüman bağlantısı?
Jonathan Allan

1
Bu, söz konusu tüm biçimler için gerçekten işe yarıyor mu? : o
totallyhuman

@totallyhuman Sonuçları gösteren bir ekran görüntüsü eklendi. Ne yazık ki bir çevrimiçi tercüman bilmiyorum :(
Suever

8

PowerShell , 91 89 91 56 bayt

date("$args"-replace'th|rd|st|(\b.*)day|,')-f yyyy/MM/dd

Çevrimiçi deneyin!

Girişi dize olarak alır. Önemsizden -replacekurtulmak için a kullanır , ardından gerekli formatı belirtmek için ormat bayrağıyla yerleşik Get-Datekomutu kullanır . Bu dize ardışık düzende bırakılır ve çıktı örtüktür.-fyyyy/MM/dd

Bay Xcoder sayesinde iki bayt kurtardı. TessellatingHeckler'ın regex golf sayesinde büyük bir yığın kaydetti.


1
Hey bakmak rekabetçi PowerShell gönderme!
Outgolfer Erik

@EriktheOutgolfer Tarih manipülasyonu PowerShell'in güçlü yönlerinden biridir.
AdmBorkBork


@ Mr.Xcoder "hepsi bu" = 2. lol. Teşekkürler!
AdmBorkBork

''-2 için tarih biçiminden kaldırabilirsiniz . Yaklaşımınıza sadık kalmak istiyorsanız, "yazım doğru" olduğunda, bunu değiştirebilirsiniz 'th|rd|st|(\b.*)day|,'ve 56 bayta düşer ve aynı durumları işler. Yanlış olduğunu düşünmeme rağmen, günleri düşürürseniz Sunday, June8, 2015 | Invalid, Pazartesi günü olduğu için davayı alamazsınız . Hata vermelidir, ancak geçerli olarak ayrıştırılır. Bununla ilgili kararın ne olacağından veya başkalarının kontrol edip etmediğinden emin değilim.
TessellatingHeckler

4

PHP, 73 164 + 1 bayt

for(preg_match("#(\d+)[^\d]+(\d+)#",$d=$argn,$r);$m++<12;)strpos(_.$d,date(F,strtotime($r[2].-$m)))&&printf(checkdate($m,$r[1],$r[2])?"$r[2]/%02d/%02d":E,$m,$r[1]);

Pipo ile çalıştırın -nRveya çevrimiçi deneyin .

Tarih kontrolü gerçekten pahalıydı: Bir yerleşkeyi kullanmadan önce tarihi sökmek zorunda kaldım, sonra ayın adını denemeliydim.


Bence bunlardan sadece birini değil tüm formatları desteklemelisiniz?
Outgolfer Erik

1
@EriktheOutgolfer yapar. Ama bonus biçimleri değil.
Titus

@EriktheOutgolfer Bu, tüm formatları işler.
Bay Xcoder

1
Bu geçersiz tarihler için başarısız oluyor. 30 February 2014döner 2014/03/02. Ya hata vererek ya da tutarlı bir falsey değeri döndürerek seçim yaparsınız. (Ancak yukarıdaki şablon formatlarına sadık kalacaklar)
Bay Xcoder

@ Mr.Xcoder Bu oldukça harap ...
Titus

3

Python 3 + parsedatetime kütüphane, 152 139 155 153 bayt

Jonathan Allan sayesinde 13 bayt kurtardı

Geçersiz uzunluk günlerine sahip tarihleri ​​işlemek için 16 bayt eklendi

Lambda atamasını kaldırarak 2 bayt kaydedildi

lambda s:re.search(f'(^| ){str(h(s)[0].tm_mday)[:2]}[^\d]',s)and time.strftime('%Y/%m/%d',h(s)[0])
import parsedatetime as p,time,re
h=p.Calendar().parse

Çevrimiçi deneyin!

Bonus tarihleri ​​desteklenmez


PPCG'ye Hoşgeldiniz! Güzel ilk gönderi. Şunları kullanarak 13 bayt kaydedin : falsey dönüş değeri None; import ...as; Ve bir lambdayeniden kullanarak parseolarak h.
Jonathan Allan


1

Java (OpenJDK 8) , 190 + 26 = 216 bayt

import java.time.format.*;

s->DateTimeFormatter.ofPattern("uuuu/MM/dd").format(DateTimeFormatter.ofPattern("[EEEE, ][d ]MMMM [d, ]uuuu").withResolverStyle(ResolverStyle.STRICT).parse(s.replaceAll("(\\d)[a-z].","$1")))

Çevrimiçi deneyin!

Önemli not: daha kısaydı doğrulama dahildir böylece, aynı zamanda onu terkediyor yerine haftanın gününü doğrulamak için!

SimpleDateFormat30 Şubat gibi tarihlerin kabul edildiği bariz davaların ötesinde denemedim . Bu yüzden onu terk etmek zorunda kaldım ve Java 8'i kullandımDateTimeFormatter .

açıklama

"[EEEE, ][d ]MMMM [d, ]uuuu"

Bu biçim şu anlama gelir:

  • isteğe bağlı haftanın gününü ve ardından virgül ve boşluk [EEEE, ](Sunday, ... ),
  • ardından isteğe bağlı alan içeren gün [d ],
  • ardından tam harflerle MMMMve boşlukta ay ,
  • ardından virgül ve boşluk içeren isteğe bağlı gün [d, ] ,
  • daha sonra uuuuayrıştırıcının Gregoryen çağda olduğumuzu bildirmesi için bir yıl .

Kod:

import java.time.format.*;                                     // Required for DateTimeFormatter, *and* ResolverStyle

s->DateTimeFormatter.ofPattern("uuuu/MM/dd")                   // Output format
  .format(
    DateTimeFormatter.ofPattern("[EEEE, ][d ]MMMM [d, ]uuuu")  // Input format
      .withResolverStyle(ResolverStyle.STRICT)                 // Invalidates xxxx-02-30 instead of transforming it into xxxx-02-28
      .parse(
        s.replaceAll("(\\d)[a-z].","$1")                       // remove st, nd, rd, th
       )
    )

Kredi

  • Neil sayesinde normal ifade 2 bayt.

1
Desendeki braketlere ihtiyacınız var replaceAllmı?
Neil

Görünmüyor gibi. Teşekkürler, @Neil!
Olivier Grégoire

1

JavaScript (ES6), 124 122 bayt

f=
s=>(d=new Date(s.replace(/.[dht]\b/,'')+' +0')).getDate()==s.match(/\d\d?/)&&d.toISOString().replace(/-(..)(T.*)?/g,'/$1')
<input oninput=o.textContent=f(this.value)><pre id=o>


İade 2015/06/07için June 8, 2015ve (UTC konuyla? Ben UTC + 2 yaşıyorum) falseiçin ya Sunday, June 8, 2015ya Monday, June 8, 2015.
Olivier Grégoire

1
@ OlivierGrégoire Bunları gösterdiğin için teşekkürler. İngiltere'de yaz saati dışında sadece tarihleri ​​denedim, bu yüzden zaten UTC kullanıyorlardı ve biten hafta içi günlerini denemedim nday.
Neil
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.