Search between dates (date as VARCHAR) - php

I have several dates stored as varchar in the following format: 01-01-2012
I want to search between dates, but sadly it isn't working as I expected. I looked for other threads which have the same question (kinda), but the answers provided there didn't work for me.
Here is my code:
$fromday = $_POST['fromday'];
$frommonth = $_POST['frommonth'];
$fromyear = $_POST['fromyear'];
$tillday = $_POST['tillday'];
$tillmonth = $_POST['tillmonth'];
$tillyear = $_POST['tillyear'];
$vanaf = "$fromday-$frommonth-$fromyear";
$tot = "$tillday-$tillmonth-$tillyear";
// zoeken
$sel = "SELECT * FROM bestelling WHERE verzenddatum >= '$vanaf' AND verzenddatum <= '$tot'";
$dosel = mysql_query($sel) or die(mysql_error());
while($row = mysql_fetch_assoc($dosel))
{
$datum = $row['verzenddatum'];
echo $datum;
}
Please let me know what I'm doing wrong!

It is not returning any rows because the query is not doing the comparison on valid DATE or DATETIME fields. You should be storing the dates as a DATE type, but what you could do is this:
// Switch the order of date elements:
$vanaf = mysql_real_escape_string("$fromyear-$frommonth-$fromday");
$tot = mysql_real_escape_string("$tillyear-$tillmonth-$tillday");
$sel = "SELECT * FROM bestelling WHERE STR_TO_DATE(verzenddatum, '%d-%m-%Y') BETWEEN '$vanaf' AND 'tot'";
The mysql_real_escape_string() function simply reduces the risk of SQL injection, which is what your original code was vulnerable to.
The MySQL function STR_TO_DATE() converts a string to a valid MySQLDATE type. %d-%m-%Y is the format you have in your varchar string currently, but STR_TO_DATE converts it to '%Y-%m-%d' which MySQL can then use to make range comparisons.
Also, I'm using the BETWEEN syntax in the SQL as it is the same thing as val >= val1 AND val <= val2. It's just clearer and simpler: val BETWEEN val1 AND val2.

