PHP Regex untuk memeriksa tanggal dalam format YYYY-MM-DD


98

Saya mencoba untuk memeriksa bahwa tanggal yang dimasukkan oleh pengguna akhir adalah dalam YYYY-MM-DD. Regex tidak pernah menjadi kekuatan saya, saya terus mendapatkan nilai pengembalian palsu untuk preg_match () yang saya siapkan.

Jadi saya berasumsi saya telah mengacaukan regex, yang dijelaskan di bawah ini.

$date="2012-09-12";

if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
    {
        return true;
    }else{
        return false;
    }

Ada pemikiran?


6
Regex tidak cukup untuk memvalidasi tanggal. Setelah regex, Anda juga harus menggunakan salah satu dari dua berikut ini: date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";atau PHP checkdate ( int $month , int $day , int $year ).
Stan Tiberiu-Ionuț

Saya tidak mencoba memvalidasinya saat ini, saya hanya ingin memastikannya dalam format YYYY-MM-DD.
cosmicsafari

2
Untuk nilai yang dimasukkan pengguna, "titik" apa yang lebih baik untuk memvalidasi selain tepat setelah regex, saat pengiriman formulir (sehingga Anda dapat menampilkan kesalahan)?
Stan Tiberiu-Ionuț

Poin yang adil, bisa menyelamatkan orang bodoh nanti.
cosmicsafari

Jawaban:


198

Coba ini.

$date="2012-09-12";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
    return true;
} else {
    return false;
}

18
return (bool)preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date);
Stan Tiberiu-Ionuț

5
Mengapa ini ditandai sebagai jawaban yang benar? Ini mengembalikan true untuk sejumlah tanggal tidak valid seperti 2016-02-30 dan 2016-09-31
Graham

7
Pertanyaan ini tentang cara memeriksa format tanggal (TTTT-BB-HH), dan jawaban yang ditandai sebagai diterima tidak selalu merupakan jawaban terbaik, itu hanya berarti bahwa ini berfungsi untuk orang yang bertanya, baca tur yang indah ini: stackoverflow. com / tour .
stramin

Kiriman lama @Graham Saya tahu tetapi setuju dengan Stramin - pertanyaan ini menanyakan tentang validasi format - bukan validasi tanggal aktual
treyBake

98

Mungkin lebih baik menggunakan mekanisme lain untuk ini.

Solusi modern, dengan DateTime:

$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());

Ini juga memvalidasi masukan: $dt !== falsememastikan bahwa tanggal dapat diuraikan dengan format yang ditentukan dan array_sumtriknya adalah cara singkat untuk memastikan bahwa PHP tidak melakukan "pergeseran bulan" (misalnya, pertimbangkan bahwa 32 Januari adalah 1 Februari). Lihat DateTime::getLastErrors()untuk informasi lebih lanjut.

Solusi jadul dengan explodedan checkdate:

list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);

Ini memvalidasi bahwa input adalah tanggal yang valid juga. Anda dapat melakukannya dengan regex tentu saja, tetapi ini akan menjadi lebih merepotkan - dan 29 Februari tidak dapat divalidasi dengan regex sama sekali.

Kelemahan dari pendekatan ini adalah Anda harus sangat berhati-hati untuk menolak semua kemungkinan input "buruk" sambil tidak mengeluarkan pemberitahuan dalam keadaan apa pun. Begini caranya:

  • explodedibatasi untuk mengembalikan 3 token (sehingga jika masukannya adalah "1-2-3-4", $dakan menjadi "3-4")
  • ctype_digit digunakan untuk memastikan bahwa input tidak berisi karakter non-numerik (selain tanda hubung)
  • array_paddigunakan (dengan nilai default yang akan menyebabkan checkdatekegagalan) untuk memastikan bahwa cukup banyak elemen yang dikembalikan sehingga jika inputnya adalah "1-2" list()tidak akan mengeluarkan pemberitahuan

+1, selalu digunakan DateTimedan tidak pernah mendengar tentang checkdate... memalukan saya.
k102

@ k102: DateTimejuga bisa melakukan ini. Saya baru saja menyelesaikan jawabannya, lihat lagi jika Anda mau.
Jon

