Tarihi kontrol etmek için PHP Regex, YYYY-AA-GG biçimindedir


101

Son kullanıcılar tarafından girilen tarihlerin YYYY-AA-GG içinde olup olmadığını kontrol etmeye çalışıyorum. Regex hiçbir zaman güçlü yanım olmadı, kurulumum olan preg_match () için yanlış bir dönüş değeri almaya devam ediyorum.

Bu nedenle, aşağıda ayrıntıları verilen normal ifadeyi karıştırdığımı varsayıyorum.

$date="2012-09-12";

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

Düşüncesi olan var mı?


6
Normal ifade bir tarihi doğrulamak için yeterli değildir. Regex'ten sonra şu ikisinden birini de kullanmalısınız: date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";veya PHP'lerden checkdate ( int $month , int $day , int $year ).
Tiberiu-Ionuț Stan

Bu noktada doğrulamaya çalışmıyorum, sadece YYYY-AA-GG formatında olduğundan emin olmak istiyorum.
cosmicsafari

2
Kullanıcı tarafından girilen bir değer için, form gönderimi sırasında normal ifadeden hemen sonra doğrulamak dışında daha iyi bir "nokta" (böylece bir hata görüntüleyebilirsiniz)?
Tiberiu-Ionuț Stan

Doğru nokta, daha sonra bir ani sıkıntıyı kurtarabilir.
cosmicsafari

Yanıtlar:


203

Bunu dene.

$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);
Tiberiu-Ionuț Stan

5
Bu neden doğru cevap olarak işaretlendi? Bu, 2016-02-30 ve 2016-09-31 gibi bir dizi geçersiz tarih için doğru değerini döndürür
Graham,

7
Bu soru, bir tarih formatının (YYYY-AA-GG) nasıl kontrol edileceğiyle ilgilidir ve kabul edildi olarak işaretlenen bir cevap her zaman en iyi cevap değildir, sadece soran kişi için işe yaradığı anlamına gelir, bu güzel turu okuyun: stackoverflow. com.tr / tour .
2017

@Graham eski gönderi Biliyorum ama Stramin ile aynı fikirdeyim - bu soru biçim doğrulamasını soruyor - gerçek tarih doğrulaması değil
treyBake

100

Bunun için başka bir mekanizma kullanmak muhtemelen daha iyidir.

Modern çözüm DateTime:

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

Bu, girdiyi de doğrular: $dt !== falsetarihin belirtilen biçimle ayrıştırılabilmesini sağlar ve array_sumhile, PHP'nin "ay kaydırma" yapmamasını sağlamanın kısa bir yoludur (örneğin, 32 Ocak'ın 1 Şubat olduğunu düşünün). Daha DateTime::getLastErrors()fazla bilgi için bakın .

Eski okul çözüm explodeve checkdate:

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

Bu, girişin de geçerli bir tarih olduğunu doğrular. Elbette bunu bir normal ifadeyle yapabilirsiniz, ancak daha fazla telaş olacak - ve 29 Şubat bir normal ifadeyle hiç doğrulanamaz.

Bu yaklaşımın dezavantajı, herhangi bir koşulda bir uyarı göndermeden olası tüm "kötü" girdileri reddetmek için çok dikkatli olmanız gerektiğidir. Bunu nasıl yapacağınız aşağıda açıklanmıştır:

  • explode3 jeton döndürmekle sınırlıdır (böylece giriş "1-2-3-4" $dise "3-4" olur)
  • ctype_digit girişin herhangi bir sayısal olmayan karakter içermediğinden emin olmak için kullanılır (kısa çizgiler dışında)
  • array_padcheckdategiriş "1-2" list()ise bir uyarı vermeyecek şekilde yeterli öğenin döndürüldüğünden emin olmak için kullanılır ( başarısız olmasına neden olacak varsayılan bir değerle )

+1, her zaman kullanılmış DateTimeve hiç duymamış checkdate... utan bana.
k102

@ k102: DateTimebunu da yapabilir. Cevabı şekillendirmeyi yeni bitirdim, istersen tekrar bak.
Jon

PHP kılavuzuna bakıldığında, ilk çözüm eksik tarihleri ​​doğrulayacak gibi görünüyor (mevcut tarihten eksik değerleri doldurarak).
user2428118

Çözüm 1 ile ilgili başka bir sorun: "var olmayan değerler devrilir", ör. 2001-02-31, 2001-03-03 olur. (OP bunun mümkün olmadığını açıkça sormamış olsa da)
user2428118

