Saya menerima string tanggal dari API, dan diformat sebagai yyyy-mm-dd
.
Saat ini saya menggunakan regex untuk memvalidasi format string, yang berfungsi ok, tapi saya bisa melihat beberapa kasus di mana itu bisa menjadi format yang benar sesuai dengan string tetapi sebenarnya tanggal yang tidak valid. yaitu 2013-13-01
, misalnya.
Apakah ada cara yang lebih baik dalam PHP untuk mengambil string seperti 2013-13-01
dan memberi tahu apakah itu tanggal yang valid atau tidak untuk format yyyy-mm-dd
?
Jawaban:
Anda dapat menggunakan
DateTime
kelas untuk tujuan ini:[ Fungsi diambil dari jawaban ini . Juga di php.net . Awalnya ditulis oleh Glavić . ]
Kasus uji:
Demo!
sumber
strtotime
untuk mendapatkan cap waktu unix kemudiandate('Y-m-d', $t)
untuk mendapatkan tanggal string. Kemudian Anda membandingkannya seperti jawaban ini.strtotime
, tetapi untuk format non-standar yangstrtotime
tidak dikenali, Anda akan memerlukan beberapa solusi lain. Dan untuk dukungan php versi 5.2 berhenti pada Januari 2011, untuk dukungan 5.3 berhenti pada Agustus 2014.var_dump( validateDate('2012-2-9'));
'Y-n-j'
, @reignsly.$d
tidak akan salah dalam Anda memberikan tanggalnya, yang memiliki bagian berlebih, seperti bulan ke 13 (2013-13-01). Tapi itu sangat tergantung apa yang Anda inginkan. Jika Anda perlu misalnyavalidateDate('2015-55-66')
valid, maka ya, Anda hanya perlu memeriksa apakah$d
objek atau tidak.Tentukan apakah string adalah tanggal
sumber
yyyy-mm-dd
.2015-02-30
sebagai tanggal yang valid karena ketika hari yang diberikan lebih besar dari jumlah hari pada bulan tertentu (atau negatif) php beralih ke bulan berikutnya. Karena tanggal dijamin dari formatyyyy-mm-dd
ini dapat diperbaiki dengan mengubah kembali kereturn (bool)strtotime($myDateString) && date("Y-m-d", strtotime($myDateString)) == $myDateString;
.(bool)strtotime('s')
benar?$myDateString = str_replace("/", '-', $myDateString);
sebelum kembali jika string tanggal berisi garis miring (/) seperti: - dd / mm / yyyyGunakan dengan cara sederhana dengan fungsi php prebuilt:
Uji
sumber
if
untuk mengembalikan secara sederhanatrue
ataufalse
, mengembalikan tes itu sendiri.return sizeof($tmpDate) == 3 && checkdate($tmpDate[1]...
2
,20
,202
,2020
atau bahkan jika tahun ini20201
- itu mengembalikan true setiap waktu.Tentukan apakah string adalah tanggal, meskipun string adalah format non-standar
(strtotime tidak menerima format khusus)
sumber
if
untuk mengembalikan secara sederhanatrue
ataufalse
, mengembalikan tes itu sendiri.Opsi ini tidak hanya sederhana tetapi juga menerima hampir semua format, meskipun dengan format non-standar dapat menjadi buggy.
sumber
202
mengembalikan angka negatif - yang masih lulus tes.Anda juga dapat menguraikan tanggal untuk tanggal dan tahun bulan lalu Anda dapat menggunakan fungsi PHP
checkdate()
yang dapat Anda baca di sini: http://php.net/manual/en/function.checkdate.phpAnda juga dapat mencoba yang ini:
sumber
Cara termudah untuk memeriksa apakah tanggal yang diberikan valid mungkin mengubahnya menjadi unixtime menggunakan
strtotime
, memformatnya ke format tanggal yang diberikan, kemudian membandingkannya:function isValidDate($date) { return date('Y-m-d', strtotime($date)) === $date; }
Tentu saja Anda dapat menggunakan ekspresi reguler untuk memeriksa validitas, tetapi akan terbatas pada format yang diberikan, setiap kali Anda harus mengeditnya untuk memenuhi format lain, dan juga akan lebih dari yang diperlukan. Fungsi bawaan adalah cara terbaik (dalam banyak kasus) untuk mencapai pekerjaan.
sumber
checkdate()
- tetapi saya menemukan checkdate gagal jika tahun adalah nilai APA PUN:2, 20, 202, 2020, 20201
- semua kembali benar. Saya akan pergi dengan solusi Anda!Sesuai dengan jawaban cl-sah, tapi ini terdengar lebih baik, lebih pendek ...
Uji
sumber
count($tempDate) === 3
meskipunSaya memiliki hal ini, bahkan dengan PHP, saya suka mencari solusi fungsional . Jadi, misalnya, jawaban yang diberikan oleh @migli benar-benar bagus, sangat fleksibel dan elegan.
Tetapi memiliki masalah: bagaimana jika Anda perlu memvalidasi banyak string DateTime dengan format yang sama? Anda harus mengulangi format di semua tempat, yang bertentangan dengan prinsip KERING . Kita bisa meletakkan format dalam konstanta, tetapi tetap saja, kita harus meneruskan konstanta sebagai argumen untuk setiap pemanggilan fungsi.
Tapi jangan takut lagi! Kita bisa menggunakan kari untuk menyelamatkan kita! PHP tidak membuat tugas ini menyenangkan, tetapi masih memungkinkan untuk menerapkan currying dengan PHP:
Jadi, apa yang baru saja kita lakukan? Pada dasarnya kami membungkus fungsi tubuh dalam anonim dan mengembalikan fungsi tersebut sebagai gantinya. Kami dapat memanggil fungsi validasi seperti ini:
Ya, bukan perbedaan besar ... tetapi kekuatan sebenarnya berasal dari fungsi yang diterapkan sebagian , dimungkinkan oleh kari:
Pemrograman fungsional FTW!
sumber
Saya khawatir solusi yang paling banyak dipilih ( https://stackoverflow.com/a/19271434/3283279 ) tidak berfungsi dengan baik. Kasing uji keempat (var_dump (validateDate ('2012-2-25')); // false) salah. Tanggalnya benar, karena sesuai dengan format - m memungkinkan satu bulan dengan atau tanpa memimpin nol (lihat: http://php.net/manual/en/datetime.createfromformat.php ). Oleh karena itu tanggal 2012-2-25 dalam format Ymd dan test case harus benar bukan salah.
Saya percaya bahwa solusi yang lebih baik adalah dengan menguji kemungkinan kesalahan sebagai berikut:
sumber
Bagaimana dengan yang ini?
Kami cukup menggunakan blok coba-tangkap.
Pendekatan ini tidak terbatas hanya pada satu format tanggal / waktu, dan Anda tidak perlu mendefinisikan fungsi apa pun.
sumber
'0000-00-00 00:00:00'
adalah nilai datetime yang valid. Ini hanya nilai pertama. Namun, properti tanggal objek datetime akan menjadi'-0001-11-30 00:00:00'
.Solusi Regex yang diuji:
Ini akan mengembalikan nol jika tanggal tidak valid atau bukan format tttt-bb-tk, jika tidak maka akan mengembalikan tanggal.
sumber
Validasi dengan fungsi checkdate :
sumber
sumber
sumber
Cobalah ini:
sumber