This is a two part problem which should be trivial but date and time handling in PHP seems to be anything but and everything I've tried so far has either given incorrect results or crashed my program
I'm trying to replicate the following two SQL Server commands in PHP
Count the days since the start of the millennium
select (cast (DATEDIFF(day,'2000-01-01',getdate()) as int)
Count the number of seconds since midnight
datediff(second,convert(date,getdate()),getdate())
I've tried all combinations of date_diff, getdate, strotime and more but nothing seems to give me a properly ISO formatted datetime or a workable method of calculating days and seconds elapsed.
I'm using PHP7 so should have all built-in functions up to date.
What am I missing?
edit: sample input data.
today's date in format '2020-11-22 16:57:10.112'
a given date in format '2000-01-01 00:00:00.000'
expected output data : 7631 days
today's date in format '2020-11-22 16:57:10.112'
previous midnight in format '2020-11-22 00:00:00.000'
expected output data : 61215 seconds
It's rather easy to do if you know your way around DateTime:
function daysSinceStartOfMillennium(DateTimeImmutable $date): int
{
$millenniumStart = new DateTimeImmutable('2000-01-01');
return $date->diff($millenniumStart)->days;
}
function secondsSinceMidnightOfDate(DateTimeImmutable $date): int
{
$midnightToday = new DateTimeImmutable('today');
$diff = $date->diff($midnightToday);
return $diff->s // seconds
+ $diff->i * 60 // minutes to seconds
+ $diff->h * 60 * 60 // hours to seconds
;
}
You could also modify the functions to take date strings as arguments and create a DateTime object inside them.
I opted to create a descriptive variable inside the millennium function to better convey the solution. The creation of this variable can be omitted if you wish and the argument passed directly into the return statement:
return $date->diff(new DateTimeImmutable('2000-01-01'))->days;
Note that if you only need to use these function for the current date, they can be simplified to take no arguments:
function daysSinceStartOfMillennium(): int
{
$millenniumStart = new DateTimeImmutable('2000-01-01');
return (new DateTimeImmutable())->diff($millenniumStart)->days;
}
function secondsSinceMidnight(): int
{
$midnightToday = new DateTimeImmutable('today');
$diff = (new DateTimeImmutable())->diff($midnightToday);
return $diff->s // seconds
+ $diff->i * 60 // minutes to seconds
+ $diff->h * 60 * 60 // hours to seconds
;
}
Related
Given -
$Foo = new DateTime();
Is it possible to extract the total number of hours (Non-fractional) from this value in a way besides something like...
$Bar = (($Foo->format('Y') * 365) + $Foo->format('d')) * 24
I was hoping for something like
echo $Foo->tHours(); /*Would output the total number of hours since the UNIX clock started.*/
Does something like this exist, or am I just kind of stuck cave-manning like the way I assigned the value to $Bar above?
DateTime has a getTimestamp method, which provides you with a UNIX timestamp (number of seconds elapsed from the epoch). So you could use that to more accurately compute numbers hours (just divide by 60*60).
$Bar = floor($Foo->getTimestamp() / (60 * 60));
echo "Hours since $Foo->format('c') = $Bar"; // Hours since 2015-10-12T18:42:39-04:00 = 401302
I have here a mysql query that get the average of the column(the column data type is 'time'). The column values for example are:
00:00:55, 00:00:59, 00:01:03
SELECT AVG(TIME_TO_SEC(column_name)) FROM table_name)AS average_result
In my Php I formatted the result this way:
<?php foreach($display_average as $da){
echo date("H:i:s", ($da["average_result"]));
}
?>
Outputs: 08:00:59 instead of 00:00:59, Why does this starts with 08? Or did I miss something? Thanks!
Both PHP's date/time functions and MySQL's date/time data types handle wall clock timestamps, not durations; i.e. 00:00:55 means fifty-five seconds past midnight. This is not what you want; you couldn't handle durations longer than 23 hours, 59 minutes, 59 seconds, because the data types and functions you're using are handling clock time, which cannot exceed these values.
Your specific issue stems from timezone settings. Your larger issue is that you need to store simple integer values expressing elapsed seconds or minutes; not timestamps. To format that into a human readable string in PHP you can use the DateInterval class.
see php manul, about the date_default_timezone_set your timezone is +8
the default date.timezone of PHP is utc, u can change it to date.timezone = PRC
date_default_timezone_set('UTC');
echo date("H:i:s", 59);//00:00:59
//date_default_timezone_set('RPC');
//echo date("H:i:s", 59);//08:00:59
Always go for standard/formal approaches. But if anyhow you need it custom, then you can do almost everything with programming. Here we go
Get your time as numbers (number of seconds in your time filed) from database as
SELECT
AVG
(
HOUR(column_name) * 3600
+ MINUTE(column_name) * 60
+ SECOND(column_name)
) AS numeric_average_result FROM table_name
Now you can convert number of seconds to proper time as
foreach($display_average as $da)
{
$r = numToTime($da["numeric_average_result"]);
echo "<br>".$r;
}
function numToTime($num)
{
$seconds = $num%60;
$num = (int)($num/60);
$minutes = $num%60;
$hours = (int)($num/60);
return make2digit($hours).":".make2digit($minutes).":".make2digit($seconds);
}
function make2digit($val)
{
if(strlen($val) == 1)
return "0".$val;
else
return $val;
}
I have a php function that creates a unix timestamp and stores it in a variable. Let's call that variable $timestamp. I'm looking for a function that will allow return two new variables that are a each a different number of hours later than the original timestamp. Is there a way to do this?
This will return a date 3 and 7 days after the supplied date as a unix timestamp. You can edit the math to get the times you need.
$timestamp = date('U');
var_dump(get_more_dates($timestamp));
function get_more_dates($timestamp){
// 60 seconds * 60 minutes * 24 hours * 3 days
$new_date_1 = (60*60*24*3)+timestamp;
$new_date_2 = (60*60*24*7)+timestamp;
return array( $new_date_1, $new_date_1 );
}
Try this-
date( "Y-M-d H:i:s", strtotime( $timestamp ) + $hours * 3600 );
strtotime to convert the timestamp string to timestamp value;
then adding the no. of seconds (hours*36*36); then converting back to the timestamp format using date()
So, you can simply add this code to a function, and give any desired values of $hours; to get the-
different number of hours later than the original timestamp
I would like to display a length of time measured in hours, minutes and seconds where some lengths of time are greater than 24 hours. Currently I am trying this:
$timeLength = new DateTime();
$timeLength->setTime(25, 30);
echo $timeLength->format('H:m:i'); // 01:30:00
I would like it to display 25:30:00.
I am looking preferably for an object oriented solution.
Thanks :)
Since you already have the length in seconds, you can just calculate it:
function timeLength($sec)
{
$s=$sec % 60;
$m=(($sec-$s) / 60) % 60;
$h=floor($sec / 3600);
return $h.":".substr("0".$m,-2).":".substr("0".$s,-2);
}
echo timeLength(6534293); //outputs "1815:04:53"
If you really want to use DateTime object, here's a (kind of cheating) solution:
function dtLength($sec)
{
$t=new DateTime("#".$sec);
$r=new DateTime("#0");
$i=$t->diff($r);
$h=intval($i->format("%a"))*24+intval($i->format("%H"));
return $h.":".$i->format("%I:%S");
}
echo dtLength(6534293); //outputs "1815:04:53" too
If you need it OO and don't mind creating your own class, you can try
class DTInterval
{
private $sec=0;
function __construct($s){$this->sec=$sec;}
function formet($format)
{
/*$h=...,$m=...,$s=...*/
$rst=str_replace("H",$h,$format);/*etc.etc.*/
return $rst;
}
}
DateTime handles time-of-day, not time intervals. And since there's no 25 o'clock, it's the wrong thing to use. There's DateInterval though, which handles date intervals. Use it or do some manual calculation. Even with DateInterval though you'll have to do some calculations, since it'll break down an interval into days and hours. The most straight forward thing to do is to calculate what you need based on the seconds you already have.
I am developing a quiz site and there is time for x min to answer the quiz. So when user clicks on start quiz link the starttime (current time at this instant) is recored in session. Also the endtime (start_time+ 30 min) is recorded in session and every time he submits a answer the current time is compared with the quiz end time. Only if the current time is less than end_time the answer should be accepted.
How can I get the currentdatetime?
How can I add x minutes to current this datetime?
How can I compare (<=) datetime ?
I think we should use date time. Is it right?
PHP measures time as seconds since Unix epoch (1st January 1970). This makes it really easy to work with, since everything just a single number.
To get the current time, use: time()
For basic maths like adding 30 minutes, just convert your interval into seconds and add:
time() + 30 * 60 // (30 * 60 ==> 30 minutes)
And since they're just numbers, just do regular old integer comparison:
$oldTime = $_SESSION['startTime'];
$now = time();
if ($now < $oldTime + 30 * 60) {
//expired
}
If you need to do more complicated things like finding the date of "next tuesday" or something, look at strtotime(), but you shouldn't need it in this case.
use php builtin functions to get time:
<?php
$currentTimeStamp = time(); // number of seconds since 1970, returns Integer value
$dateStringForASpecificSecond = date('Y-m-d H:i:s', $currentTimeStamp);
?>
for your application that needs to compare those times, using the timestamp is more appropriate.
<?php
$start = time();
$end = $start + (30 * 60); // 30 minutes
$_SESSION['end_time'] = $end;
?>
in the page where the quiz is submitted:
<?php
$now = time();
if ( $now <= $_SESSION['end_time'] ) {
// ok!
}
?>
Use the time() function to get a UNIX timestamp, which is really just a large integer.
The number returned by time() is the number of seconds since some date (like January 1, 1970), so to add $x minutes to it you do something like (time() + ($x*60)).
Since UNIX timestamps are just numbers, you can compare them with the usual comparison operators for numbers (< <= > >= ==)
time() will give you the current time in seconds since 1/1/1970 (an integer), which looks like it should be good.
To add x minutes, you'd just need to add x*60 to that, and you can compare it like any other two integers.
Source: http://us3.php.net/time
This is an old question but I wanted to provide an answer based on the PHP 5.2 DateTime class which I feel is much easier to use and much more versatile than any previous functions.
So how can i get the currentdatetime?
You can create a new DateTime object like this:
$currentTime = new DateTime();
But at this point, $currentTime is a datetime object and must be converted to a string in order to store it in a database or output it.
$currentTime = $currentTime->format('Y-m-d H:i:s');
echo $currentTime;
Outputs 2014-05-10 21:14:06
How can i add x minutes tocurrent this datetime?
You can add x minutes with the modify method:
$currentTime = new DateTime();
$addedMinutes = $currentTime->modify('+10 minutes');
echo $addedMinutes;
Outputs 2014-05-10 21:24:06
How can i comapare (<=) datetime ?
With the DateTime class, you can not only easily compare datetime objects, you can get the difference between them.
$currentTime = new DateTime('2014-05-10 21:14:06');
$addDays = $currentTime->modify('+10 days');
To compare
if ($currentTime >= $addDays) {
//do something//
}
$diffTime = new DateTime('2014-05-10 21:14:06');
$diff = $addDays->diff($diffTime);
$diff = $diff->format('There are %d days difference.');
echo $diff;
Outputs There are 10 days difference.