Melihat manual PHP, sepertinya solusi pertama akan memvalidasi tanggal yang tidak lengkap (mengisi nilai yang hilang dari tanggal sekarang).
pengguna2428118

Masalah lain dengan solusi # 1: "nilai non-existing roll over", misalnya 2001-02-31 menjadi 2001-03-03. (Meskipun OP tidak menanyakan secara eksplisit bahwa ini tidak mungkin.)
user2428118

1
@ user2428118: Apakah Anda mencoba solusi # 1 persis seperti yang diberikan, atau hanya baris pertama? Apakah Anda mengklik link yang saya berikan ke dokumentasi getLastErrors?
Jon

42

tttt-bb-hh: /^((((19|[2-9]\d)\d{2})\-(0[13578]|1[02])\-(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\-(0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\-02\-(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\-02\-29))$/g

tttt / bb / hh: /^((((19|[2-9]\d)\d{2})\/(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\/(0[13456789]|1[012])\/(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\/02\/(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/02\/29))$/g

bb-hh-tttt: /^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

bb / hh / tttt: /^(((0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])\/((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\/(0[1-9]|[12]\d|30)\/((19|[2-9]\d)\d{2}))|(02\/(0[1-9]|1\d|2[0-8])\/((19|[2-9]\d)\d{2}))|(02\/29\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

hh / bb / tttt: /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

hh-bb-tttt: /^(((0[1-9]|[12]\d|3[01])\-(0[13578]|1[02])\-((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\-(0[13456789]|1[012])\-((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\-02\-((19|[2-9]\d)\d{2}))|(29\-02\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g


Di atas semua pekerjaan untuk tanggal dari 1900 hingga 9999 yang paling dibutuhkan sepanjang waktu dan 74 karakter lebih pendek dari upaya saya (re format tttt-bb-hh). jika Anda menginginkan tanggal sebelum tahun 1900, maka sedikit perubahan pada jawaban Shyju akan memungkinkan dari tahun 1000 dan 23 karakter lainnya lebih pendek: ^ ((([1-9] \ d {3}) \ - (0 [13578] | 1 [02]) \ - (0 [1-9] | [12] \ d | 3 [01])) | (((19 | [2-9] \ d) \ d {2}) \ - ( 0 [13456789] | 1 [012]) \ - (0 [1-9] | [12] \ d | 30)) | (([1-9] \ d {3}) \ - 02 \ - (0 [1-9] | 1 \ d | 2 [0-8])) | (([1-9] \ d (0 [48] | [2468] [048] | [13579] [26]) | ( (16 | [2468] [048] | [3579] [26]) 00)) \ - 02 \ -29)) $
Graham

36

Kriteria:

Setiap tahun habis dibagi 4 adalah tahun kabisat, kecuali jika habis habis 100 kecuali habis habis 400. Jadi:

2004 - leap year - divisible by 4
1900 - not a leap year - divisible by 4, but also divisible by 100
2000 - leap year - divisible by 4, also divisible by 100, but divisible by 400

Februari memiliki 29 hari sebagai tahun kabisat dan 28 hari sebagai tahun kabisat

30 hari pada bulan April, Juni, September dan November

31 hari di bulan Januari, Maret, Mei, Juli, Agustus, Oktober dan Desember

Uji:

Semua tanggal berikut harus lulus validasi:

1976-02-29
2000-02-29
2004-02-29
1999-01-31

Tanggal-tanggal berikut ini harusnya semua gagal validasi:

2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00

Jarak:

Kami akan menguji untuk tanggal dari 1 Jan 1000 hingga 31 Des 2999. Secara teknis, kalender Gregorian yang saat ini digunakan hanya mulai digunakan pada 1753 untuk Kerajaan Inggris dan pada berbagai tahun pada 1600-an untuk negara-negara di Eropa, tetapi saya tidak akan melakukannya khawatir tentang itu.

Regex untuk menguji tahun kabisat:

Tahun-tahun yang habis dibagi 400:

1200|1600|2000|2400|2800
can be shortened to:
(1[26]|2[048])00

if you wanted all years from 1AD to 9999 then this would do it:
(0[48]|[13579][26]|[2468][048])00
if you're happy with accepting 0000 as a valid year then it can be shortened:
([13579][26]|[02468][048])00

Tahun-tahun yang habis dibagi 4:

[12]\d([02468][048]|[13579][26])

Tahun-tahun yang habis dibagi 100:

[12]\d00

Tidak habis dibagi 100:

[12]\d([1-9]\d|\d[1-9])

Tahun-tahun yang habis dibagi 100 tetapi tidak habis dibagi 400:

((1[1345789])|(2[1235679]))00

Dapat dibagi 4 tetapi tidak dibagi 100:

[12]\d([2468][048]|[13579][26]|0[48])

Tahun kabisat:

divisible by 400 or (divisible by 4 and not divisible by 100)
((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48])

Tidak habis dibagi 4:

[12]\d([02468][1235679]|[13579][01345789])

Bukan tahun kabisat:

Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)

Bulan dan hari yang valid kecuali Februari (MM-DD):

((01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|((04|06|09|11)-(0[1-9]|[12]\d|30))
shortened to:
((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30))

Februari dengan 28 hari:

02-(0[1-9]|1\d|2[0-8])

Februari dengan 29 hari:

02-(0[1-9]|[12]\d)

Tanggal berlaku:

(leap year followed by (valid month-day-excluding-february OR 29-day-february)) 
OR
(non leap year followed by (valid month-day-excluding-february OR 28-day-february))

((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8]))))

Jadi begitulah regex untuk tanggal antara 1 Jan 1000 dan 31 Des 2999 dalam format YYYY-MM-DD.

Saya kira ini bisa dipersingkat, tapi saya serahkan pada orang lain.

Itu akan cocok dengan semua tanggal yang valid. Jika Anda ingin itu hanya berlaku ketika itu hanya berisi satu tanggal dan tidak ada yang lain, maka bungkuslah ^( )$seperti ini:

^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$

Jika Anda menginginkannya untuk entri tanggal opsional (misalnya dapat dikosongkan atau tanggal yang valid) kemudian tambahkan ^$|di awal, seperti ini:

^$|^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$

8
Itu adalah ekspresi heroik, dan dijelaskan dengan sangat baik.
ambient

Apakah Anda memiliki bukti kuat bahwa itu akan melewati setiap kasus yang valid dan gagal pada setiap kasus yang tidak valid?
Md Ashraful Islam

@D Ashrul Islam No
Graham

@Graham Meskipun tidak masalah, kami menggunakannya di situs web kami. Saya harap tidak ada masalah yang terjadi.
Md Ashraful Islam

@Md Ashraful Islam - Kami juga menggunakannya dan sejauh ini tidak ada masalah dengan itu
Graham

18

Anda bisa membuatnya seperti ini:

if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
    echo 'true';
} else {
    echo 'false';
}

tetapi Anda sebaiknya menggunakan yang ini:

$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
    echo $date -> format('Y-m-d');
}

dalam hal ini Anda akan mendapatkan objek yang lebih mudah digunakan daripada string.


1
Teknik dateTime yang digunakan di sini akan mengembalikan true untuk tanggal seperti 2016-05-44 yang bukan tanggal sebenarnya
nonybrighto

Ini bukan contoh yang baik apalagi jika Anda ingin mendapatkan kencan (Ymd). Contoh: 0175-44-19927akan lulus.
Attila Naghi

7

Saya tahu ini pertanyaan lama. Tapi saya rasa saya punya solusi yang bagus.

$date = "2016-02-21";
$format = "Y-m-d";

if(date($format, strtotime($date)) == date($date)) {
    echo "true";
} else {
    echo "false";
}

Kamu bisa mencobanya. Jika Anda mengubah tanggal menjadi 21.02.2016 gema tersebut salah. Dan jika Anda mengubah format setelah itu menjadi dmY echo benar.

Dengan kode mudah ini, Anda seharusnya dapat memeriksa format tanggal mana yang digunakan tanpa memeriksanya dengan regex.

Mungkin ada orang yang akan mengujinya di setiap kasus. Tapi saya pikir ide saya secara umum valid. Bagi saya ini sepertinya logis.


Saya rasa Anda tidak perlu date () sekitar $ date di baris if. if (date ($ format, strtotime ($ date)) == $ date) - harus cukup
iateadonut

7

Anda dapat menggunakan preg_match dengan fungsi php checkdate

$date  = "2012-10-05";
$split = array();
if (preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split))
{
    return checkdate($split[2], $split[3], $split[1]);
}

return false;

return preg_match ("/ ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) $ /", $ date, $ split)) && tanggal cek ($ split [2], $ split [3], $ split [1]);
Tiberiu-Ionuț Stan

5

preg_match membutuhkan / atau karakter lain sebagai pembatas.

preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)

Anda juga harus memeriksa validitas tanggal tersebut sehingga Anda tidak akan mendapatkan sesuatu seperti 9999-19-38

bool checkdate ( int $month , int $day , int $year )

3

Anda juga bisa melakukannya seperti ini:

if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {

    // date is correctly formatted and valid, execute some code

}

Ini tidak hanya akan memeriksa format, tetapi juga validitas tanggal itu sendiri, karena DateTimehanya akan membuat tanggal yang valid dan ini harus cocok dengan masukan.


3

kamu bisa memakai

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

$date="2012-09-12";    
echo validateDate($date, 'Y-m-d'); // true or false

2

Periksa dan validasi YYYY-MM-DDtanggal dalam satu baris pernyataan

function isValidDate($date) {
    return preg_match("/^(\d{4})-(\d{1,2})-(\d{1,2})$/", $date, $m)
        ? checkdate(intval($m[2]), intval($m[3]), intval($m[1]))
        : false;
}

Outputnya adalah:

var_dump(isValidDate("2018-01-01")); // bool(true)
var_dump(isValidDate("2018-1-1"));   // bool(true)
var_dump(isValidDate("2018-02-28")); // bool(true)
var_dump(isValidDate("2018-02-30")); // bool(false)

Hari dan bulan tanpa awalan nol diperbolehkan. Jika Anda tidak ingin mengizinkan ini, regexp harus:

"/^(\d{4})-(\d{2})-(\d{2})$/"

1

Jika Anda ingin mencocokkan jenis tanggal itu, gunakan:

preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)

1

Ini akan memberi tahu Anda jika formatnya valid dan jika tanggal input valid.

    $datein = '2012-11-0';

    if(preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $datein)){
        echo 'good';
    }else{
        echo 'no good';
    }

1

Jika ada bantuan, berikut adalah regex untuk format jnY (tahun harus lebih besar dari 2018):

if (preg_match('/^([1-9]|[1-2][0-9]|[3][0-1])\-([1-9]|[1][0-2])\-(?:20)([1][8-9]|[2-9][0-9])$/', $date)) {
   // Do stuff
}

1

Format 1: $ format1 = "2012-12-31";

Format 2: $ format2 = "31-12-2012";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$format1)) {
    return true;
} else {
    return false;
}

if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/",$format2)) {
    return true;
} else {
    return false;
}

1

Mungkin berguna bagi seseorang:

$patterns = array(
            'Y'           =>'/^[0-9]{4}$/',
            'Y-m'         =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])$/',
            'Y-m-d'       =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$/',
            'Y-m-d H'     =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4])$/',
            'Y-m-d H:i'   =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?(0|[0-5][0-9]|60)$/',
            'Y-m-d H:i:s' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?((0|[0-5][0-9]):?(0|[0-5][0-9])|6000|60:00)$/',
        );