You need to store the dates as either DATE field types or DATETIME field types. Migrate your database with a script (shouldn't be too hard on a small DB: Backup your table, convert all of your dates to the proper format, change the schema and then re-insert your data. Restore your backup if it explodes.) After fixing this, everything will work as expected.

I would strongly recommend that you fix this by converting the fields to proper DATE fields now and take the pain, rather than waiting until the inevitable performance problems that this approach will incur arise. If you cannot, try this:
$fromday = $_POST['fromday'];
$frommonth = $_POST['frommonth'];
$fromyear = $_POST['fromyear'];
$tillday = $_POST['tillday'];
$tillmonth = $_POST['tillmonth'];
$tillyear = $_POST['tillyear'];
$sel = "SELECT * FROM bestelling WHERE SUBSTRING(verzenddatum, 7, 4) BETWEEN '$fromyear' AND '$tillyear' AND SUBSTRING(verzenddatum, 4, 2) BETWEEN '$frommonth' AND '$tillmonth' AND SUBSTRING(verzenddatum, 1, 2) BETWEEN '$fromday' AND '$tillday';"
(The hope here is that if a record's date lies outside the "from year" and "to year", the MySQL query optimiser will notice this and bail out early)

MySQL's standard date format is 'year-month-day' try this $vanaf = "$fromyear-$frommonth-$fromday"; and do the same for $tot. Try that and see if it works.

Some theory:
$startdate = sprinf('%04d-%02d-%02d', $year, $month, $day);
$enddate = sprinf('%04d-%02d-%02d', $year, $month, $day);
$query = "SELECT * FROM orders WHERE date BETWEEN '{$startdate}' AND '{$enddate}'";
My tipp: Invest some time in PDO and prepared statements. Dont use mysql_ functions anymore.

Since you are using PHP, you can set your data type in MySQL to INT (Integer) and use UNIX Timestamps for your dates. This is a good way to search for greater than and less than values.
You can use something like:
$fromday = strtotime($_POST['fromday']);

Change Only Mysql query it's Working.
select * from Your_table_name
where STR_TO_DATE( "your_date_field" , '%d/%m/%Y' )
BETWEEN STR_TO_DATE("your_first_date", '%d/%m/%Y')
AND STR_TO_DATE("your_second_date", '%d/%m/%Y')

Related

Extracting only date from datetime field (mysql) and assigning it to php variable

I am unable to assign only date to a php variable from datetime field of a MySQL table. I am using PHP 4, I know how to do it in PHP 5.
Can someone help as to what is missing from the below php code.
$dc = mysql_query("SELECT * FROM INVHDR WHERE Invdate BETWEEN '2011-04-01' AND '2012-03-31'");
while ($dc2 = mysql_fetch_assoc($dc)) {
$invno = $dc2['Invno']; // Here Invno is a datetime field type
$invdat3 = $dc2['Invdate'];
$date_array = explode("-", $invdat3);
$invdat = sprintf('%02d/%02d/%4d', $date_array[2], $date_array[1], $date_array[0]);
}
If you just want to display the date portion, you could use the DateTime class:
echo DateTime::createFromFormat("Y-m-d H:i:s", "2012-12-24 12:13:14")->format("d/m/Y");
// 24/12/2012
//Edited for double echo typo.
There is a link I find extremely useful when it comes to date manipulations:
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
one can easily find the solution there:
SELECT *, DATE(Invdate) as Inv_date ...
Do it directly in MySQL:
select DATE_FORMAT('2012-12-24 12:13:14', '%Y/%m/%d')
So your query will look like this:
SELECT DATE_FORMAT(Invdate, '%Y/%m/%d') FROM INVHDR WHERE Invdate BETWEEN '$startdat' AND '$enddat'

php mysql getting count WHERE BETWEEN AND

Hey i have a little problem when i'm trying to get count of rows from table, where date is BETWEEN 2012-09-01 AND 2012-09-32...
Could you please tell me where's the problem?
$month = date(m);
$year = date(Y);
$day_start = '01';
$day_end = '32';
$from = $year.'-'.$month.'-'.$day_start;
$till = $year.'-'.$month.'-'.$day_end;
$result1 = $mysqli->query("SELECT COUNT(id) FROM `dreams` WHERE dream_state='dream' AND date BETWEEN $from AND $till");
$row1 = $result1->fetch_row();
$this_dream = $row1[0];
i've tryed to convert the string to time and from time to date like this:
$from = strtotime($from);
$from = date("Y-m-d",$from);
$till = strtotime($till);
$till = date("Y-m-d",$till);
but still doesn't work, so any ideas?
Thank you.
First of all, your date column needs to be some kind of date datatype, like DATE or TIMESTAMP.
Second, you need to use valid dates for comparison. September 32 is no good. When MySQL tries to interpret that date it gets NULL. All comparisons between real values and NULLs come up false. So, you get an empty result set.
Third, BETWEEN is terrible for date comparison ; it often fouls up the end -- the last day -- of the range.
I suggest you use a query like this. Notice that the second date comparison to is the day after the end of the range you want.
$month = date(m);
$year = date(Y);
$day_start = '01';
$from = $year.'-'.$month.'-'.$day_start;
$result1 = $mysqli->query("SELECT COUNT(id)
FROM `dreams`
WHERE dream_state='dream'
AND date >= '$from'
AND date < '$from' + INTERVAL 1 MONTH");
$row1 = $result1->fetch_row();
$this_dream = $row1[0];
You include dashes in your dates but don't quote them as strings in the SQL. There are no date literals in SQL, so you have to represent dates as strings upon entry. Simply enclose them in single quotes to represent SQL value strings.
$result1 = $mysqli->query("SELECT COUNT(id) FROM `dreams` WHERE dream_state='dream'
AND date BETWEEN '$from' AND '$till'");
You also have an invalid date, as no month has 32 days. Computing the last day of each month seems a bit of an overkill here, so you're probably better off describing the first day of the next month, and using < to exclude it from the range.
A previous version of this answer suggested using numbers to describe dates instead of strings. While this works, it might be quite bad for performance, as #ypercube pointed out in a comment below.

between operator for timestamps in mysql query

I have a form to pick up dates from calender. That form will pass start date and end date. My database table stores date in time-stamp format. I have to create a query to pick records from database table between start date and end date. How can I make a query? I have tried the code below, but which is not working.
if(isset($_POST['filter']))
{
$sid=$_POST['sid'];
$start= date("dMY",strtotime($_POST['start']));
$end= date("dMY",strtotime($_POST['end']));
$res=$db->fetchAll("SELECT * FROM `logfile` WHERE `site_id`=".$sid." AND (date('dMY',`timestamp`) BETWEEN $start AND $end)");
}
Any thoughts?
Thanks.
You're forcing PHP and MySQL to do a lot of useless date/time string<->native conversions for no reason.
Why not simply have:
$start = strtotime($_POST['start']);
SELECT ... WHERE `timestamp` BETWEEN FROM_UNIXTIME($start) AND ...
if $_POST['start'] and $_POST['end'] are already in timestamp format, just don't change them. In other case just convert the string in timestamp:
$start = strtotime($_POST['start']); // where $_POST['start'] might be 2012/08/07
$end = strtotime($_POST['end']);
$res=$db->fetchAll("SELECT * FROM logfile WHERE site_id=".$sid." AND date BETWEEN $start AND $end");
As #Matei Mihai said you don't need to convert $_POST['start'] and $_POST['end'] to timestamp format and you must enclose date columns in quotes.
Also you need to convert date in MySQL compatible format like '2012-08-01'.
"SELECT *
FROM `logfile`
WHERE `site_id`=".$sid." AND
(date('dMY',`timestamp`) BETWEEN '$start' AND '$end')");

PHP - Formatting HH:MM:SS to 12hr HH:MM:a string

I'm hoping this will be a piece of pie for someone! String output is currently 12:00am for everything.
The following code from MySQL with format HH:MM:SS (hours_open, hours_closed)
$get_hours_sql = "SELECT * FROM client_hours ORDER BY day";
$get_hours_res = mysqli_query($dbConnect, $get_hours_sql) or die(mysqli_error($dbConnect));
// Establish the output variable
$hoursList = '<div class="right_bar">';
while ($productList = mysqli_fetch_array($get_hours_res)) {
$id_hours = $productList['id_hours'];
$day = $productList['product_name'];
$open = $productList['hours_open'];
$close = $productList['hours_close'];
$hoursList .= ''.date("g:ia", $open).' - '.date("g:ia", $close).'<br/>';
}
$hoursList .= '</div>';
echo $hoursList;
Output is currently
12:00am - 12:00am
looped.
I want to get the output to
11:00am - 11:00pm
which would represent the database entries.
Thanks!
I always find PHP <-> MySql date handling fiddly (got better with 5.3 though).
My guess is that the mysql query returns the date as a string and date() is expecting a time stamp.
Often, I just get mysql to format the date as a string for me and return it as an additional field, like so:
$get_hours_sql = "SELECT *,date_format(hours_open,'%h:%i %p') as hours_open_formatted, date_format(hours_close,'%h:%i %p') as hours_close_formatted FROM client_hours ORDER BY day";
then just use the formatted fields:
$hoursList .= ''.$productList['hours_open_formatted'].' - '.$productList['hours_close_formatted'].'<br/>';
Data accepts as it's second parameter a Unix timestamp, so what you're trying to do simply won't work. You could use either mysql's TIME_TO_SEC function, or php's mktime to convert the time string to a Unix timestamp.
Example:
$openHours = explode(':',$productList['hours_open']);
$timestamp = mktime($openHours[0],$openHours[1]);
$yourDate = date("g:ia",$timestamp);
Edit: I think you should try Ben's answer, I think it's a better solution than mine.

PHP/MySQL: Convert from YYYY-MM-DD to DD Month, YYYY?

I have in a MySQL table a DATE column that represents the date in this format: YYYY-MM-DD.
I wanto to retrieve the date from the database using PHP but display it like this: DD Month, YYYY.
From '2009-04-13' to '13 April, 2009' for example.
Witch is the best way to do it?? ( I know how to get the date from the DB. I only need to know how to convert it)
I also need to display the month names in Spanish. There is a way to do it without translating each month using strplc or something like that??
I'm new to programming, please be detailed.
Thanks!!!
Refer to DATE_FORMAT() function in MySQL. I guess that's the best way for you to do it.
Also, you can make this:
Fetch your date from DB
Use strtotime in PHP, to convert to unix time
Then format the time using date.
By using date() you'll be able to get months names in Spanish when you set your locale in PHP with setlocale.
You could also skip the strtotime() part by using UNIX_TIMESTAMP(date) in your MySql select. But remember that this is a MySQL specific function and may not be be portable in the future.
Execute following MySQL queries:
SET lc_time_names = 'es_ES';
SELECT DATE_FORMAT(t.date,'%e de %M, %Y') FROM your_table t ...
With MySQLi it'll be:
$mysqli->query("SET lc_time_names = 'es_ES'");
$stmt = $mysqli->prepare("SELECT DATE_FORMAT(t.date,'%e de %M, %Y') FROM your_table t ...where id = ?");
...
Another option not yet mentioned:
SQL:
SELECT UNIX_TIMESTAMP(date) FROM table
PHP:
print date('your format', $timestamp_from_the_db);
Personally, I like to use integer data types in MySQL for date storage in the UNIX timestamp format. I leave all the processing of that integer up to PHP. Keeping tables and queries as simple as possible has always served me well. Predominantly, in the code I write, dates have some sort of calculation done to them. This is all done on the PHP side and always in the UNIX timestamp format. Storing or retrieving the dates in anything other than the UNIX timestamp format just means another step for errors to creep in and makes the query less modular. How a date is formatted is best left up until the last minute before it's displayed. It's just my opinion, but unless there are extreme circumstances where you can't process the DB value after extraction, a date shouldn't be formatted SQL-side.
A simplified example:
<?php
$date = now();
$dueDate = $date + 60*60*24*7; // One week from now
$sqlInsert = "INSERT INTO reports SET `dueDate` = $date";
$resInsert = mysql_query( $sqlInsert );
$sqlSelect = "SELECT `dueDate` FROM reports";
$resSelect = mysql_query( $sqlSelect );
$rowSelect = mysql_fetch_array( $resSelect );
$DB_dueDate = $rowSelect['dueDate'];
$daysUntilDue = ( $DB_dueDate - now() ) / 60*60*24;
$formattedDueDate = date( "j F, Y", $DB_dueDate );
?>
The report is due on <?=$formattedDueDate?>. That is <?=$daysUntilDue?> from now.
Simplest way is to use the strtotime() function to normalize the input to UNIX timestamp.
Then use the date() function to output the date in any format you wish. Note that you need to pass the UNIX timestamp as the second argument to date().
This will help you to convert as you want:
$dob ='2009-04-13';
echo date('d M Y', strtotime($dob));
$origDate = "2018-04-20";
$newDate = date("d-m-Y", strtotime($origDate));
echo $newDate;

Categories