how to solve date matching in php mysql website? - php

So here is the thing I get dates from users from select tags like this:
<select>
<?php
for($i=date('m'); $i>=0; $i--){
echo "<option>".$i."</option>";
}
?>
</select>
Now what this does is give 05 as first option 4,3,2,1 as next options, I want 04,03,02,01 as all options.
How can I do that?
Also I am running a sql query that deletes rows by matching dates.
So the date selected by user comes as 2013-5-18(without zero) but the date in database is 2013-05-18 (with zero), so the dates don't match and the query is unable to delete the row.
Also can I change the way date is stored in a database?
I store date as 2013-5-18(without zero) and it automatically gets stores as 2013-05-18 (with zero).
Any other thing that will just help me to match the dates so I can run the delete query?

Try:
echo "< option>".sprintf("%02d", $i)."< /option>";
sprintf will format your number to have a preceding 0 when required.
What you're seeing is date('m') properly returning the value 05 for the first month. However when you add 1 to it ($i++) it's being cast to an integer, so the next value is 6. I might presume your actual code uses $i--, as this presently looks a lot like an infinite loop.
You might also consider handling the formatting when you build the query, rather than on form presentation. $month = sprintf("%02d", $_POST['month']); rather than relying on the client to pass it forward nicely.

Related

Inserting actual hours (not time) to MySQL

I am trying to insert actual hours not the time itself to MySQL database through form fields. So for example
$time1 = '00:00';
$time2 = '27:20';
$time3 = '00:45';
So I can retrieve the different rows and can calculate on the fly whenever require. Either through search query or even in other area of the system.
When I have tried to do addition of above three times, it is not giving the result the way I am looking for
$total = strtotime($time1) + strtotime($time2) + strtotime($time3);
echo date('H:i:s', $total);
The result
14:16:44
While it should be something like
28:05:00
I have used TIME DATATYPE in MySQL table. I may use as a TEXT but I am also concern about the error happen in user input. Where I do not have to force the user to insert the any particular format but they can either insert as below way
27.20
27:20
or
1.5
1:30
My main concern is to calculate the time, the user input can be on second priority but it would be great if can implement.
So is there anyway, idea or hint to achieve this?
date() expects the timestamp in UNIX format, i.e. seconds since January 1 1970 00:00:00 UTC (which is also the value provided by strtotime)
You're passing it the result of adding a series of amounts of time since 1 January 1970 instead of just adding up hours, so (as far as date is concerned) you're generating a random date and time, and printing only the time (try printing the date of $total and see what you get).
Since your time is stored in the database, one possibility is to let MySQL handle the time calculations itself, e.g.:
SELECT ADDTIME('00:00',ADDTIME('27:20','00:45'))
will result in "28:05:00". You can have your database fields as TIME and operate on them directly through SQL, and do the user input conversions into acceptable TIME values in PHP.
If you're only interested in the hours and minutes, why don't you just store the value as an in integer? Just multiply the hours by 60.
You can handle the conversion in PHP.
Alternatively, you can also easily use two (very small) int fields for this.

PHP Foreach Loop Query