echo preg_match($patterns['Y'], '1996'); // true
echo preg_match($patterns['Y'], '19966'); // false
echo preg_match($patterns['Y'], '199z'); // false
echo preg_match($patterns['Y-m'], '1996-0'); // false
echo preg_match($patterns['Y-m'], '1996-09'); // true
echo preg_match($patterns['Y-m'], '1996-1'); // true
echo preg_match($patterns['Y-m'], '1996/1'); // true
echo preg_match($patterns['Y-m'], '1996/12'); // true
echo preg_match($patterns['Y-m'], '1996/13'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-1'); // true
echo preg_match($patterns['Y-m-d'], '1996-11-0'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-32'); // false
echo preg_match($patterns['Y-m-d H'], '1996-11-31 0'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 00'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 24'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 25'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 2400'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:00'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:59'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:60'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:6000'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:00'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:59'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:60'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:01'); // false

'1996-11-31 24:00'); // true, Betulkah? Selain itu, terkadang ada 61 detik dalam satu menit, lihat: en.wikipedia.org/wiki/Leap_second
Toto

1

Fungsi untuk memvalidasi format tanggal umum:

function validateDate($date, $format = 'Y-m-d') {
  $d = DateTime::createFromFormat($format, $date);
  return $d && $d->format($format) == $date;
}

Contoh eksekusi:

var_dump(validateDate('2021-02-28')); // true
var_dump(validateDate('2021-02-29')); // false

Harap letakkan jawaban Anda selalu dalam konteks, bukan hanya menempelkan kode. Lihat di sini untuk lebih jelasnya. Harap edit juga jawaban Anda untuk memuat semua bagian kode di blok penurunan harga
gehbiszumeis

0

Itu semua tergantung pada seberapa ketat Anda menginginkan fungsi ini. Misalnya, jika Anda tidak ingin mengizinkan bulan di atas 12 dan hari di atas 31 (tidak bergantung pada bulannya, itu akan memerlukan penulisan logika tanggal), ini bisa menjadi sangat rumit:

function checkDate($date)
{
  $regex = '/^' . 
    '(' .

    // Allows years 0000-9999
    '(?:[0-9]{4})' .
    '\-' .

    // Allows 01-12
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)' .
    ')' .
    '\-' .

    // Allows 01-31
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)|(?:13)|(?:14)|(?:15)|(?:16)|(?:17)|(?:18)|(?:19)|(?:20)|' .
    '(?:21)|(?:22)|(?:23)|(?:24)|(?:25)|(?:26)|(?:27)|(?:28)|(?:29)|(?:30)|' .
    '(?:31)' .
    ')' .

    '$/';

  if ( preg_match($regex, $date) ) {
    return true;
  }

  return false;
}

