Php get hours difference ranges from midnight fails - php

Am trying to get hours from midnight from the current time
that is suppose now it's 02:34 then I expect to get
02:34 - 02:00,
01:00 - 02:00,
00:00 - 01:00
as an array
so I have tried
function getFromMidnight(){
$durations = [];
$currentTime = strtotime("now");
$iStartOfHour = $currentTime - ($currentTime % 3600);
$midnight = strtotime('today midnight');
$hours = floor(($iStartOfHour - $midnight)/3600);
array_push($durations,["from"=>$currentTime, "to"=>$iStartOfHour]);
if(floor(($iStartOfHour - $midnight)/3600) > 0){
for ($val = 1;$val <= $hours;$val++){
$newval = $val +=1;
array_push($durations, ["from"=>strtotime('- '.$val.' hours',$iStartOfHour),"to"=>strtotime('- '.$newval.' hours',$iStartOfHour)]);
}
}
return $durations;
}
For the first array has the correct durations e.g. from the above example 02:34-02:00 but the next arrays are messed up giving me wrong values with constant timestamps eg: 01:00 - 01:00
I suspect its my for loop with an error, what could be wrong?

I would not use that code, instead of working things out just use DateInterval inverted and work backwards. Then sub() the hour in the loop to get the offset.
<?php
date_default_timezone_set('UTC');
$begin = new DateTime('today midnight');
$end = new DateTime();
$interval = new DateInterval('PT60M');
$interval->invert = 1;
$daterange = new DatePeriod($begin, $interval, $end);
$range = [];
foreach ($daterange as $date){
$range[] = [
'from' => $date->format("H:i"),
'to' => $date->sub($interval)->format("H:i")
];
}
print_r($range);
https://3v4l.org/BMSbI
Result:
Array
(
[0] => Array
(
[from] => 00:00
[to] => 01:00
)
[1] => Array
(
[from] => 01:00
[to] => 02:00
)
[2] => Array
(
[from] => 02:00
[to] => 03:00
)
[3] => Array
(
[from] => 03:00
[to] => 04:00
)
)

Related

PHP get date between a date range and separate by week

How can I create a function that can return accurate start and end date within date range of given date that separate by week.
For example, a date range is given,
$startDate = '2022-08-05';
$endDate = '2022-08-16';
(2022-08-01 is the first day of the week but I want the data return start from the date that user given so do the end date)
So the output should be like this:
2022-08-05 to 2022-08-07
2022-08-08 to 2022-08-14
2022-08-15 to 2022-08-16
data
data
data
My problem is function I found cannot get data start from that date that user given but start from the first day of week and I have no idea how to modify it or create a new function. Any help is appreciate.
function rangeWeek ($datestr) {
date_default_timezone_set (date_default_timezone_get());
$dt = strtotime ($datestr);
return array (
"start" => date ('N', $dt) == 1 ? date ('Y-m-d', $dt) : date ('Y-m-d', strtotime ('last monday', $dt)),
"end" => date('N', $dt) == 7 ? date ('Y-m-d', $dt) : date ('Y-m-d', strtotime ('next sunday', $dt))
);
}
If I set the start date to '2022-08-05' then the output will be start from the first day of the week, how to let it start from '2022-08-05'?
print_r (rangeWeek('2022-08-05'));//output = Array ( [start] => 2022-08-01 [end] => 2022-08-07 )
You can iterate from start to end date and check the week for each day. So you know the week begin and end.
Example
function rangeWeek(string $start, string $end): array
{
$start = new DateTime($start);
$end = new DateTime($end);
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
$weeks = [];
$oldWeek = null;
$weekStart = null;
foreach ($period as $date) {
$week = $date->format('W');
if ($week !== $oldWeek) {
if (null === $weekStart) {
$oldWeek = $week;
$weekStart = $date->format('Y-m-d');
} else {
$weeks[] = ['start' => $weekStart, 'end' => $date->format('Y-m-d'), 'week' => $week];
$weekStart = null;
}
continue;
}
}
$weeks[] = ['start' => $weekStart, 'end' => $end->format('Y-m-d'), 'week' => $week];
return $weeks;
}
$startDate = '2022-08-05';
$endDate = '2022-08-20';
$weeks = rangeWeek($startDate, $endDate);
print_r($weeks);
Output
Array
(
[0] => Array
(
[start] => 2022-08-05
[end] => 2022-08-08
[week] => 32
)
[1] => Array
(
[start] => 2022-08-09
[end] => 2022-08-15
[week] => 33
)
[2] => Array
(
[start] => 2022-08-16
[end] => 2022-08-20
[week] => 33
)
)

