Best practice to manage date and days - php

I am working on a project where I have many operations to manage.
Each operation have an end date and is composed by a certain amount of tasks.
I want to display reminders (a text displayed on the screen) if a task is not done before [end date] - X days.
All the data is stored in MySQL database and I work with PHP and HTML5.
Which datatype is (are) the best to work with date and days (to
perform calculations)?
Can I work with Date() and subtract days in a easy way?
I do not have a specific technical question, but I think sharing best way to proceed is a good thing, right?
I'm curious to know what are the best ways to proceed and open to any proposal!

I recommend to store your date in mysql at field timestamp because you can use default value CURRENT_TIMESTAMP - it very helpful,
and i think you shouldn't worry about it, there is a plenty of functions::
mysql:
select now();
+---------------------+
| now() |
+---------------------+
| 2015-04-08 12:13:18 |
+---------------------+
select now() - interval 1 day;
+------------------------+
| now() - interval 1 day |
+------------------------+
| 2015-04-07 12:13:29 |
+------------------------+
select now() - interval 7 day;
+------------------------+
| now() - interval 7 day |
+------------------------+
| 2015-04-01 12:13:38 |
+------------------------+
select now() - interval 1 month;
+--------------------------+
| now() - interval 1 month |
+--------------------------+
| 2015-03-08 12:13:58 |
+--------------------------+
php:
<?php
var_export([
date('Y-m-d H:i:s', strtotime('now')),
date('Y-m-d H:i:s', strtotime('- 1 day')),
date('Y-m-d H:i:s', strtotime('- 7 day')),
date('Y-m-d H:i:s', strtotime('- 1 month')),
]);
/*
Result:
array (
0 => '2015-04-08 15:15:42',
1 => '2015-04-07 15:15:42',
2 => '2015-04-01 15:15:42',
3 => '2015-03-08 15:15:42',
)
*/
And sometimes very helpful to create table like:
CREATE TABLE t1 (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
in result your field ts will be automatically seted and updated...

You can store dates as DATETIME in your database.
Then in PHP convert it to manageable data using strtotime() and the date() functions

The best data type to work with is the DateTime class.
In order to perform substractions using the DateTime class, you'll need to use the DateInterval class.
You'll need some time to get on your ease using those two classes but it will make formatting or date operations easier afterwoods.

Related

MySQL - saving date and time as DATETIME vs as saving date and time as String

I need to store a deadline, that consists of a date and a time (e.g 2016-05-02 19:02). I am currently using a field that has DATETIME as datatype but the problem is that its automatically saving it as 2016-05-02 19:02:00.
as a solution i was thinking to save the date in a String field.
So i am wondering if i should do that ? any performance advantages/disadvantages ?
Don't fight the database. Use the builtin types unless you really need something that they can't offer(I'd say it's unlikely, though). (And by this I mean that you should use TIME, DATE or similar for times and dates. Then you can do calculations without having to convert values, etc)
If you don't need the seconds then just keep them 00 all the time.
Whether you use DATETIME, DATE & TIME or perhaps TIMESTAMP is up to you, how you use the data. Choose the alternative that makes most sense in your current situation.
As mentioned in the other answer, you should always use built-in data types whenever possible.
In your case, stick with DATETIME and then convert it to whatever format you need in the query using the DATE_FORMAT function, like so:
mysql> SELECT * FROM `mytable`;
+----+---------------------+
| id | mydatetime |
+----+---------------------+
| 1 | 2016-06-06 14:12:00 |
+----+---------------------+
1 row in set (0.00 sec)
mysql> SELECT DATE_FORMAT(`mydatetime`,'%b %d %Y %h:%i %p') AS `mydatetime` FROM `mytable`;
+----------------------+
| mydatetime |
+----------------------+
| Jun 06 2016 02:12 PM |
+----------------------+
1 row in set (0.00 sec)
Reference:
http://www.w3schools.com/sql/func_date_format.asp

How to get difference in minutes betwen two timestamps

I want to ask how to find the time difference of two fields in minutes. eg in 'in' field filled 2014-07-12 19:00:00 , and in 'out' field filled 2014-07-12 20:30:00 , the time difference will be automatically saved in the 'duration' field
----in--------------|-------out-----------| duration
2014-07-12 19:00:00 | 0000-00-00 00:00:00 | 0
--------------------------------------------------
when i click update button it will updated like,
-------in-----------|---------out---------| duration
2014-07-12 19:00:00 | 2014-07-12 20:30:00 | 90
--------------------------------------------------
thank you
You can use the TIMESTAMPDIFF function, as below:
SELECT
TIMESTAMPDIFF(MINUTE, in, out) duration
FROM mytable;
Reference:
TIMESTAMPDIFF function on MySQL Reference Manual
Manual for TIME_TO_SEC function.
SELECT (TIME_TO_SEC(`in`)-TIME_TO_SEC(`out`))/60 AS duration FROM TABLE_NAME ;

mySQL datetime and timestamp

I want to update mysql rows where DATETIME < TIMESTAMP
DATETIME is like: "2014-06-21 17:56:00"
TIMESTAMP is like 1454546656 (which is now)
I want to update all the rows where DATETIME is in the past
What's the lightest method to deal with a huge number for rows?
Thanks.
In mysql there 2 function which are
from_unixtime() to convert the unix time to human readable date
unix_timestamp() to convert a human readable date to timestamp
So you can use one of then for the comparison
Here how it looks
mysql> select from_unixtime(1454546656);
+---------------------------+
| from_unixtime(1454546656) |
+---------------------------+
| 2016-02-04 06:14:16 |
+---------------------------+
mysql> select unix_timestamp('2014-06-21 17:56:00');
+---------------------------------------+
| unix_timestamp('2014-06-21 17:56:00') |
+---------------------------------------+
| 1403353560 |
+---------------------------------------+
mysql> select unix_timestamp('2014-06-21 17:56:00') < 1454546656;
+----------------------------------------------------+
| unix_timestamp('2014-06-21 17:56:00') < 1454546656 |
+----------------------------------------------------+
| 1 |
+----------------------------------------------------+
mysql> select from_unixtime(1454546656) > '2014-06-21 17:56:00';
+---------------------------------------------------+
| from_unixtime(1454546656) > '2014-06-21 17:56:00' |
+---------------------------------------------------+
| 1 |
+---------------------------------------------------+
So its upto you which one you want to use for the comparison.
Since you are using PHP, try using the PHP Date Function:
$ts = date("Y-m-d H:i:s", $timestamp); //Convert Unix Timestamp to MySQL Date/Time Format
UPDATE table WHERE DATETIME < '$ts';
This is the lightest method I can think of, because it is not recalculating the timestamp for each record, and furthermore, if the DateTime Field is indexed, it will go incredibly fast.

How to select a records with timestamp ranges?

I mean that if I have table like this:
id | time | name
1 | 1354382314 | test1
2 | 1374769114 | test2
3 | 1322759914 | test3
How to select a records, for example, that was created a week ago, month ago or year ago? Is it possible only with mysql functions or how can I do it in php?
I think it's also possible with mysql functions
Like,
select * from table where time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 WEEK))
select * from table where time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 YEAR))
select * from table where time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 MONTH))
Since timestamp is a number that always grows, you can simply calculate the start and end stamp of your requested range, and use
WHERE `time` >= 'startstamp' AND `time` <= 'endstamp'
To get a stamp 1 week ago, you can use php functoon strtotime("-1 week"). Similar with month etc.
If you need current stamp for anything, use time().
select id,time,name from your_table where (current_timestamp-time)>7*24*60*60;
7*24*60*60 stands for a week

