How to get time only timestamp from a date in PHP - php

I have a time field in a PHP that receives Hours and minutes (H:i).
This goes into a \Datetime Object.
By magic and, in my case, undesiredly, the current Date is added to that time.
I would like to strip the date and keep the time only.
$timeonly = $this->getDate()->format('H:i');
This gives me the string 10:00.
But now ... how can this string be converted into the desired integer 36000 which is 10h?
I tried strtotime($timeonly) but this added the date again...
Is this even a good idea, and do I not find it because it's so trivial or because this isn't done?
Maybe there's something in DateTime-> like returnTimeWithoutDate?

This is trivial with a little bit of math:
function timeToSeconds(\DateTime $dt)
{
return $dt->format('H') * 3600 + $dt->format('i') * 60;
}
echo timeToSeconds($this->getDate());

Hack the code :
$timeonly = $this->getDate()->format('H')*3600 + $this->getDate()->format('i')*60;

You should try sometings like this :
$timeonly = $this->getDate()->format('H:i');
$date = strtotime($timeonly);
echo date('H', $date);

Related

PHP: calculate days since event and seconds since midnight

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
;
}

subtract and add a variable of time to a given time using php

I have a given time and i need to create another time base on another given time. Let suppose i have given 4:00:00 AM, and another time is 2:00:00 , my result should be 6:00:00 AM, and 2:00:00 AM(based on condition).
this is what i am using but its not giving correect result.
if($data['turn_on_before_or_after'] == 'before'){
$time = strtotime($data['sunset']) - strtotime($data['variation_turn_on']);
$dataNew['final_turn_on'] = date('h:m:s',$time);
}
if($data['turn_on_before_or_after'] == 'after'){
$time = strtotime($data['sunset']) + strtotime($data['variation_turn_on']);
$dataNew['final_turn_on'] = date('h:m:s',$time);
}
Recommendation: use strtotime(). It will takes the date/time/datetime string and convert it to an integer; starting at the unix epoch. So 2AM would be 7200 and 4AM would be 14400; add those integers together and use date('H', $result) would convert the integer back into a time string. Boosh, win!
Opinion: many people will say unix timestamp is hard to use 'cause it is not human readable;I'd rather my logic be easy to read than the output. As the output only happens at the end of processing.
I recreated your scenario, but instead of using strtotime I used the DateTime object.
Your main problem is that your first date ($data['sunset']) must be considered as a real date, but your second date ($data['variation_turn_on']) must be considered as an interval. Because of this, and after looking at the DateInterval object constructor, you notice that you can create an interval using sscanf from your initial string. After creating that interval, all you have to do is to use the methods from the DateTime class to simply add or substract intervals from a specific date.
Here is the code I wrote to obtain the results you expect (6:00:00 AM and 2:00:00 AM) :
<?php
/* Initial parameters */
$data['turn_on_before_or_after'] = "before";
$data['sunset'] = "4:00:00 AM";
$data['variation_turn_on'] = "2:00:00";
/* Creating a list with your variation values */
list($hours, $minutes, $seconds) = sscanf($data['variation_turn_on'], '%d:%d:%d');
/* Creating the interval (here is the magic) */
$intervale = new DateInterval(sprintf('PT%dH%dM%dS', $hours, $minutes, $seconds));
/* Creating a DateTime object from your sunset time */
$date = new DateTime($data['sunset']);
/* Ternary for simplification, substract if before, add if everything else, you may use an if statement here */
$data['turn_on_before_or_after'] == 'before' ? $date->sub($intervale) : $date->add($intervale);
/* Printing the result */
echo $date->format('h:i:s A');

strtotime and weird results when calculating time differences (datetime)