How to get datetime range between two datetimestamps with an interval in php

I am trying to write a program to dynamically add interval and find datetime between two dates in php.
I am getting Startdatetime, Enddatetime, Interval from the user.
If the
Start date is 2020-02-17 00:00:00, end date is 2020-02-17 08:00:00, and interval to be added to is 2hrs,
then I am trying to print all datetime ranges like
Array(
[0] => 2020-02-17 00:00:00
[1] => 2020-02-17 02:00:00
[2] => 2020-02-17 04:00:00
[3] => 2020-02-17 06:00:00
[4] => 2020-02-17 08:00:00
)
I tried with dateperiod, but doesn't work as it gives only start & end date
$period = new DatePeriod(
new DateTime($from_datetime),
new DateInterval('PT$hoursH'),
new DateTime($to_datetime)
);
Please help me to get all datetime ranges.
Using this:
<?php
$begin = new DateTime('2020-02-17 00:00:00');
$end = new DateTime('2020-02-17 08:00:01');
$interval = DateInterval::createFromDateString('2 hours');
$period = new DatePeriod($begin, $interval, $end);
$myDates = [];
foreach ($period as $dt) {
$myDates[] = $dt->format("Y-m-d H:i:s");
}
Now executing:
print_r($myDates);
gives you
Array (
[0] => 2020-02-17 00:00:00
[1] => 2020-02-17 02:00:00
[2] => 2020-02-17 04:00:00
[3] => 2020-02-17 06:00:00
[4] => 2020-02-17 08:00:00
)
You can use the date parser of PHP, its pretty intelligent.
$startDate = new DateTime('2020-02-17 00:00:00');
$endDate = new DateTime('2020-02-17 08:00:00');
$intervalInHrs = 2;
while ($startDate <= $endDate) {
$output[] = $startDate->format("Y-m-d H:i:s");
$startDate->modify("+$intervalInHrs Hours");
}
Output:
Array
(
[0] => 2020-02-17 00:00:00
[1] => 2020-02-17 02:00:00
[2] => 2020-02-17 04:00:00
[3] => 2020-02-17 06:00:00
[4] => 2020-02-17 08:00:00
)
$from_datetime = new DateTime('2020-02-17 00:00:00');
$to_datetime = new DateTime('2020-02-17 08:00:00');
$hours = 2;
$interval = new DateInterval('PT'.$hours.'H');
$period = new DatePeriod($from_datetime, $interval, $to_datetime);
$dateArray = [];
foreach ($period as $dt) {
$dateArray[] = $dt->format("Y-m-d H:i:s");
}
print_r($dateArray);exit;
Above code gave me the expected output as
Array
(
[0] => 2021-02-17 00:00:00
[1] => 2021-02-17 02:00:00
[2] => 2021-02-17 04:00:00
[3] => 2021-02-17 06:00:00
[4] => 2021-02-17 08:00:00
)

Convert times into interval array

