preg_match for mysql date format - php

im trying to validate a date to see if it matchs the mysql format
this is the code
$match = "/^\d{4}-\d{2}-\d{2} [0-2][0-3]:[0-5][0-9]:[0-5][0-9]$/";
$s = $this->input->post("report_start"). " " . $this->input->post("report_start_time").":00";
$e = $this->input->post("report_end"). " " . $this->input->post("report_end_time").":59";
if($this->input->post("action") != "")
{
echo trim($s). " => " . preg_match($match, trim($s));
echo "<br>";
echo trim($e). " => " . preg_match($match, trim($e));
}
the date format goes into $s and $e are
$s = 2011-03-01 00:00:00
$e = 2011-03-01 23:59:59
and they both return false (0).
i tested the pattern on http://www.spaweditor.com/scripts/regex/index.php and it returns true (1)
http://pastebin.com/pFZSKYpj
however if i manual inter the date strings into preg_match like
preg_match($match, "2011-03-01 00:00:00")
it works.
i have no idea what im doing wrong
======================
now that i think about it, i only need to validate the houre:min part of the datetime string.
im manually adding the seconds and the date is forced by a datepicker and users cant edit it

You're making your work harder that it needs to be. In php there are many date handling functions that mean you don't have to treat dates like strings. So, rather than test that your input dates are in the correct format, just insist on the correct format:
$adate= date_create('January 6, 1983 1:30pm'); //date format that you don't want
$mysqldate= $adate->format("Y-m-d h:i:s");//date format that you do want
There are also functions to check that a date is a real date, like checkdate.

ok heres wat i did.
since im forcing the date format and the ending seconds of the time part
i just validated the hour:mini part using "/^2[0-3]|[01][0-9]:[0-5][0-9]$";
and if that returns true i put everything together end reconstructed the final datetime string
$match = "/^2[0-3]|[01][0-9]:[0-5][0-9]$/";
$s_d = $this->input->post("report_start");
$s_t = $this->input->post("report_start_time");
$e_d = $this->input->post("report_end");
$e_t = $this->input->post("report_end_time");
if($this->input->post("action") != "")
{
if(
( preg_match($match , trim($s_d." ".$s_t.":00")) )
&& ( preg_match($match , trim($e_d." ".$e_t.":59")) )
)
{
$r = $this->model_report->client_hours_logged(array($s,$e));
$data['report'] = $r;
var_dump($r);
//$this->load->view("report/client_hours_per_client",$data);
}
}

Watch out:
[0-2][0-3] is not a good regex for hour values - it will match 01, 12, 23 and others, but it will fail 04 through 09 and 14 through 19.
Better use (2[0-3]|[01][0-9]) instead.

I use this to validate a 'Y-m-d H:i:s' format date string:
match = '/^[12][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[01]) ([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/';

You could use strtotime and date to parse and format the date properly.

Why not just simply force the date into the format you want:
$e = '2011-03-01 00:00:00';
$mysqlFormat = date('Y-m-d H:i:s', strtotime($e));
Also, there is a bit of an error in your regex [0-2][0-3]:[0-5][0-9]:[0-5][0-9] will only match the hours of 00,01,02,03,10,11,12,13,20,21,22,23 so it will never match 4am, or 3pm among others. That aside I looked over your RegEx and I don't see any problems with it matching the test cases you've offered. I would check to make sure there is not extra whitespace on either side of date string with trim().

I concur with Tim : MySQL behaves in quirks mode and always tries to go easy on DATE and DATE_TIME column types. You can omit certain parts of your input and it still will try to compensate and achieve that goal successfully to some degree... That's why, most numbers your Reg-ex considers as invalid, MySQL will accept as valid.

Related

regex match cond1 OR match cond2 in single command

