Baca tanggal bentuk bebas saya

10

Diberi tanggal yang ditulis dalam format apa saja (harus menangani semuanya dalam program yang sama), parsing menjadi valid yyyy/mm/dd date.

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

Aturan

  • Tanggal terkadang tidak valid, yaitu. hari yang salah untuk bulan atau jumlah bulan dalam setahun, Anda harus menangani kedua kasus. Baik dengan membuat kesalahan atau mengembalikan nilai falsey yang konsisten, Anda memilih. (Namun mereka akan tetap berpegang pada format template di atas)
  • Padding selama berhari-hari dan berbulan-bulan kurang dari 10 harus digunakan untuk membuat output dua digit.
  • Nama bulan akan selalu menjadi nama lengkap, tidak disingkat menjadi tiga karakter rekan mereka.
  • Anda dapat mengasumsikan tahun akan selalu berada dalam kisaran 0000-9999.
  • Nomor negatif tidak perlu ditangani.
  • Anda dapat membuat program atau fungsi lengkap sehingga output dapat dalam format apa pun, dicetak untuk menghibur atau dikembalikan dari suatu fungsi.
  • Input akan selalu berupa string, output harus selalu berupa string, jika membuatnya lebih pendek untuk menjadikannya sebagai argumen tunggal dalam array misalnya. ["17th May 2012"]Anda dapat melakukannya dan hasilnya bisa sama["2012/05/17"]
  • Anda dapat menganggap ejaan dalam input akan benar.

BONUS: cos yang ada di sini tidak suka tantangan;)

Jika Anda dapat mengatur untuk juga mengizinkan format input The Fourteenth of March, 2016atau March the Fourteenth, 2016Anda dapat mengambil 20 byte tambahan dari kode Anda dengan jumlah byte terakhir kurang dari 1 yang menghasilkan 1.

Berikut adalah angka tertulis lengkap untuk setiap hari untuk menghindari kebingungan dalam pengejaan.

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

Uji Kasus

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
MysticVagabond
sumber
10
" karena siapa di sini tidak suka tantangan " - ketika mereka datang dalam bentuk bonus, kebanyakan dari kita semua tidak! Dan boo-guci untuk memasukkan validasi.
Shaggy
3
@ Mr.Xcoder Saya pikir seluruh tantangannya adalah untuk mendukung berbagai format input .. Hal-hal seperti 20 February 2014standar didukung dalam banyak pengurai tanggal, tetapi 17thdan Sunday, June 8, 2015sedikit lebih sulit untuk diurai (tergantung pada bahasa).
Kevin Cruijssen
1
@ Mr.Xcoder Saya tidak pernah mengatakan itu adalah tantangan kode-golf yang menyenangkan / membosankan, mudah / sulit, baik / buruk. Saya hanya menyatakan bahwa berdasarkan apa yang saya baca dalam tantangan, berbagai format input yang mendukung tampaknya menjadi tujuan utama dari tantangan tersebut. Saya setuju itu kemungkinan besar akan menjadi if-else untuk lima format input, atau semacam regex untuk mengekstrak tahun, bulan dan hari (yang saat ini merupakan pendekatan saya).
Kevin Cruijssen
3
Apakah hari dalam seminggu selalu benar? Apakah Thursday, August 25, 2017akan valid Saya melihat kiriman mengabaikan DOW.
Benjamin Cuningham

Jawaban:

4

Rails, 41 , 37 35 byte

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

Saya tidak tahu tentang juru bahasa online untuk Rails, tapi di sini ada tangkapan layar yang menunjukkan proc ini

masukkan deskripsi gambar di sini