If I have the following variables:
$starttime = '09:00'; // Start time
$endtime = '21:00'; // End time
$interval = '30'; // In minutes
What would be the best way to generate the following array?
[
"09:00" => "09:30",
"09:30" => "10:00",
"10:00" => "10:30",
"10:30" => "11:00",
...
"20:00" => "20:30",
"20:30" => "21:00"
]
There are some similar topics that show how to array time intervals but none of them have been able to show my specific issue.
Using DateTime class with DateInterval you can achieve what you need.
DateTime - https://www.php.net/manual/pt_BR/class.datetime.php
DateInterval - https://www.php.net/manual/pt_BR/class.dateinterval.php
<?php
$startTime = DateTime::createFromFormat("H:i", "09:00");
$endTime = DateTime::createFromFormat("H:i", "22:00");
$interval = DateInterval::createFromDateString("30 minutes");
$result = [];
while ($startTime <= $endTime) {
$result[$startTime->format('H:i')] = $startTime->add($interval)->format('H:i');
}
echo print_r($result, true);
You can add 30 min to by this command :
$time=date("H:i", strtotime('+30 minutes', $time));
For your problem can set a while loop(for check condition).
Then set and array and set index to :
date("H:i", strtotime('+'.$interval.' minutes', $time));`
And set value to :
date("H:i", strtotime('+'.(2*$interval).'minutes', $time));
Then update $time.
You should just be able to use a 'while' loop to increment a timestamp until $endtime is reached. Here's a working example:
$starttime = '09:00'; // Start time
$endtime = '21:00'; // End time
$interval = '30'; // In minutes
$result = [];
$last = strtotime($starttime);
$endtimestamp = strtotime($endtime);
while ($last < $endtimestamp) {
$next = strtotime("+{$interval} minutes", $last);
$result[date('H:i', $last)] = date('H:i', $next);
$last = $next;
}
var_dump($result);
Can be done using DateTime and DateInterval
<?php
date_default_timezone_set('UTC');
// define start/end
$begin = DateTime::createFromFormat('H:i', '09:00');
$end = DateTime::createFromFormat('H:i', '21:00');
// define the interval
$interval = new DateInterval('PT30M');
$interval->invert = 1;
// get date range
$daterange = new DatePeriod($begin, $interval, $end);
// loop and build your array
$range = [];
foreach ($daterange as $date){
$range[$date->format("H:i")] = $date->sub($interval)->format("H:i");
}
print_r($range);
Result:
Array
(
[09:00] => 09:30
[09:30] => 10:00
[10:00] => 10:30
[10:30] => 11:00
[11:00] => 11:30
[11:30] => 12:00
[12:00] => 12:30
[12:30] => 13:00
[13:00] => 13:30
[13:30] => 14:00
[14:00] => 14:30
[14:30] => 15:00
[15:00] => 15:30
[15:30] => 16:00
[16:00] => 16:30
[16:30] => 17:00
[17:00] => 17:30
[17:30] => 18:00
[18:00] => 18:30
[18:30] => 19:00
[19:00] => 19:30
[19:30] => 20:00
[20:00] => 20:30
[20:30] => 21:00
)
https://3v4l.org/FqViY

Find week days date from range of the two dates

$start_date = "2013-05-01";
$last_date = "2013-08-30";
How can I get dates of tuesdays and thursdays between these two dates?
<?php
$start = new DateTime('2013-05-01');
$end = new DateTime('2013-08-30');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
if ($dt->format("N") == 2 || $dt->format("N") == 4) {
echo $dt->format("l Y-m-d") . "<br>\n";
}
}
See it in action
What this code does:
Creates a starting date object using DateTime.
Creates a starting date object using DateTime.
Creates a DateInterval object to represent our interval of time to iterate through. In this case 1 day.
Creates a DatePeriod object to manage these objects.
Using DatePeriod, it iterates through the date starting with the starting date and ending at the end date. We use DateTime::format() with the N parameter to get the day number of the week. If the day number of the week is 2 (Tuesday) or 4 (Thursday) echo out it's value.
Some PHP-Fu
$start_date = '2013-05-01';
$last_date = '2013-08-30';
$dates = range(strtotime($start_date), strtotime($last_date),86400);
$days = array('tuesday' => array(), 'thursday' => array());
array_map(function($v)use(&$days){
if(date('D', $v) == 'Tue'){
$days['tuesday'][] = date('Y-m-d', $v);
}elseif(date('D', $v) == 'Thu'){
$days['thursday'][] = date('Y-m-d', $v);
}
}, $dates); // Requires PHP 5.3+
print_r($days);
Output
Array
(
[tuesday] => Array
(
[0] => 2013-05-07
[1] => 2013-05-14
[2] => 2013-05-21
[3] => 2013-05-28
[4] => 2013-06-04
[5] => 2013-06-11
[6] => 2013-06-18
[7] => 2013-06-25
[8] => 2013-07-02
[9] => 2013-07-09
[10] => 2013-07-16
[11] => 2013-07-23
[12] => 2013-07-30
[13] => 2013-08-06
[14] => 2013-08-13
[15] => 2013-08-20
[16] => 2013-08-27
)
[thursday] => Array
(
[0] => 2013-05-02
[1] => 2013-05-09
[2] => 2013-05-16
[3] => 2013-05-23
[4] => 2013-05-30
[5] => 2013-06-06
[6] => 2013-06-13
[7] => 2013-06-20
[8] => 2013-06-27
[9] => 2013-07-04
[10] => 2013-07-11
[11] => 2013-07-18
[12] => 2013-07-25
[13] => 2013-08-01
[14] => 2013-08-08
[15] => 2013-08-15
[16] => 2013-08-22
[17] => 2013-08-29
)
)
Online demo
$start_date = strtotime("2013-05-01");
$last_date = strtotime("2013-08-30");
while ($start_date <= $last_date) {
$start_date = strtotime('+1 day', $start_date);
if (date('N',$start_date) == 2 || date('N',$start_date) == 4){
echo date('Y-m-d', $start_date).PHP_EOL;
}
}
<?php echo date('Y-m-d', strtotime('next thursday', strtotime($start_date)));
Also for tuesday ofcourse
Please use the following function for your solution,
function daycount($day, $startdate, $lastdate, $counter=0)
{
if($startdate >= $lastdate)
{
return $counter;
}
else
{
return daycount($day, strtotime("next ".$day, $startdate), ++$counter);
}
}
$start_date = "2013-05-01";
$last_date = "2013-08-30";
echo "Tuesday Count - ".daycount("tuesday", strtotime($start_date), strtotime($last_date));
echo "<br/>";
echo "Thursday Count - ".daycount("thursday", strtotime($start_date), strtotime($last_date));
Try with this
$startDate = strtotime($start_date);
$endDate = strtotime($last_date);
while ($startDate < $endDate) {
echo date('Y-m-d', $startDate ). "\n";
// Give the condition to find last Tuesday
$startDate = strtotime( 'next Tuesday', $startDate );
}
With DateTime:
$start_date = "2013-05-01";
$last_date = "2013-08-30";
$start = new DateTime($start_date);
$clone = clone $start;
$start->modify('next thursday');
$thursday=$start->format('Y-m-d');
$clone->modify('next tuesday');
$tuesday=$clone->format('Y-m-d');
echo $thursday; //2013-05-02
echo $tuesday; //2013-05-07
We need to objects because if in interval tuesday is before thursday we will have next tuesday. But you can modify little code to use one object.
With the help of few php date functions this can be solved easily..
<?php
// Create the from and to date
$start_date = strtotime("2013-05-01");
$last_date = strtotime("2013-08-30");
// Get the time interval to get the tue and Thurs days
$no_of_days = ($last_date - $start_date) / 86400; //the diff will be in timestamp hence dividing by timestamp for one day = 86400
$get_tue_thu_days = array();
// Loop upto the $no_of_days
for($i = 0; $i < $no_of_days; $i++) {
$temp = date("D", $start_date);
if($temp == "Tue" || $temp == "Thu") {
$get_tue_thu_days[] = date("D/M/Y", $start_date); //formating date in Thu/May/2013 formate.
}
$start_date += 86400;
}
print_r($get_tue_thu_days);
if you have a reference date which you know is a tuesday/thursday you can find days which are a multiple of 7 days from your reference date, these days will always be the same day of the week.

Compare todays dayname and time through array?

I have an array like this:
Array
(
[0] => stdClass Object
(
[Start] => 08:00
[dayName] => Tuesday
[dayID] => 2
[courseName] => Math
)
[1] => stdClass Object
(
[Start] => 10:00
[dayName] => Tuesday
[dayID] => 2
[courseName] => Geography
)
[2] => stdClass Object
(
[Start] => 14:00
[dayName] => Tuesday
[dayID] => 2
[courseName] => Science
)
[3] => stdClass Object
(
[Start] => 10:00
[dayName] => Thursday
[dayID] => 4
[courseName] => Math
)
[4] => stdClass Object
(
[Start] => 18:00
[dayName] => Friday
[dayID] => 5
[courseName] => History
)
)
What I want to do is , I want to compare the daya nd time now to the values in the array. For example lets assume that it is 7:00 am and it is Tuesday. Then I want to get the Object[0]. But if it is 11:00 o'clock then i need to get the Object[2] which starts at 14:00 on Tuesday.
It it is Tuesday and 16:00 o'clock then i need Object[3] .
If it is a weekend then i need the beginning of the week which is Tuesday at 08:00 with the Math Course.
I tried to get that using key => value but I mixed up.
How can I compare the Day and then time and in case there is a Course on that combination just pick it up if not just continue checking.
regards
littleblue
function getObject($array){
$timeNow = date('U'); // time now
$oneHour = $timeNow+3600; // time now + 1 hour
foreach($array as $num => $one){ // loop in each $array
$date = strtotime($one->Start); // convert start time to timestamp
if($date >= $timeNow && $date < $oneHour && date('l', $date) == $one->dayName){ // if all criteria met
return $array[$num]; // return that object
}
}
return array('no data'); // if no criteria is met return no data.
}
$course = getObject($yourArray);
echo $course->courseName;
You can mix the use of DateTime and a simple min search :
$myCourse = null;//initialisation
$myCourseDate =null;
$now = new DateTime;
foreach($array as $course){
//get the date from the datas
$date = DateTime::createFromFormat('l h:i',$course->dayName.' '.course->start);
if($now < $date && ($myCourseDate === null || $myCourseDate > $date)){
$myCourse = $course;
$myCourseDate = $date;
}
}
//at the end of the loop, you've got the expected course

Categories