I need to check if entered date is between 2019-09-01 - 2019-12-31
I can do this as follows: $koodi is user input
$pattern1 = "/^2019-(09|11)-([0-2][0-9]|30)$/";
$pattern2 = "/^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
if(preg_match($pattern1, $koodi) || preg_match($pattern2, $koodi)) {
echo "<code>$koodi</code> ok!<br>\n";
}
else {
echo ("<code>$koodi</code> NOT ok!<br>\n");
}
I was trying to make those two conditions into single regex statement, is that possible and if so how?
I tried:
$pattern = "/^2019-(09|11)-([0-2][0-9]|30)$ | ^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
Did not work, neither the following where i tried to put parentheses around conditions:
$pattern = "/(^2019-(09|11)-([0-2][0-9]|30)$) | (^2019-(10|12)-([0-2][0-9]|3[0-1])$)/";
Please don't use a regex to do that, what if the dates change or what if the next developer has to come and work on this and figure out what your doing?
According to this article you can check if a date is between 2 dates by doing something like this.
<?php
$currentDate = date('Y-m-d');
$currentDate = date('Y-m-d', strtotime($currentDate));
$startDate = date('Y-m-d', strtotime("01/09/2019"));
$endDate = date('Y-m-d', strtotime("01/10/2019"));
if (($currentDate >= $startDate) && ($currentDate <= $endDate)){
echo "Current date is between two dates";
}else{
echo "Current date is not between two dates";
}
as for why your patterns didn't work its because you have a space around the pipe in the middle and you may possibly need to wrap the whole thing in brackets. You also have the $ half way through the regex which is matching the whole string, I would usually only have it at the end, like this: -
^(regex1|regex2)$
I haven't written the correct version in case your tempted to use it, (please use the date objects method)

How to compare date strings in the format yyyy-mm-dd in PHP

I have a range of dates in string format in the form of
'2014-10-12'
what i want to do is compare these dates so i can get the oldest and the youngest.
In PHP how do i convert these to a format where i can do the following?
$oldestdate;
$youngesdate;
//loop though all the dates
if($exampledate < $youngesdate)
$youesdate = $exampledate;
if($exampledate > $oldestdate)
$oldestdate = $exampledate;
Thanks
The nice thing about YYYY-MM-DD style dates is that they will always sort correctly, whether treated as text (as in your example), numbers (e.g. 20141012), or actual dates.
Thus, there's no need to do anything special to compare them as long as everything is the same format. Your code, as written, should work as-is (besides the typos for $youngestdate).
Note that if you want to do anything besides comparing them -- e.g. anything actually involving treating them like actual dates -- you will indeed want something like strtotime() or a mix of mktime() + substr()
have you tried strotime? reference http://php.net/manual/de/function.strtotime.php
then you can easily compare with <and > and so on.
have you tried checkdate(12, 31, 2000)? PHP.net Checkdate function
For years between 1 and 32767 inclusive.Check post 2 in the php.net link
You should use the DateTime class.
$arr = ['2012-10-12', '2004-10-12', '2014-08-12', '2014-09-12', '2014-09-13', '2014-09-11'];
$_now = new DateTime('now');
foreach ( $arr as $_t ) {
$d = new DateTime ( $_t );
if ( !isset($newest) || $d >= $newest ) $newest = $d;
if ( !isset($oldest ) || $d <= $oldest ) $oldest = $d;
}
echo 'Newest ' . $newest->format('Y-m-d');
echo 'Oldest' . $oldest->format('Y-m-d');
Take a look here: Reference on php.net
And here is an working example

Check whether day is specified in a date string