I've been trying at this for a bit and can't get the damn code to work.. This is my first post, I've gone through a few, tried a million different ways.. I just want to get the difference in hours, then I'm set, I'll get the rest figured out..
Right now, it's giving me unusual answers (say there's a 2 hour difference, it'll give me 14 as an answer) Pardon my coding, I haven't done this in years and have no real formal training. I'll be as thorough as possible in my comments, and thanks a LOT. Any links appreciated. I have tried a LOT. Using PHP 5.3.something, and am pulling off a Wordpress 3.7.1 database.
Thanks in advance for the help for a beginner. I want to display "Updated x hours ago". Once I have the darned thing displaying the correct result, I'll figure the rest out.
//This is the current date, putting it into strtotime so everything is in the same format. It displays accurately.
$currentDate = date("Y-m-d");
$currentTime = date("H:i:s");
$currentDateHour = date("H", strtotime($currentDate . $currentTime));
// This is the date I'm pulling from the database, it only displays
// when in strtotime for some reason. It displays accurately to what is in the mySQL DB
$upDate = date("Y-m-d H", strtotime($row2[post_date]));
// Some variables to make life easier for later if statements if I ever get that far. Displays accurately.
$upDatehour = date("H", strtotime($row2[post_date]));
// trying simple subtraction
$hour = $currentDateHour - upDatehour;
// this is where the result is incorrect, what is wrong here? Any method I've tried gives me the same result, with or without strotime.. it's gotta be something simple, always is!
print strtotime($hour);
You can drastically simplify your code. I'd recommend refactoring it to use DateTime and specifically DateTime::diff().
$now = new DateTime();
$post = new DateTime($row2['post_date']);
$interval = $now->diff($post);
echo "Updated " . $interval->h . " hours ago";
Working example: http://3v4l.org/23AL6
Note that this will only show up to 24 hours difference. If you want to show all hours even for a difference of more than 24 hours, you'll need to figure in the days. Something like this:
$hours = $interval->h + ($interval->format("%a") * 24);
echo "Updated $hours hours ago";
Working example: http://3v4l.org/ilItU
If you are just trying to get the number of hours between two arbitrary times, the easiest way would be to get the difference in seconds of the two times, and then divide by 3600 to determine the number of hours between the two dates.
Here is a basic example:
<?php
$row2['post_date'] = '2013-12-02 07:45:38'; // date from database
$now = time(); // get current timestamp in seconds
$upDate = strtotime($row2['post_date']); // convert date string to timestamp
$diff = $now - $upDate; // subtract difference between the two times
$hours = floor($diff / 3600); // get the number of hours passed between the 2 times
echo $hours; // display result
Also, Wordpress has a built in function that may end up doing what your ultimate goal is, see wordpress function human_time_diff().
Example:
<?php echo human_time_diff( get_the_time('U'), current_time('timestamp') ) . ' ago';
Result:
2 days ago.
Example how to get difference between dates in hours:
$diff = date_diff(date_create(), date_create($row2['post_date']));
$hours = $diff->days * 24 + $diff->h;
If you wish to format output number with leading zeros, you can use sprintf() or str_pad() function. Example of sprintf() use for HH:mm format:
echo sprintf('%02d:%02d', $hours, $diff->i);
demo

Change date after 6 hrs in php variable

I need to change the shiftdate variable after 05:30 AM. Since i need to generate data from past 24 hrs starting 05:31 AM to Next day 05:30 AM. I tried like this, but its giving previous day every time. Please help.
I want $shiftdate to use in my sql query;
Code:
<?php
if(date('H:i')>="00:00" || date('H:i')<"05:30"){
$shiftdate= date('Y-m-d',strtotime(date('Y-m-d'))-24*60*60);
}
else if(date('H:i')>"05:30" || date('H:i')<"00:00")
{
$shiftdate=date('Y-m-d');
}
echo $shiftdate;
?>
You can't just compare string like "05:30" as a number and hope for the best. You need to compare numerical value of the hour and then numerical value of the minute.
You have a race in between the first if and the else if
Also the else if doesn't cover it completely, so if it hit's the sweetspot, you can end up with $shiftdate being NULL.
Make it a function with protoype shiftdate_type_whatever_it_is fn_name(int hour, int minute);. This way you can simply unit test the function for different (think boundary) values of the date("H:i");
You can use the DateTime classes for this and encapsulate your check into a function:-
/**
* #param DateTime $checkTime
* #return string
*/
function getShiftDate(DateTime $checkTime)
{
$shiftDate = (new DateTime())->setTimestamp($checkTime->getTimestamp());
$hours = (int)$checkTime->format('H');
$minutes = (int)$checkTime->format('i');
$totalMins = $hours * 60 + $minutes;
if($totalMins < 330){
$shiftDate->modify('yesterday');
}
return $shiftDate->format('Y-m-d');
}
var_dump(getShiftDate(new DateTime()));
Obviously the input to the function may need to be modified as I don't know how you get your date/time, but that won't be a problem. Post a comment if you need help with that.

Getting unix timestamp in milliseconds in PHP5 and Actionscript3

