Select between dates from table - strtotime? - php

I have been trying for a while, read countless stackoverflow answers and still cant crack it!
I have a table in my db with a field called dob. This field is currently just a TEXT field (but i have since tried changing it to a DATE field and still cant get it to work).
The DOB field's data is in this format (UK dates) - 22/05/2016.
Im trying to find out the number of users who's birthdays are between two dates.
For example, anyone who was born in the last two years:
$twoyearsago=date('d/m/Y', strtotime("-2 years"));
$today = date("d/m/Y");
$sql = mysql_query("SELECT * FROM users WHERE dob >= '" . $twoyearsago . "' AND date <= '" . $today . "' ORDER by id DESC");
I also tried:
$sql = mysql_query("SELECT * FROM users WHERE dob BETWEEN '" . date('d-m-Y', strtotime($twoyearsago)) . "' AND '" . date('d-m-Y', strtotime($today)) . "'";
Hopefully you can see where me logic is and hoping you will see where im going wrong - any help would be appreciated.
Jack

With STR_TO_DATE can you convert your date
NOTE: i have changed the Column type from TIMESTAMP to DATE, because in a TIMESTAMP you can store date before 1970-01-01.
SELECT STR_TO_DATE('22/05/2016','%d/%m/%Y');
sample
MariaDB [bb]> SELECT STR_TO_DATE('22/05/2016','%d/%m/%Y');
+--------------------------------------+
| STR_TO_DATE('22/05/2016','%d/%m/%Y') |
+--------------------------------------+
| 2016-05-22 |
+--------------------------------------+
1 row in set (0.00 sec)
MariaDB [bb]>
so you can change you Table
ALTER TABLE `users`
ADD COLUMN new_dob DATE;
UPDATE `users` SET new_dob = str_to_date(dob,'%d/%m/%Y');
** Verify the dates
ALTER TABLE `users`
DROP COLUMN dob;
ALTER TABLE `users`
CHANGE COLUMN `new_dob` `dob` DATE;
** CREATE an INDEX for perfomance **
ALTER TABLE `users`
ADD KEY (`dob`);
SELECT
SELECT * from `users` where dob between '2014-01-01' AND `2015-08-01';

The problem with many local date formats is that their lexical and chronological order are different (eg, 16-11-2016 comes after 11-12-2016 lexically, but before chronologically). That's why storing dates in string fields in some regional format is in most cases a bad idea: you will get sorting issues sooner or later.
Next, when specifying dates literally for MySQL, you have to respect certain formats, as explained in the documentation
Putting that into practice, the range variables should look something like this:
$today = date("Y-m-d");
$twoyearsago=date("Y-m-d", strtotime("-2 years"));
Then we use a built-in function str_to_date to convert the string column into a date that can be compared correctly:
SELECT * FROM users WHERE
STR_TO_DATE(dob, '%d/%m/%Y') between '$twoyearsago' and '$today'
This will work, but in the long run you're much better off converting that dob column into a real date format (as #BerndBuffen shows) as it's clearer, easier to internationalize and a lot better performing.
Sidenote: you are still using the long-deprecated mysql_ extension. You should really switch to either mysqli_ or PDO.

You need to build your query by using actual date values, not string. So you need format YYYY-MM-DD in query - both side of the comparison.
Try following.
$twoyearsago=date('Y-m-d', strtotime("-2 years"));
$today = date("Y-m-d");
$sql = mysql_query("SELECT * FROM users WHERE STR_TO_DATE(dob, '%d/%m/%Y') >= '" . $twoyearsago . "' AND STR_TO_DATE(dob, '%d/%m/%Y') <= '" . $today . "' ORDER by id DESC");
STR_TO_DATE(dob, '%d/%m/%Y') makes sure your d/m/Y saved dob string value to be converted to date in the query that MySQL can understand and compare with the given YYYY-MM-DD values.
Actually the proper way is creating a date field and transferring dob string values as date to this new field by using the same function unless you will always get the date values as string into the dob field.

Another method is to use DateTime and format the date before doing your query.
$begin = '10/02/2014';
$emd = '10/02/2015';
$beginDate = DateTime::createFromFormat('d/m/Y', $begin);
$emdDate = DateTime::createFromFormat('d/m/Y', $emd);
$stmt = "
SELECT
...
FROM users
WHERE birthday >= '".$beginDate->format('Y-m-d')."'
AND birthday <= '".$endDate->format('Y-m-d')."'
";

Related

How to check if date between two date in php and sql?

I sent parameter date to check if that date between two date from database.
example date string parameter that i sent to API is "09/01/2020" which format is mm/dd/YYYY
this format also same for date string in database table column.
Now in database, I put date_start as "08/21/2020" and date_end as "09/05/2020"
My code is :
$date = $data["date"];
to get date string parameter that I sent to API.
Example table name is promo,
my code is :
$sql = "SELECT * FROM promo WHERE STR_TO_DATE('" . $date . "', '%M%M/%d%d/%Y%Y%Y%Y')
between date_start and date_end";
But I did not get it.
How to correct that to get it?
Edited my latest code is like this but still did not get it:
$date = $data["date"];
$date = DateTime::createFromFormat('m/d/Y', $date);
$date = $date->format('m/d/Y');
$sql = "SELECT * FROM promo WHERE $date BETWEEN STR_TO_DATE(date_start, '%m/%d/%Y') AND
STR_TO_DATE(date_end, '%m/%d/%Y')";
You said:
Now in database, I put date_start as "08/21/2020" and date_end as "09/05/2020"
This is not best practice, and you should always store your dates as a proper date or datetime type in MySQL. Had you done this, you would only need a range comparison in your query:
SELECT *
FROM promo
WHERE ? BETWEEN date_start and date_end;
If you must stick with your current design, then you would actually have to use STR_TO_DATE on the start and end dates:
SELECT *
FROM promo
WHERE ? BETWEEN STR_TO_DATE(date_start, '%m/%d/%Y') AND
STR_TO_DATE(date_end, '%m/%d/%Y');
To the ? placeholder above, you should bind either a valid PHP date, or a valid MySQL date literal string. But again, I strongly recommend fixing the design problem.

Adding days to a Date (retrieved from MySQL database) in PHP

I am trying to do, what I assume is, an easy task of adding days to a date.
I have a date stored in a MySQL table, in a column called meta_date, with the type of DATE (A date, supported range is 1000-01-01 to 9999-12-31)
I retrieve this date from the database as follows:
$thisId = 1;
$dateQuery = mysqli_query($connection, "SELECT * FROM `sometable` WHERE `id` = '$thisId'");
$fetchDate = mysqli_fetch_assoc($dateQuery);
$theDate = $fetchDate['meta_date'];
Now I add a number of days to this date.
$newDate = date("Y-m-d", strtotime($theDate . " + 7 days"));
Next I put it back inside the database with an UPDATE query.
$editDate = mysqli_query($connection, "UPDATE `sometable` SET `meta_date` = '$newDate' WHERE `id` = '$thisId'");
However the date always returns as 0000-00-00 after the update.
Am I missing something here to do with the way the date is handled in PHP?
edit: The data I first retrieve from the database (into $theDate) is "2016-11-30".
You can use Mysql's built in function DATE_ADD()
Syntext
DATE_ADD(date,INTERVAL expr type) Where date is a valid date expression and expr is the number of interval you want to add.
For your case
UPDATE sometable
SET `meta_date` = DATE_ADD(`meta_date` , INTERVAL 7 DAY)
WHERE `id` = '$thisId';

Retrieve only today records from MySQL database using PHP

In my database I stored date and time as a TIMESTAMP values. I want to retrive only today data from the database. This is code that I tried
$today = date("Y-m-d") . '00:00:00';
$last = date("Y-m-d") . '23:59:59';
$sql = "SELECT id, name, name2,some,some,submittimestamp,some FROM recs where submittimestamp Between $today AND $last";
$result = $conn->query($sql);
But I only get the 0 results message using this. There is more than 100 rows added today.
How can I solve this ? I cant change the database now. only way to solve this is change the PHP script
Do I need to convert PHP datetime to MYSQL timestamp ?
This is my sample database entry time-stamp value
2014-10-02 15:47:01
I only want to retrieve data for one day. time is not required !!
SELECT id, name, name2, submittimestamp
FROM recs WHERE submittimestamp > DATE_SUB(CURDATE(), INTERVAL 1 DAY);
Also you may try this, as DATE() ignores time part
SELECT id, name, name2, submittimestamp
FROM recs WHERE DATE(submittimestamp) = CURDATE();

php Comparing date if date format in database is like this (02/02/2014)

I wants to fetch some data from my database table. my mysql query is bellow.
$sql = 'SELECT *
FROM advertisments
WHERE ad_type = "Jobs"
AND last_date <= "' . $todays_date .'" ';
let me know how it works if in table last_date format is like this (day/month/year 01/01/2014)
and $today_date = 02/02/2014 . in my case it is not working. let me know how can i compare this situation.
If that's not working I'd hazard a guess that your last_date column is not a date/time type in your database and so the database software is probably just performing a string comparison.
Set the last_date type to DATE and then last_date <= "' . $todays_date .'" '; should work just fine if $todays_date is in the correct format.
Edit: I believe MySQL date uses the format Y-m-d
Just by googling about how to convert time into datetime and then compare datetime instead of only time.

PHP Matching the output of 2 codes

I need to match the result format of 2 code:
I need to get the output/format of this:
$event_day = $year.'-'.$month.'-'.$list_day; // $event_day
match this:
DATE_FORMAT(date,'%Y-%m-%d')
Full code:
$query = "
SELECT title, DATE_FORMAT(date,'%Y-%m-%d') AS date
FROM table
WHERE user_id = '$session_user_id'
AND date BETWEEN '$year-$month-1' AND '" . date("Y-m-t", strtotime("$year-$month-1")) . "'
AND active = 1";
My problem is that $event_day is only displaying events for: October, November and December.
I had a similar problem with this code below:
$query = "
SELECT title, DATE_FORMAT(date,'%Y-%m-%d') AS date
FROM table
WHERE user_id = '$session_user_id'
AND date LIKE '$year-$month%'
AND active = 1";
and it was fixed with this code:
$query = "
SELECT title, DATE_FORMAT(date,'%Y-%m-%d') AS date
FROM table
WHERE user_id = '$session_user_id'
AND date BETWEEN '$year-$month-1' AND '" . date("Y-m-t", strtotime("$year-$month-1")) . "'
AND active = 1";
Anyone know how I could sort this out?
If you are simply trying to match dates in a SQL query, which is what you look like you're after, you can just pass the date as a string with a # on each end. This will tell SQL to parse the string as a date and the format you give it in is not really important. The exception to this is it can get confused between US/EU date formats like dd/mm/yyyy vs mm/dd/yyyy.
$query = "SELECT title, DATE_FORMAT(myDate,'%Y-%m-%d') AS formattedDate
FROM table
WHERE user_id = '$session_user_id'
AND (myDate BETWEEN #$year-$month-1# AND #$year-$month-1#)
AND active = 1";
This format should work but your query is select records that fall between the same date so you'll only get records that are actually on that date. You might as well just use WHERE date = #$year-$month-1#
edit: this assumes your date field datatype is correctly set up in the database as a date/time.
edit2: "date" is often a reserved word in databases and shouldn't really be used for field names and variables. See edited code above.
In addition I would suggest using php to format the date using the date() function rather than format it in the query. This allows more flexibility to actually use the date in your script.

Categories