1
@ user2428118: Çözüm 1'i tam olarak verildiği gibi mi yoksa sadece ilk satırı mı denediniz? Belgelerine verdiğim bağlantıya tıkladınız getLastErrorsmı?
Jon

43

yyyy-aa-gg: /^((((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

yyyy / aa / gg: /^((((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

aa-gg-yyyy: /^(((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

aa / gg / yyyy: /^(((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

gg / aa / yyyy: /^(((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

gg-aa-yyyy: /^(((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


Yukarıdakilerin tümü 1900 ile 9999 arasındaki tarihler için çalışır ki bu çoğu zaman ihtiyaç duyulan şeydir ve denememden 74 karakter daha kısadır (yyyy-aa-gg formatı). 1900 öncesi tarihler istiyorsanız, Shyju cevabına yapılacak küçük bir ince ayar 1000 yıldan itibaren izin verir ve 23 karakter daha kısadır: ^ ((([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

Kriterler:

4'e bölünebilen her yıl, 400'e bölünmediği sürece 100 ile bölünebildiği durumlar dışında artık bir yıldır.

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

Şubatta artık yılda 29 gün ve artık yıl olmadığında 28 gün vardır

Nisan, Haziran, Eylül ve Kasım aylarında 30 gün

Ocak, Mart, Mayıs, Temmuz, Ağustos, Ekim ve Aralık aylarında 31 gün

Ölçek:

Aşağıdaki tarihlerin tümü doğrulamadan geçmelidir:

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

Aşağıdaki tarihlerin tümü doğrulamada başarısız olmalıdır:

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

Aralık:

1 Ocak 1000'den 31 Aralık 2999'a kadar olan tarihleri ​​test edeceğiz. Teknik olarak şu anda kullanılan Gregoryen takvimi yalnızca 1753'te Britanya İmparatorluğu için ve 1600'lerde çeşitli yıllarda Avrupa ülkeleri için kullanılmaya başlandı, ancak ben bunu yapmayacağım bunun için endişelen.

Artık yılı test etmek için normal ifade:

400 ile bölünebilen yıllar:

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

4'e bölünebilen yıllar:

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

100'e bölünebilen yıllar:

[12]\d00

100'e bölünemez:

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

Yıllar 100'e bölünebilir ancak 400'e bölünemez:

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

4'e bölünebilir ancak 100'e bölünemez:

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

Artık yıllar:

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

4'e bölünemez:

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

Artık yıl değil:

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

Şubat hariç geçerli Ay ve gün (AA-GG):

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

28 günlük Şubat:

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

29 günlük Şubat:

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

Geçerli tarih:

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

İşte burada 1 Ocak 1000 ve 31 Aralık 2999 tarihleri ​​için YYYY-AA-GG biçiminde bir normal ifade var.

Biraz kısaltılabileceğinden şüpheleniyorum ama bunu başkasına bırakacağım.

Bu, tüm geçerli tarihlerle eşleşecek. Yalnızca bir tarih içerdiğinde ve başka hiçbir şey içermediğinde geçerli olmasını istiyorsanız, o zaman şu şekilde sarın ^( )$:

^(((((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])))))$

Opsiyonel bir tarih girişi için istiyorsanız (yani boş veya geçerli bir tarih olabilir), o zaman ^$|başlangıca şu şekilde ekleyin :

^$|^(((((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
Bu kahramanca bir ifadedir ve çok iyi açıklanmıştır.
ortam

Her geçerli vakayı geçeceğine ve her geçersiz vakada başarısız olacağına dair güçlü kanıtınız var mı?
Md Ashraful Islam

@Md Ashraful Islam No
Graham

@Graham Sorun olmamakla birlikte web sitemizde kullanıyoruz. Umarım sorun çıkmaz.
Md Ashraful Islam

@Md Ashraful Islam - Biz de kullanıyoruz ve şu ana kadar herhangi bir sorun yaşamadık
Graham

18

Bunu şu şekilde yapabilirsiniz:

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

ama bunu kullansan iyi olur:

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

bu durumda, kullanımı sadece dizelerden daha kolay olan bir nesne alırsınız.


2
Burada kullanılan dateTime tekniği, gerçek bir tarih olmayan 2016-05-44 gibi bir tarih için true değerini döndürecektir
nonybrighto

Bu iyi bir örnek değil, özellikle randevu almak istiyorsanız (Ymd). Örnek: 0175-44-19927geçecek.
Attila Naghi

7

Bunun eski bir soru olduğunu biliyorum. Ama iyi bir çözümüm olduğunu düşünüyorum.

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

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

Deneyebilirsin. Tarihi 21.02.2016 olarak değiştirirseniz yankı yanlıştır. Ve bundan sonra formatı dmY olarak değiştirirseniz, yankı doğrudur.

Bu kolay kodla, normal ifadeyle kontrol etmeden hangi tarih formatının kullanıldığını kontrol edebilmelisiniz.

Belki her vakada test edecek bir kişi vardır. Ama fikrimin genel olarak geçerli olduğunu düşünüyorum. Benim için mantıklı görünüyor.


İf satırında $ date () civarında tarihe ihtiyacınız olduğunu sanmıyorum. eğer (tarih ($ format, strtotime ($ tarih)) == $ tarih) - yeterli olmalıdır
iateadonut

7

Checkdate php işlevi ile bir preg_match kullanabilirsiniz

$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}) $ /", $ tarih, $ bölme)) && checkdate ($ bölme [2], $ bölme [3], $ bölme [1]);
Tiberiu-Ionuț Stan

5

preg_match, sınırlayıcı olarak bir / veya başka bir karaktere ihtiyaç duyar.

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

9999-19-38 gibi bir şeyle sonuçlanmamak için o tarihin geçerliliğini de kontrol etmelisiniz

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

3

Bunu şu şekilde de yapabilirsiniz:

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

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

}

Bu sadece formatı kontrol etmekle kalmayacak, aynı zamanda self tarihinin geçerliliğini de kontrol DateTimeedecektir , çünkü sadece geçerli tarihler yaratacaktır ve bunun girdiyle eşleşmesi gerekir.


3

kullanabilirsiniz

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

YYYY-MM-DDTek satırlık ifadede tarihi kontrol edin ve doğrulayın

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;
}

Çıktı şu şekilde olacaktır:

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)

Başında sıfır olmadan gün ve aya izin verilir. Buna izin vermek istemiyorsanız normal ifade şöyle olmalıdır:

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

2

Muhtemelen birisi için yararlıdır:

$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, Gerçekten mi? Dahası, bazen bir dakikada 61 saniye olabilir, bakınız: en.wikipedia.org/wiki/Leap_second
Toto

1

Bu tür bir tarihle eşleştirmek istiyorsanız, şunu kullanın:

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

1

Bu size formatın geçerli olup olmadığını ve giriş tarihinin geçerli olup olmadığını söylemelidir.

    $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

Herhangi bir yardımı olacaksa, jnY ​​formatı için bir normal ifade (yıl 2018'den büyük olmalıdır):

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

Biçim 1: $ biçim1 = "2012-12-31";

Biçim 2: $ biçim2 = "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

Genel tarih biçimini doğrulama işlevi:

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

Uygulama örneği:

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

Lütfen yalnızca kodu yapıştırmak yerine yanıtınızı her zaman bağlama oturtun. Daha fazla ayrıntı için buraya bakın. Lütfen yanıtınızı
markdown

0

Her şey, bu işlevin ne kadar katı olmasını istediğinize bağlıdır. Örneğin, 12'nin üzerindeki aylara ve 31'in üzerindeki günlere izin vermek istemiyorsanız (aya bağlı olarak değil, tarih mantığı yazmayı gerektirir), oldukça karmaşık hale gelebilir:

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

Şahsen ben şunun için giderdim: /^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/


4
Bu normal ifade gereksiz yere karmaşıktır. 0[1-9]|1[0-2]01-12 0[1-9]|[12][0-9]|3[01]. aylarla ve 01-31. günlerle eşleşir.
estrar

İ kusmuk ise Afedersiniz
AlxVallejo

0

Php'de tarihlerle çalışmak için php standardını izlemelisiniz, böylece verilen regex PHP ile çalışabilecek geçerli bir tarihe sahip olmanızı sağlayacaktır.

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

Rgex'iniz yanlış, eşleşmeyecek 1980-01-01ama eşleşecek2100-02-29
Toto

0

Bu yöntem PHP'de tarihi doğrulamak için yararlı olabilir. Geçerli yöntem aa / gg / yyyy biçimi içindir. Sen parametre dizisi güncellemek zorunda checkdate de formattır ve sınırlayıcı göre patlayabilir .

    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

[Symfony 4.1.2 kullanıyorsanız bunu deneyin] [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

Laravel 5.7'den ve tarih biçiminden, yani: 31.12.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

"Tarih nasıl doğrulanır" arıyordum ve bu çözümü buldum, Eski ama php'de tarihi doğrulamak için kullanılabilecek yöntemi aşağıda paylaşacağım,

checkdate('01', '31', '2019')
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.