PHP MYSQL - Impossible Query? - Find "currently showing"

I have a table with a kind of weird date format in a column as varchar - this is the format that the company has provided me with - the T in the middle seems to mess things up.
EVENTID | EVENT_DATE | EVENT_DURATION
1 | 2012-10-14T06:00 | 15
2 | 2012-10-14T06:15 | 11
3 | 2012-10-14T06:26 | 14
4 | 2012-10-14T06:40 | 10
ect...ect
I have php code to return the current time in the exact same format (with the weird 'T' in the middle'
$thisin = DateTime::createFromFormat('Y-m-d\TH:i', date('Y-m-d\TH:i'));
$thisin->setTimeZone(new DateTimeZone('UTC'));
$thisout= $thisin->format('Y-m-d\TH:i');
Assuming that today is the 14th and the current time is 06:21, how do i query the current row based on duration that matches "$thisout from php" and the next five rows (in the future).
Because the current time and date are returned from php as "2012-10-14T06:21" The query should output
2 | 2012-10-14T06:15 | 11 (Now SHowing)
3 | 2012-10-14T06:26 | 14
4 | 2012-10-14T06:40 | 10
ect ect
I have been scratching my head for hours, DATE_FORMAT() Doesn't seem to work, and I think it may be the T in the middle. I am aslo have to figure out how to use duration to determine if the current time applies to a specific row.
This does not work
SELECT DISTINCT EVENTID, EVENT DATE, EVENT_DURATION
FROM epg_event
WHERE DATE_FORMAT(EVENT_DATE, '%Y-%m-%dT%H:%i') >= DATE_FORMAT(NOW(), '%Y-%m-%dT%H:%i')
ORDER BY EVENT_DATE ASC LIMIT 5
Any Ideas?
You should load the date information into a Date column rather than a varchar column in the database. As previously noted this is the ISO format for dates.
Need to add in the interval.
where event_date + INTERVAL duration MINUTE >= NOW()
I'm not currently able to test it, but something like this might work:
SELECT DISTINCT EVENTID, EVENT_DATE, EVENT_DURATION
FROM epg_event
WHERE (event_date <= NOW()) AND (ADDTIME(event_date, INTERVAL event_duration MINUTE) >= NOW())
ORDER BY event_date ASC LIMIT 5
DATE_FORMAT() is meant for formatting a DATETIME field, not the other way around. And, as mentioned earlier, you event_date should be a DATETIME field and you should convert the time when you import the data to your database.

Categories