Test case scenario - User clicks on one of two links: 2012/10, or 2012/10/15.
I need to know whether the DAY is specified within the link. I am already stripping the rest of the link (except above) out of my URL, am I am passing the value to an AJAX request to change days on an archive page.
I can do this in either JS or PHP - is checking against the regex /\d{4}\/\d{2}\/\d{2}/ the only approach to seeing if the day was specified or not?
You can also do this if you always get this format: 2012/10 or 2012/10/15
if( str.split("/").length == 3 ) { }
But than there is no guaranty it will be numbers. If you want to be sure they are numbers you do need that kind of regex to match the String.
You could explode the date by the "/" delimiter, then count the items:
$str = "2012/10";
$str2 = "2012/10/5";
echo count(explode("/", $str)); // 2
echo count(explode("/", $str2)); // 3
Or, turn it into a function:
<?php
function getDateParts($date) {
$date = explode("/", $date);
$y = !empty($date[0]) ? $date[0] : date("Y");
$m = !empty($date[1]) ? $date[1] : date("m");
$d = !empty($date[2]) ? $date[2] : date("d");
return array($y, $m, $d);
}
?>
I would personally use a regex, it is a great way of testing this sort of thing. Alternatively, you can split/implode the string on /, you will have an array of 3 strings (hopefully) which you can then test. I'd probably use that technique if I was going to do work with it later.
The easiest and fastest way is to check the length of the string!
In fact, you need to distinguish between: yyyy/mm/dd (which is 10 characters long) and yyyy/mm (which is 7 characters).
if(strlen($str) > 7) {
// Contains day
}
else {
// Does not contain day
}
This will work EVEN if you do not use leading zeros!
In fact:
2013/7/6 -> 8 characters (> 7 -> success)
2013/7 -> 6 characters (< 7 -> success)
This is certainly the fastest code too, as it does not require PHP to iterate over the whole string (as using explode() does).

PHP format date

How can I force the date format to output:
12/12/2012, 1/10/2012, 1/5/2012
instead of
12/12/2012, 01/10/2012, 01/05/2012?
My code is the following:
$adatefrom = date_create($_POST['datefrom']);
$adateto = date_create($_POST['adateto']);
$adatefrom = date_format($adatefrom, 'd/m/Y');
$adateto = date_format($adateto, 'd/m/Y');
Please do note that I have to format the date AFTER posting it.
Have a look at the PHP built in date function here
You will find that your solution is as simple as this:
date('j/n/Y',strtotime($_POST['datefrom']));
The key things to note are the characters used in the first parameter.
j represents the day without leading zeros
n represents the month without leading zeros
There are many other options you have, just have a read through the documentation.
Please note that a simple search of 'PHP date' on Google would have found this solution for you
$adatefrom = date_create($_POST['datefrom']);
$adateto = date_create($_POST['adateto']);
$adatefrom = date_format($adatefrom, 'j/n/Y');
$adateto = date_format($adateto, 'j/n/Y');
you are welcome! ;)

strtotime date validation passes on invalid date

I am in the middle of setting up a basic CMS that allows the client to add articles to their mobile app. The CMS is coded in PHP and will use JSON to deliver the content to the mobile app.
Now my problem is there is an option to publish the article at a certain date, so I want to validate the date to check it is valid.
So to test possibilites I made a small script. I am using strtotime() to check the date is valid, my script is:
<?php
$date[] = '2011-31-01';
$date[] = '2011-02-31';
foreach($date as $str) {
if(strtotime($str) == false) {
$result[] = '<p>[' . $str . '] Resulted in an <span style="color: red;">Error.</span></p>';
} else {
$result[] = '<p>[' . $str . '] Resulted in <span style="color: green;">Success.</span></p>';
}
}
foreach($result as $return) {
echo $return;
}
?>
Now my problem is the date 2011-02-31 which is 31st February 2011 is returning as valid, when obviously it isn't. So my question is why does it do this? and is there a better method to check that the date is valid and exists?
Thanks in advance.
checkdate(); Validates a Gregorian date. Returns TRUE if the date given is valid; otherwise returns FALSE.
if(checkdate(2, 31, 2011)){
echo "Yeah";
} else {echo "nah";}
It returns false!
That's the way to go.
Unless you have one (or a small set) fixed format for your date string it will be hard to get an acceptable result. In case you know the format, you can either parse the string directly yourself (and test it afterwards with checkdate), or you use strptime to try parsing against known formats until you get a valid result.
If you don’t know the format, and you have to use strtotime, then you are required to accept that strtotime will try parsing the date string in the best possible way. This may lead to different dates than it was expected to be.

Categories