Facing issue while calculating the difference of time on different days - php

I have a cron which runs every minute calculates the difference between current time and an entry made. This cron will stop after business hours and run again when business hour starts.
I'm having an issue only when the entry is made on the evening (6pm) of tuesday and the difference is calculated with 1am of Wednesday.
How can I fix this?
Here is my code:
$ticket_created_timestamp = strtotime($ticket_created_time);
$current_time = date("H:i:s");
$current_timestamp = strtotime($current_time);
$time_difference_timestamp = $current_timestamp - $ticket_created_timestamp;

i don't see any particular problem here but my guess is - perhaps strtotime can't correctly interpret your ticket created time value
try something like that instead
$ticket_created_time = "2016-08-17 12:00:00";
$objDateCreatedTicketTime = DateTime::createFromFormat("Y-m-d H:i:s", $ticket_created_time);
$objDateTime = new DateTime();
$time_difference_timestamp = $objDateTime->getTimestamp() - $objDateCreatedTicketTime->getTimestamp();
The main advantage with this method is, that you've something standardized.
You can decide how your date input looks like without loosing the flexibility of handling your dates correctly.

Related

Looking for better way to append hours and minutes onto a modified Datetime object

I am trying to project out many recurring appointments based on one database item that declares the appt time, what day of the week it occurs on, and how many times the appt happens until it stops (if it ever stops)
I can get it to work by first storing the minutes and hours into seperate variables, then modifying the object and appending the hours and minutes onto each modified object as its stored in an array.
$t = new DateTime($ra->start_date);
$c = new DateTime($ra->end_date);
$hour = $t->format('H');
$mins = $t->format('i');
$chour = $c->format('H');
$cmins = $c->format('i');
for($k=0; $k<$frequency[$i]; $k++){
$mod = '+1 weekday';
$s = clone $t->modify($mod)->setTime($hour, $mins);
$e = clone $c->modify($mod)->setTime($chour, $cmins);
array_push($starts, $s);
array_push($ends, $e);
}
If I dont do it like this it will modify the date by the desired amount, but it will wipe the time stamp to 00:00:00.
That behavior is explained in the first Note block of the relative time formats documentation:
Note that "tomorrow 11:00" and "11:00 tomorrow" are
different. Considering today's date of "July 23rd, 2008" the first one
produces "2008-07-24 11:00" where as the second one produces
"2008-07-24 00:00".
The reason for this is that "yesterday", "midnight", "today", "noon"
and "tomorrow"
directly influence the current time.
So taking that into account, a slightly more compact way of doing this is to pass the time as part of the relative time you want to add. For demonstration:
$date = new DateTimeImmutable('2019-08-30 14:31:26');
$newDate = $date->modify('+1 weekday ' . $date->format('H:i:s'));
Demo
Since you need mutability to be able to recurrently add days, use regular DateTime objects like you are doing instead of DateTimeImmutable.

Find next occurance of a given time after given timestamp