In Actionscript, the Unix timestamp in milliseconds is obtainable like this:
public static function getTimeStamp():uint
{
var now:Date = new Date();
return now.getTime();
}
The doc clearly states the following:
getTime():Number Returns the number of
milliseconds since midnight January 1,
1970, universal time, for a Date
object.
When I trace it, it returns the following:
824655597
So, 824655597 / 1000 / 60 / 60 / 24 / 365 = 0.02 years.
This is obviously not correct, as it should be around 39 years.
Question #1: What's wrong here?
Now, onto the PHP part: I'm trying to get the timestamp in milliseconds there as well. The microtime() function returns either a string (0.29207800 1246365903) or a float (1246365134.01), depending on the given argument. Because I thought timestamps were easy, I was going to do this myself. But now that I have tried and noticed this float, and combine that with my problems in Actionscript I really have no clue.
Question #2: how should I make it returns the amount of milliseconds in a Unix timestamp?
Timestamps should be so easy, I'm probably missing something.. sorry about that. Thanks in advance.
EDIT1: Answered the first question by myself. See below.
EDIT2: Answered second question by myself as well. See below. Can't accept answer within 48 hours.
I used unsigned integer as the return type of the function. This should be Number.
public static function getTimeStamp():Number
{
var now:Date = new Date();
return now.getTime();
}
Think I got the function for getting milliseconds in PHP5 now.
function msTimeStamp() {
return round(microtime(1) * 1000);
}
For actionscript3, new Date().getTime() should work.
In PHP you can simply call time() to get the time passed since January 1 1970 00:00:00 GMT in seconds. If you want milliseconds just do (time()*1000).
If you use microtime() multiply the second part with 1000 to get milliseconds. Multiply the first part with 1000 to get the milliseconds and round that. Then add the two numbers together. Voilá.
Use this:
intval(microtime(true)*1000)
To normalize a timestamp as an integer with milliseconds between Javascript, Actionscript, and PHP
Javascript / Actionscript:
function getTimestamp(){
var d = new Date();
return Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()).valueOf();
}
PHP:
function getTimestamp(){
$seconds = microtime(true); // true = float, false = weirdo "0.2342 123456" format
return round( ($seconds * 1000) );
}
See PHP note at "ben at sixg dot com's" comment at: http://www.php.net/manual/en/function.gmmktime.php
EXCERPT:
For most intents and purposes you can imagine that mktime() first converts your input parameters to GMT and then calls gmmktime() which produces a GMT timestamp.
So, time() always will return the same thing at the same actual moment, anywhere in the world.
gmmktime() and mktime(), when given specific time parameters, convert those time parameters FROM the appropriate timezone (GMT for gmmktime(), local time for mktime()), before computing the appropriate timestamp.
UPDATE:
On some versions of PHP, the timestamp with milliseconds is too large to display as a string. So use the sprintf function to get the string value:
PHP
function getTimestamp($asString=false){
$seconds = microtime(true); // false = int, true = float
$stamp = round($seconds * 1000);
if($asString == true){
return sprintf('%.0f', $stamp);
} else {
return $stamp;
}
}
microtime() in php5 returns unix timestamp with microseconds as per microtime() and if the get_as_float argument is not provided, it gives you a string formatted as "msec sec" so the first part is the millisecond part and the second is the second part. Just split it in two and you get the two parts of the timestamp
Simple answer for PHP:
function exact_time() {
$t = explode(' ',microtime());
return ($t[0] + $t[1]);
}
To get millisecond timestamp from PHP DateTime object:
<?php
date_default_timezone_set('UTC');
$d = new \DateTime('some_data_string');
$mts = $d->getTimestamp().substr($d->format('u'),0,3); // millisecond timestamp
PHP 7
This function has its return type declared.
function timestamp_ms(): int {
$times = gettimeofday();
$seconds = strval($times["sec"]);
$milliseconds = strval(floor($times["usec"]/1000));
$missingleadingzeros = 3-strlen($milliseconds);
if($missingleadingzeros >0){
for($i = 0; $i < $missingleadingzeros; $i++){
$milliseconds = '0'.$milliseconds;
}
}
return intval($seconds.$milliseconds);
}
PHP 5
function timestamp_ms() {
$times = gettimeofday();
$seconds = strval($times["sec"]);
$milliseconds = strval(floor($times["usec"]/1000));
$missingleadingzeros = 3-strlen($milliseconds);
if($missingleadingzeros >0){
for($i = 0; $i < $missingleadingzeros; $i++){
$milliseconds = '0'.$milliseconds;
}
}
return intval($seconds.$milliseconds);
}
when you need the millisecond in str format, I think you should use:
public function get_millisecond() {
list($milliPart, $secondPart) = explode(' ', microtime());
$milliPart = substr($milliPart, 2, 3);
return $secondPart . $milliPart;
}
this will fix the bug int some get millisecond example where the milli part is like : 0.056. some example convert the milli part to float, your will get 56 instead of 056. I think some one want 056.
especially when you need the millisecond to order some data.
hope will help. :)
I recently had this problem to get a timestamp in milliseconds. To just multiply the unix timestamp by 1000 did not resolve the problem because i had to compare two database entrys very precicely. Aparently the php datetime object can´t handle milliseconds/microseconds but its stored in the datetime string anyway. So here is my solution:
$dateObject = new \DateTime('2015-05-05 12:45:15.444', new \DateTimeZone('Europe/London'));
$millis = $dateObject->format('v');
echo $dateObject->getTimestamp()*1000+$millis;
This should also work with microseconds if you use format->('u') (and of course multiply the timestamp by 1000000) instead. I hope you find this useful.
Something like this:
$mili_sec_time = $_SERVER['REQUEST_TIME_FLOAT'] * 1000;
Gives float type representing miliseconds from UNIX epoch to starts of the request.
$timestamp = str_replace(".","",number_format((float)microtime(true),2,'.',''));

Categories