$result = checkDate('2012-09-12');

Secara pribadi saya hanya akan pergi untuk: /^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/


4
Regex ini tidak perlu rumit. 0[1-9]|1[0-2]mencocokkan bulan 01-12 dan 0[1-9]|[12][0-9]|3[01]mencocokkan hari 01-31.
estrar

Permisi saat saya muntah
AlxVallejo

0

Untuk bekerja dengan tanggal di php Anda harus mengikuti standar php sehingga regex yang diberikan akan memastikan bahwa Anda memiliki tanggal yang valid yang dapat beroperasi dengan PHP.

    preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)

Rgex Anda salah, tidak akan cocok 1980-01-01tetapi akan cocok2100-02-29
Toto

0

Metode ini dapat berguna untuk memvalidasi tanggal dalam PHP. Metode saat ini adalah untuk format bb / hh / tttt. Anda harus memperbarui urutan parameter di checkdate sesuai format Anda dan pembatas di meledak .

    function isValidDate($dt)
    {
        $dtArr = explode('/', $dt);
        if (!empty($dtArr[0]) && !empty($dtArr[1]) && !empty($dtArr[2])) {
            return checkdate((int) $dtArr[0], (int) $dtArr[1], (int) $dtArr[2]);
        } else {
            return false;
        }
    }

0

[Jika Anda menggunakan Symfony 4.1.2 coba ini] [1]

  $validDate = explode("-",$request->get('date'));
        if (checkdate(filter_var($validDate[1],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[0],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[2],FILTER_SANITIZE_NUMBER_INT))){
            $date = date_create(filter_var($request->get('date'),FILTER_SANITIZE_SPECIAL_CHARS));
        }else{
            return $this->redirectToRoute('YOUR_ROUTE');
        }

0

Dari Laravel 5.7 dan format tanggal yaitu: 12/31/2019

function checkDateFormat(string $date): bool
{
    return preg_match("/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/[0-9]{4}$/", $date);
}

0

Saya sedang mencari "cara memvalidasi tanggal" dan menemukan solusi ini, Ini lama tetapi saya akan membagikan metode di bawah ini yang dapat digunakan untuk memvalidasi tanggal di php,

checkdate('01', '31', '2019')
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.