I've been tinkering with PHP lately (self-taught, no formal training), trying to understand how to grab data from a database and display the data somewhere. So far I have learned quite a bit, but now I am stumped.
I have a list of about 200 users in my local database in a table called site_members. The table has three fields: id, name, birth_date. Via PHP, I want to display all the users on a webpage, and have something like "Birthday soon!" be mentioned right after their name. Something like this:
John Smith (Birthday soon!)
I haven't written the code to do this, because I usually write pseudocode first before actually diving into the coding part. Here's the pseudocode:
Get the current date and time and convert it to Unix timestamp
Start foreach loop and go through list of users
Query the database table, get the birthdate of a user by their id, and store it in a variable named bdate.
Convert bdate to Unix timestamp
Subtract the current date from bdate, convert it into days remaining, and store it in a variable called remaining_days.
If the user's bdate is within 15 days (remaining_days is less than 15)
Display their name, followed by (Birthday soon!)
otherwise
Just display their name only
End if
End foreach loop
Here's my problem: With the above pseudocode once translated into actual code, there would be a database query made every time in that foreach loop. Some of the tutorials I consulted mentioned I should avoid that for efficiency reasons, and it makes sense. I ran Google searches to find something similar, but that didn't do much. I do not want anyone to write any actual code for me. I just want a better solution to the querying.
Thanks in advance!
I think your concept for the pseudo code is right, and you're understanding of doing multiple database queries is also right, you just tangled the two into giving you a wrong idea.
If you construct your select statement properly (that's basically what you'd be using to access the database), you actually pull the information for everyone out of the database and store it once in an array (or some other form of object). You can then start your foreach loop using the array as your value and perform the rest of your checks that way.
$date = date("m.d.y");
$people = ** insert your commands to grab the info from the DB **
foreach($people as $person) {
// do your comparison checks and echo's etc in here
}
Does this make sense?
There can be two solutions to your problem:-
1:
Instead of making query for every user, first get the data for all the users.
Traverse the data using foreach loop php
Do the processing and display the results.
2:
Store the user date_of_birth in proper mysql date datatype
Change your mysql query to use date function to get all the users who match your date difference criteria and just display those users.
It seems you failed to read up properly on the relationship between SQL and PHP. If you actually posted code, then you could have been easily unstumped because there are many ways to do the simple task from legacy tutorials to current PDO or even MVC within in 5mins or less.
I'm not going to write the code but you need to change HOW you think in your "pseudo code".
The problem with your pseudo code is because you believe that the DB is not smart and you are doing it as if it was only for storage.
The correct pattern for PHP is the following:
1) use the Date function to retrieve current day + 15. Get month and
day only.
2) you make a SQL query that retrieve all users who's
birth_date field's month and day are GREATER THAN (or equal) to
TODAY and who are less than or equal to today + 15 (day and month
only)
3) execute the query.
4) with the returned data set (if any)
you can choose two path depending situation and design
a) you can loop it with a simple FETCH which fetch each row retrieve
and display name and extra message.
or
b) iterates through the result set and store the display message
into a variable and then finally display it once the iteration is
done.
(option b is prefered because its more flexible since you can use this technique to out into a file instead of an echo)
THIS pseudo-code ensures that you are only retrieve the correct data set with the aid of the SQL system (or storage system).
In terms of overall process, aashnisshah is absolutely correct. First, you should retrieve all the records you need from your database then loop through each row to do your data comparisons and finally close the loop.
As for finding out if their birthday is close and if you want MySQL to do the hard work, you can build your query like that in PHP:
$query = "SELECT *, DATEDIFF(DATE_FORMAT(dob, '" . date('Y') . "-%m-%d'), CURDATE()) AS days_to_dob FROM Members";
The idea is to fetch an extra column called 'days_to_dob' containing the amount of days until that person's date of birth. Note that it will be negative if that date has passed for this year. With that extra column you can easily evaluate whether their dob is within 15 days.
If you don't want any php code, then here is my pseudocode:
Get date and time -> UTC stamp and store in $time_current
Get all from site_members and store in $data
for each entry in $data, store in $record
get birth_date from $record and convert to utc stamp and store in $birthday
print name from $record
if $birthday is close to $time_current then print "Birthday soon" end if
print new line
end for
That performs only one request to your database.

PHP and MySQL - display contnet of column between certain numerical values