Suever
sumber
Tautan penerjemah online?
Jonathan Allan
1
Apakah ini benar-benar berfungsi untuk semua format yang dimaksud? : o
totallyhuman
@totallyhuman Menambahkan tangkapan layar yang memperlihatkan hasilnya. Sayangnya saya tidak tahu tentang juru bahasa online :(
Suever
8

PowerShell , 91 89 91 56 byte

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

Cobalah online!

Mengambil input sebagai string. Menggunakan a -replaceuntuk menyingkirkan sampah, kemudian menggunakan Get-Dateperintah -fbawaan dengan bendera ormat untuk menentukan yyyy/MM/ddformat yang diperlukan . String itu ditinggalkan di pipeline dan outputnya implisit.

Menyimpan dua byte berkat Mr Xcoder. Menyelamatkan sebagian besar berkat golf regangan TessellatingHeckler.

AdmBorkBork
sumber
1
Hei, lihat pengajuan PowerShell yang kompetitif!
Erik the Outgolfer
@EriktheOutgolfer Date manipulasi adalah salah satu kekuatan PowerShell.
AdmBorkBork
@ Mr.Xcoder "semua itu" = 2. lol. Terima kasih!
AdmBorkBork
Anda dapat menghapus ''dari format tanggal, untuk -2. Jika Anda ingin tetap pada pendekatan Anda, mengingat "ejaan sudah benar" maka Anda dapat mengganti 'th|rd|st|(\b.*)day|,'dan turun menjadi 56 byte dan menangani kasus yang sama. Walaupun saya pikir itu salah karena jika Anda membatalkan hari, Anda tidak dapat mengambil Sunday, June8, 2015 | Invalidkoper karena itu hari Senin. Seharusnya kesalahan, tetapi diurai sebagai valid. Tidak yakin apa keputusannya, atau jika orang lain memeriksanya.
TessellatingHeckler
4

PHP, 73 164 +1 byte

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]);

Jalankan sebagai pipa dengan -nRatau coba online .

Cek tanggal benar-benar mahal: Saya harus membongkar tanggal sebelum menggunakan builtin, lalu coba-coba kesalahan pada nama bulan.

Titus
sumber
Saya pikir Anda harus mendukung semua format bukan hanya salah satu dari mereka?
Erik the Outgolfer
1
@EriktheOutgolfer tidak. Tapi bukan format bonus.
Titus
@EriktheOutgolfer Ini memang menangani semua format.
Tn. Xcoder
1
Ini gagal untuk tanggal yang tidak valid. 30 February 2014kembali 2014/03/02. Baik dengan membuat kesalahan atau mengembalikan nilai falsey yang konsisten, Anda memilih. (Namun mereka akan tetap berpegang pada format template di atas)
Tn. Xcoder
@ Mr.Xcoder Itu cukup merusaknya ...
Titus
3

Python 3 + parsedatetime library, 152 139 155 153 byte

Disimpan 13 byte berkat Jonathan Allan

Menambahkan 16 byte untuk menangani tanggal dengan hari panjang yang tidak valid

Disimpan 2 byte dengan menghapus tugas lambda

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

Cobalah online!

Tidak mendukung tanggal bonus

Noskcaj
sumber
Selamat datang di PPCG! Posting pertama yang bagus. Hemat 13 byte dengan menggunakan: nilai pengembalian falsey None; import ...as; & a lambdadengan menggunakan kembali parsesebagai h.
Jonathan Allan
1

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

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")))

Cobalah online!

Catatan penting: dulu lebih pendek juga memvalidasi hari minggu bukannya membolos itu, sehingga validasi disertakan!

Saya belum mencobanya SimpleDateFormat luar kasus-kasus nyata yang diterima semua tanggal seperti 30 Februari. Jadi saya harus membuangnya dan saya menggunakan Java 8's DateTimeFormatter.

Penjelasan

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

Format ini berarti:

  • opsional hari-hari diikuti oleh koma dan spasi [EEEE, ](terjadi di Sunday, ...),
  • diikuti oleh hari opsional dengan ruang [d ],
  • diikuti oleh bulan dalam huruf MMMMdan ruang penuh ,
  • diikuti oleh hari opsional dengan koma dan spasi [d, ],
  • diikuti oleh tahun era uuuuuntuk memberi tahu parser bahwa kita berada di era Gregorian.

Kode:

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
       )
    )

Kredit

  • 2 byte di regex berkat Neil.
Olivier Grégoire
sumber
1
Apakah Anda membutuhkan tanda kurung dalam replaceAllpola?
Neil
Sepertinya saya tidak. Terima kasih, @Neil!
Olivier Grégoire
1

JavaScript (ES6), 124 122 byte

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>

Neil
sumber
Pengembalian 2015/06/07untuk June 8, 2015(masalah UTC? Saya dalam UTC + 2) dan falseuntuk Sunday, June 8, 2015atau Monday, June 8, 2015.
Olivier Grégoire
1
@ OlivierGrégoire Terima kasih telah menunjukkannya. Saya hanya mencoba kencan di Inggris di luar Waktu Musim Panas sehingga mereka sudah menggunakan UTC, dan saya tidak akan mencoba hari kerja yang berakhir dengan nday.
Neil