Given an arbitrary timestamp (e.g. 2019-02-26 10:30:00) I would like to find the next occurrence of an arbitrary time.
For example, the next occurrence of 12:00:00 will be 2019-02-26 12:00:00 but the next occurrence of 09:00:00 will be the next day at 2019-02-27 09:00:00. The results could be Carbon or Datetime objects. The test time will just be a string as shown.
Is there a way to calculate this in native PHP or PHP Carbon without conditionally boxing in time periods. An obvious way would be to see if the time being tested is past the check time for today, and if it is, taking the result as the check time plus 24 hours (the next day). That feels to me like too much chopping and joining of dates and times, so is there a way to calculate it by considering time to be a simple linear line?
All times will be in a single timezone, with DST. Note: the arbitrary datetimes and check times will stay clear of DST changeovers i.e. 01:00 to 02:00 so hopefully they will not be an issue to take into account.
Short answer is no for PHP (partial answer, I'm no specialist of Carbon but from quick look it's also no, but you can create a macro from following code).
However, with a ternary condition the one-liner is simple enough IMHO (replace the second DateTime($str) with DateTime() if you want to compare with current date and time, and change the >= by > if you want next day when time compared is exactly the same):
$str = '2019-02-26 10:30:00';
$date1 = ( ($a = (new DateTime($str))->setTime(12,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
$date2 = ( ($a = (new DateTime($str))->setTime(9,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
echo $date1->format('Y-m-d H:i:s'); //2019-02-26 12:00:00
echo $date2->format('Y-m-d H:i:s'); //2019-02-27 09:00:00
quick note: what you gave us is not a timestamp, but a formatted date.
Here is what I am using now through Carbon, which appears to give me the correct results:
$dateTime = Carbon::parse('2019-03-30 17:34:50', 'Europe/London');
$testTime = '16:00:00';
list ($hour, $minute, $second) = explode(':', $testTime);
$nextTimeOccurrence = $dateTime
->copy() // Carbon 1 only
->hour($hour)->minute($minute)->second($second);
if ($dateTime->gt($nextTimeOccurrence)) {
$nextTimeOccurrence = $nextTimeOccurrence->addDay();
}
// $nextTimeOccurrence is the next occurrence of $testTime after $dateTime
The splitting of the time seems clumsy, but might be the best way? The approach is:
Create a timestamp with the test time on the same day as the timestamp I'm checking. This will be the timestamp I am looking for.
If the timestamp I'm checking is after the timestamp created in the previous step, then add a day to it.
I've tested this around DST, and happily Carbon/Datetime keeps the same time when adding a day over a DST period, where a day there would be 25 hours or 23 hours, depending on which way it goes.
I still think there is a more "linear time" way to do this, but this seems simple and robust. Thanks go to #michael-stokoe here at the office for my lead on this.

How to get the duration of an inserted time by inserting another one with minute:seconds:milliseconds?

I am making a game mode in which I am trying to get the time a player has arrived at their destination after starting the mode and to do this I am using the insert of a date when it starts the mode it inserts a date and after reaching the your destination it registers another date and with both dates it calculates the time it took to get to the destination, with this I'm using date H:i:s (hours, minutes, seconds) but I need to take the time out and leave milliseconds after seconds example: i:s:u (minutes, seconds, milliseconds) but I'm not able to do this, I've tried it in several ways, basically everything works as follows:
1. I add in the player array a current date with hour, minutes, seconds;
$this->game[$player->getName()] = ["start" => strtotime('now')];
2. After the Player arrives at his destination he calculates the time of his trajectory creating another current date with already registered and using date and mktime to do the join and give a visual of time to the player;
$time = date('H:i:s', mktime(0, 0, str_replace("-", "", $this->game[$player->getName()]["start"] - strtotime('now'))));
3. Send the pretty message to the player about the time of his trajectory then time will be something like this: 01:45:23 (minute:seconds:milliseconds).
$player->sendMessage("You beat your time record by ".$time);
This is my method of doing, if you have another better method with the milli seconds added I accept the suggestion! Maybe there might be some errors in my code that I'm still not sure if they work correctly as the subtraction to calculate and join the current time with the previous one, tell me if it's right and if it is not correct correct me or do better. Thank you
Use microtime which returns the current Unix timestamp with microseconds
$game = [];
$game['start'] = microtime(true);
// Do stuff
sleep(3); // Without the sleep, start and end are the 'same'
$game['end'] = microtime(true);
$elapsedTime = ($game['end'] - $game['start']);
$minutes = floor($elapsedTime / 60);
$seconds = $elapsedTime % 60;
$milliseconds = number_format($elapsedTime - floor($elapsedTime),3);

php add scheduled tasks as minutes to current time as 12:10 - 12:19

I´m making a simple time management system feature and I want to add
task and estimated minutes.
So if I add into the field "finish sending e-mail to John" and "23" (as minutes) it goes into
mysql as $sql = "INSERT INTO schedule (task, time, timestamp) VALUES ('$_POST[task]','$_POST[time]','$_POST[timestamp]')";
The output would be " Finish sending e-mail to John 21:02 - 21:25 "
so if next task takes 7 minutes it will be from 21:26 - 21:33" (take notice
of the first task and so and and so forth
I tried echo date('H:i', strtotime('+["time"] minutes', ));
but it doesn´t
work and I don´t know how the next record would take notice of the next one
is this possible?
What you tried above is almost correct, except that you might mean $_POST['time'] instead of ["time"], making your code: echo date ('H:i', strtotime('+{$_POST["time"]} minutes'));. But that will give you the time minutes after current time, not after the starting time.
To get the end time, you need to convert your start time (I assume it's $_POST['timestamp']) into UNIX timestamp, then add the task's length and get the UNIX timestamp from it.
Give this a try:
// Remember to check for valid user input. I'll leave that for you.
$task = $_POST['task'];
$time = $_POST['time'];
$timestamp = $_POST['timestamp'];
// Get the time here
$start_time = date ("H:i", strtotime ($timestamp));
$end_time = date ("H:i", strtotime ($timestamp) + $time * 60);
echo "{$task} {$start_time}-{$end_time}\n";

One hour difference in date and time after adding Daylight Saving Time offset in php

HI All,
I'm trying to match today's date and time at Atalanta to a database value. I'm testing following code.
$date = new DateTime();
$newToday = $date->format('Y-m-d H:i:s');
$dateTimeArr = split(" ",$newToday);
$dateArr = split("-", $dateTimeArr[0]);
$timeArr = split(":",$dateTimeArr[1]);
$testTime = date("Y-m-d H:i",mktime($timeArr[0]+4, $timeArr[1], $timeArr[2], $dateArr[1], $dateArr[2], $dateArr[0])); // 4 is Daylight Saving Time offset
When I run the code, I found that there is 1 hour time difference if I check the time at http://www.timetemperature.com/tzga/atlanta.shtml
I'm adding the day light saving offset which 4 hours, but still the time I get is 1 hour more than the actual time. Why this difference is seen ? How to rectify this ?
EDIT
My server is at different time zone than Atalanta. I want to handle the time difference without knowing the timezones. For this, for each city we have added timezone offset in database.
Use the DateTime and DateTimeZone objects:
//EDT = Eastern Daylight Saving Time
$x = new DateTime(null, new DateTimeZone('EDT'));
echo $x->format("Y-m-d H:i")
I think that if you use America/New_York (which is in the same timezone as Atlanta) as the timezone, it will change accordingly between normal and daylight saving time.
$x = new DateTime(null, new DateTimeZone('America/New_York'));
echo $x->format("Y-m-d H:i")
Both versions output the same time for me.
Have you checked your server's (the computer that executes the actual PHP script) time? See if it has the right time

Categories