I'm new to MySQL and PHP but was wondering if someone could help me with a little project I'm doing for my boss.
I have a SQL database (MyDB) and a table in there (mytable) with two columns - the first column (index) is an auto-incrementing integer from 1-10, the second column (date) has different dates and timestamps in the format of Year-month-day time 2013-04-12 1326
I'm trying to create a simple PHP page that first gets the current date (easy enough) then looks at the table and shows the number of rows that fall within yesterday's date. For example, if I have 3 rows with 2013-04-11 XXXX and 2 rows with 2013-04-12 XXXX (and today is the 12th April 2013) the page will display 3. (The time is not important but we can't remove it from the table as it's auto created by one of the other staff's programs and he refuses to change it).
So far I've got my php page, done a connection to the DB and defined two variables:
$startdate = date('Y'."-".'n'."-".'d'." "."0000");
$enddate = date('Y'."-".'n'."-".'d'." "."2359");
As the timestamp doesn't matter I've gone for the min/max possible on the variables. I realise this will only give the current date, trying to work out how to get it to display the previous day as the date in the variable.
Now I'm trying to create a sql query that will count the number of rows where the date field falls within the startdate and enddate variables (-1 day) but not too sure where to start or how this would look. I then need to output this as a variable in PHP so I can echo it later in the page.
Anyone able to point me in the right direction? Hope any of this makes sense.
You could write a query with no params to do this (if its always just yesterday).
SELECT * FROM <table>
WHERE DATE_FORMAT(<date column>,'%j-%Y') = DATE_FORMAT(DATE_SUB(now(),INTERVAL 1 DAY), '%j-%Y');
Date functions in the where clause might not be super awesome performance wise

how to update the mysql database in php

$query="update attendance
SET
`day1`='$day1', `day2`='$day2', `day3`='$day3', `day4`='$day4',
`day5`='$day5', `day6`='$day6', `day7`='$day7', `day8`='$day8',
`day9`='$day9', `day10`='$day10', `day11`='$day11', `day12`='$day12',
`day13`='$day13', `day14`='$day14', `day15`='$day15', `day16`='$day16',
`day17`='$day17', `day18`='$day18', `day19`='$day19', `day20`='$day20',
`day21`='$day21', `day22`='$day22', `day23`='$day23', `day24`='$day24',
`day25`='$day25', `day26`='$day26', `day27`='$day27', `day28`='$day28',
`day29`='$day29', `day30`='$day30', `day31`='$day31', `accident`='$a1',
`disiplinary`='$d1', `family_death`='$fd1', `family_illness`='$fi1',
`holiday`='$h1', `illness`='$i1', `jury_duty`='$j1', `leave`='$l1',
`layoff`='$lo1', `personal`='$p1', `tardy`='$t1', `vacation`='$v1'
WHERE `month`='January'";
$result=mysql_query($query);
Here the day1 value updated (value as 1), next to update the value day2 is 1,
in that time the day2 value is updated(1), but day1 value changed to zero.
What i do?
The way you phrased your query, all the variables like $day1 have to be set inside PHP. If they are not, then an empty string gets pasted into the request, which in turn gets converted to zeros by the MySQL server.
So if you only want to modify day2, then do just that:
UPDATE attendance SET day2 = ? WHERE month = 'January'
That said, there are a number of ways how you could improve your current approach.
You should not use mysql_query as it is deprecated.
You should not directly include variables into the query, as this opens the door to both bugs and SQL injection vulnerabilities. Use placeholders like ? instead, and provide the actual values when executing this query.
Having one column for every day looks like a pretty bad database schema. Instead have a single table with one row for each day. You can compute monthly overviews from that for your output, but in general such a request will be far easier to handle on the DB level. If you want some columns per month, you could have those in an extra table.
You probably should use the DATE type to describe each day, along the lines just described. If you really have to have a table with one row per month, then you might still use a DATE to describe it, using the first day of the month to identify the whole month. This will allow you to easily use date and time functions on that column. If you want separate year and month columns, I guess I'd still identify the month by number, not name.

Best method to input and validate custom datetime in PHP form

This is a double question in terms of front end usability and PHP DATE_TIME validation.
I am working on a site for a client who would like to add the date he finished a project (so the projects can be listed in that order). He will be the only one using the admin interface, so I would like it to be as simple as possible.
I am storing the dates as DATE_TIME in a SQLite db.
I would like to require the client enter at least the year and month, with the option to add day, hour, minute, second to the DATE_TIME. If these are not set they will default to the smallest number.
I thought the best way and easiest to do this was making a single input form taking the input(left) and making the result(right). Making him use xxxx/xx/xx/xx/xx/xx as the format.
2009/08 = 2009-08-01 00:00:01
2009/08/01 = 2009-08-01 00:00:01
2009/08/01/05 = 2009-08-01 05:00:01
(adding one second as default otherwise it will be the day before)
I tried first by exploding the input into an array and validating each date section with regex. it got messy real fast and I can't figure out how to validate the proper ranges, say, /[1980-2009]/ or /[01-12]/ (that doesn't work like I expected). Also /[(0-9){2}]/ isn't going to work for the month obviously.
Another option is making each date section a separate select field. Making each field after month optional. But that gets messy in the html output, also given that each month doesn't have 31 days, I would need some javascript to change the day field depending on what month is selected. That's too much. It also seems a lot easier and faster to use a single field.
What do you guys suggest is the best way to input and validate custom datetimes?
I would reccomend calling strtotime() on the date, that way he can enter a variety of date formats, including month/year, day/month/year, day/month/year hours:minutes, and year-month-day hours:minutes
If strtotime can't determine what the date is, it returns false (or -1 in older versions of PHP, check your manual). SO your general code would be:
Run input through stripslashes (if needed) and strtotime
Check if value is === false. If so, display error
Otherwise, format the time as yor database expects is using date()

Categories