Dates got buggy when they are stored to database - php

I have two datepickers in format dd/mm/YYYY. Problem is that when I store them to database, they got buggy. Output is "1970-01-01'. I am also using mySQL STR_TO_DATE function and php built in function for date format... I don't know why my dates are not working. Can someone told me why my dates got buggy?
Here is code that I am using:
$datumDO=$_POST['datepicker'];
$datumOD=$_POST['datepicker1'];
$time = strtotime($datumDO);
$NewDatum = date('d/m/Y',$time);
$time = strtotime($datumOD);
$NewDatumOD = date('d/m/Y',$time);
if ($stmt = $dbConnection->prepare("INSERT INTO `cat-item` (id_cat, id_item, datumOD, datumDO) VALUES (?,?,STR_TO_DATE(?,'%d/%m/%Y'),STR_TO_DATE(?,'%d/%m/%Y'))")){
$stmt->bind_param('iiss', $category, $item, $NewDatum , $NewDatumOD;
$stmt->execute();
$stmt->close();
}

If your datepickers are providing dates in dd/mm/YYYY format (with / as the separator), the inputs to your functions are incorrect.
strtotime:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at
the separator between the various components: if the separator is a
slash (/), then the American m/d/y is assumed; whereas if the
separator is a dash (-) or a dot (.), then the European d-m-y format
is assumed. To avoid potential ambiguity, it's best to use ISO 8601
(YYYY-MM-DD) dates [ source ]

$datumDO= date('Y-m-d', strtotime($_POST['datepicker']));
$datumOD= date('Y-m-d', strtotime($_POST['datepicker1']));
if ($stmt = $dbConnection->prepare("INSERT INTO `cat-item` (id_cat, id_item, datumOD, datumDO) VALUES (?,?,?,?)")){
$stmt->bind_param('iiss', $category, $item, $datumDO, $datumOD;
$stmt->execute();
$stmt->close();
}
try this.....hope this helps

Related

php - uniformize date strings with different formats

I have an array with many different formats of dates. All strings.
I want to uniformize this into an array with dates(). Something like this:
function uniformize($str){
$date = strtotime($str);
return $date;
}
$arr = array(
'07/29/1975',
'20/01/1981',
'1983-05-24',
'10 /8 /1995'
);
print_r( array_map('uniformize', $arr) );
But this only works with one format:
Array (
[0] =>
[1] =>
[2] => 454215600
[3] =>
)
Is there any way I can do it for all formats?
You can use this function for that. Fiddle here
Notice it's supposed to have always the days before than the months. Otherwise it's impossible to know whether first part of the date is a day or a month (unless the day is more than 12.. and can't cover all the cases).
function date2time($date)
{
$date = str_replace(' ','',$date);
if(strpos($date,'-')!==false)
$date_array = explode('-',$date);
if(strpos($date,'/')!==false)
$date_array = explode('/',$date);
//add more delimiters if needed
$day = $month = $year = '';
foreach($date_array as $date_elem)
{
if(strlen($date_elem) < 3)
{
if(empty($day))
$day = $date_elem;
else
$month = $date_elem;
}else
$year = $date_elem;
}
$time = mktime(0,0,0,$month,$day,$year);
return $time;
}
$arr = array(
'07/29/1975',
'20/01/1981',
'1983-05-24',
'10 /8 /1995'
);
print_r( array_map('date2time', $arr) );
Unfortunately, I think you have to detect yourself the format and then convert it into the format you wish...
The real problem is about months and days...
some use 31-12-2014, other countries use 12-31-2014...
so you HAVE to define which is the month and the day in a string like 05-06-2015...
EDIT :
You have many regex to do...
I'm using this for 2015-12-31 format :
if(preg_match("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $yourDate, $split)) && (checkdate($split[2],$split[3],$split[1]))) {
// do stuff where $split[1] is years, split[2] is month, and split[3] is day
}
Then you may adapt it to every formats you encounter changing order...
checkdate checks if it is a valide date (2015-52-38 is not a valid date)
You may also find some on google with "date pattern regex" for instance...
The first two strings use / as component separator. The function strtotime consider them to be formatted according to the American format: month/day/year. Because 24 and 20 are invalid month numbers they cannot be parsed correctly.
The last string ('10 /8 /1995') looks like a short date format but the spaces inside the components also render it invalid.
As it is explained in a note in the documentation of function strtotime():
Note:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.
What can you do
If you know the order of components in your dates you can use str_replace() to always use / for m/d/y (the American format) and - for d-m-y (the European format). Also, you should strip the spaces.
Another option is to write your own date parser to identify the date components then use mktime() or DateTime::setDate() to get the date. However, if the date have both the day and the month in 1..12, the format cannot be detected and it have to be assumed (from the separator).

Check if date is in the next 3 days PHP

I have a date stored in my DB (due_date)
I am wanting to write a script that checks if the due_date is in the next 3 days
From checking online (google) i have found some code but it doesnt seem to work, see below
if (time() - filemtime($due_date) >= 3 * 86400)
{
echo" Invoice $id is due in the next 3 days<br />";
}
else
{
echo" Invoice $id not due in the next 3 days </br>";
}
$due_date contains a date in the format 01/01/2015
Please can someone help with this? P.s I am a newbie!
Thanks
Use strtotime() to convert the date string to a unix timestamp, and edit your if statement accordingly:
$seconds_to_expire = strtotime($due_date) - time();
if ($seconds_to_expire < 3*86400) {
...
Note that dates in the m/d/y or d/m/y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed (see this). You may want to convert your date to a Y-m-d format instead:
$due_date_ymd = date('Y-m-d', strtotime(str_replace('/', '-', $due_date));
$seconds_to_expire = strtotime($due_date_ymd) - time();
if ($seconds_to_expire < 3*86400) {
...
Change
filemtime($due_date)
to
strtotime(str_replace('/', '-', $due_date))
you have to change / to - if the day comes first, otherwise php will assume that first is month!
if (strtotime($due_date)+60*60*24*3 =< time()+60*60*24*3) {
echo "Is due in the next 3 days"
} else {
echo "Is not due in the next 3 days"
}
You could translate the DB date value (which is in the format 'yyyy-mm-dd') to a DateTime object and then compare:
$d = DateTime::createFromFormat('Y-m-d', $due_date);
$d->modify('-3 days'); // subtract 3 days from due date
if ($d < new DateTime()) {
echo 'date is due within 3 days';
}
Notes:
new DateTime() will give you the current date.
I assume that $due_date is a string in the format 'yyyy-mm-dd', as you should get if it is a Date column in the database.
Since you commented that $due_date is "A date in the format 01/01/2015", you can easily ajust the code: change the format specifier in the createFromFormat function from 'Y-m-d' into 'd/m/Y'.

PHP date conversion from user input

I am trying to convert a user inputted date so I can use it to search in MySQL. This is my code -
<form name="date_form" action="" method="POST"">
<input type="text" name="start_date" value="<?php echo date('d/m/Y');?>"/>
<input type="submit" name="submit_start" value="Submit" />
<?php
if(isset($_POST["submit_start"]))
{
$date_1 = mysqli_real_escape_string($dbc, trim($_POST['start_date']));//checking that I am getting something from the input
$newDate = date("Y-m-d", strtotime($_POST['start_date']));//converting date from the input to SQL format
echo '<br>date 1 = '.$date_1.'<br>';
echo 'date 2 = '.$newDate.'<br>';
$start_date = '2013-12-13';
echo 'date 3 = '.$start_date.'<br>';//Just to compare formats
$report = create_user_report($dbc, $start_date);
}
and this is the output
date 1 = 14/12/2013
date 2 = 1970-01-01
date 3 = 2013-12-13
2013-12-13
I was expecting date 2 to be 2013-12-13, the format appears to be ok but the value isnt. I have played with many different ways of getting the value, all have been wrong!
So I have two questions please
1. How can I get the correct value in the code above?
2. I want to use this value to search a MySQL table and return a count of dates that match it. Once the above is working, is that the best way to do it - or is there a better way?
Many thanks
From the strtotime manual:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between
the various components: if the separator is a slash (/), then the American m/d/y is
assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y
format is assumed.
So:
$newDate = date("Y-m-d", strtotime($_POST['start_date']))
is asking for the 12th day of the 14th month.
Try replacing the / with -
$date = str_replace ( '/' , '-' , $_POST['start_date'])
The problem is caused because when confronted with /, strtotime assumes the time to be in the American format of m/d/Y (instead of d/m/Y). Read the manual on strtotime (especially the Notes) for more information.
And because 14/12/2013 is not valid in the American format, you'll get the default time (aka UNIX timestamp 0).
Since this is user input and you cannot be sure if he really means to use the American format or is misusing it, you could do a check before the conversion like this
//check if input is a date in the American format
if (preg_match("#^(\d+)/(\d+)/(\d+)$#", $_POST['start_date'], $matches)) {
if ($matches[1] > $matches[2]) {
$day = $matches[1];
$month = $matches[2];
} else {
$day = $matches[2];
$month = $matches[1];
}
$start_date = $month.'/'.$day.'/'.$matches[3];
}
However if a user inputs e.g. 04/05/2013 this will be interpreted in the American format, although the user could have meant it in d/m/Y.
"Explode" seems to be commonly used in situations like this.
$mydate = $_POST["submit_start"];
list ($y, $m, $d) = explode('/', $mydate);
$mydate = sprintf("%02d-%02d-%04d", $m, $d, $y);
strtotime requires the English date format as input - HERE.
strtotime() PHP Manual
Take a look over there, it reports
The function expects to be given a string containing an English date format
And that's why your function doesn't work as you expect. In fact, d/m/Y is NOT an american date format. Here, take a look, I made you some examples to let you see how to make it work: Click here - eval.in
<?php
echo strtotime(date('m/d/Y'));
echo strtotime(date('d/m/Y'));
echo strtotime(date('d-m-Y'));
echo strtotime(date('d/m/Y'));
echo strtotime(date('Y-m-d'));
echo strtotime(date('Y/m/d'));
?>
Produces
1386979200
FALSE
1386979200
FALSE
1386979200
1386979200
Since you'll never know what kind of date format (or if it's actually a date at all) an user may input, I suggest you to use a date picker plugin on your input, that'll be very useful, or you may want to use a regular expression that other user suggested.
For the mysql part you can easly compare two dates with the MySQL Date Function
Since I don't know your query I'll just provide you the part you need for the comparsion in the query:
... WHERE DATE(some_date) = DATE(some_other_date) ...
Where some_date and some_other_date are two valid date formats as written above.

How to use PHP's strtotime

I'm new to PHP and kind of struggling with the basics, please excuse the horrible code to come.
What I'm trying to do is parse a date retrieved from an XML file, and see if that date falls on a Monday/Tuesday/etc.
I can't seem to get it right, any help is much appreciated.
<?php
foreach ($xml as $x)
{
$time = strtotime($x->Start);
echo $time;
if(date('D', $time) === 'Mon')
echo "Booking for Monday";
else if(date('D', $time) === 'Tue')
echo "Booking for Tuesday";
else if(date('D', $time) === 'Wed')
echo "Booking for Wednesday";
else if(date('D', $time) === 'Thu')
echo "Booking for Thursday";
else if(date('D', $time) === 'Fri')
echo "Booking for Friday";
}
?>
$time isn't outputting anything, and the only result coming back is "Booking for Thursday" for each XML record (x5) despite only two of the records falling on a Thursday.
If I output the results by:
echo $x->Start;
That works fine and outputs "15/07/2013 9:30:00 a.m.".
Cheers!
The date looks like European format d-m-y and uses American format m/d/y seperator.
Note:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at
the separator between the various components: if the separator is a
slash (/), then the American m/d/y is assumed; whereas if the
separator is a dash (-) or a dot (.), then the European d-m-y format
is assumed.
Instead of
$time = strtotime($x->Start);
Try
$time = strtotime(str_replace('/','-',$x->Start));
Additional Info :PHP Manual
you have to convert your time string($x->Start) to one of the Supported Formats before passing it to the strtotime.
Replacing / with . would change your date to a support format. but double check to be sure.
$time = strtotime(str_replace('/', '.',$x->Start));
I see you already have an accepted answer, but I would strongly recommend that you take a look at PHP's DateTime classes. They are extremely useful and can make seemingly complex date operations trivial.
In your particular case, I would replace:-
$time = strtotime($x->Start);
with:-
$time = \DateTime::createFromFormat('d/m/Y H:i:s a', $x->Start);
You can then format the date as you wish using the \DateTime::format() method.

PHP: Help with this date formatting

I have an application I'm building with CodeIgniter. I have records in a SQL Server DB which have datetime fields.
I'm querying these records from dates entered into a textfield in the m/d/Y. This corresponds to the date format in the db.
Unfortunately I'm in the UK! So I want to enter dates in like d/m/Y. So I need to capture this, format it into the appropriate format and then validate it.
Here's the code in using to format:
$datestring = "%m/%d/%Y";
if(isset ($_POST['from_date']) AND isset ($_POST['to_date'])){
$from = mdate($datestring, strtotime($_POST['from_date']));
$to = mdate($datestring, strtotime($_POST['to_date']));
I'm using mdate from the CI date helper but it's pretty much the same as date() I think.
If I enter the data 13/12/2010 then post the form and dump the new date it comes out as
string(10) "02/06/2011"
How'd this happen?
Can someone lend a hand? :D
Billy
The answer is that the European date format uses dashes, not slashes.
According to the manual:
Note:
Dates in the m/d/y or d-m-y formats
are disambiguated by looking at the
separator between the various
components: if the separator is a
slash (/), then the American m/d/y is
assumed; whereas if the separator is a
dash (-) or a dot (.), then the
European d-m-y format is assumed.
Using a correct format works like a charm:
// American format
//
$_POST['from_date'] = "02/06/2011";
$yankeeTimestamp = strtotime($_POST['from_date']);
// European format
//
$_POST['from_date'] = "06-02-2011";
$euroTimestamp = strtotime($_POST['from_date']);
echo date("m/d/Y", $yankeeTimestamp); // returns 02/06/2011
echo date("m/d/Y", $euroTimestamp); // returns 02/06/2011
What I would do is explode the date by '/' and make a new date with mktime:
$from = explode('/', $_POST['from_date']);
$from = mktime(0, 0, 0, $from[1], $from[0], $from[2]);
$from = mdate($datestring, $from);

Categories