I developed a function to obtain equal time intervals within a user generated time-frame.
$start = strtotime("12:00"); //start at...
$end = strtotime("18:00"); //end at...
$timeframe = $end - $start; //time-frame
$intervals = 3; //number of intervals within time-frame
$interval_time = $timeframe/$intervals; //time of each interval
for($i = 0, $start;
$i < $intervals;
$i++, $start = strtotime("+$interval_time seconds", $start)) //increment time
{
$new_time = date('H:i:s a', $start);
echo "$new_time \n";
}
The code above outputs
12:00:00 pm 14:00:00 pm 16:00:00 pm
What code can I incorporate to divide each interval and obtain the middle? For example to get from the code above
13:00:00 pm 15:00:00 pm 17:00:00 pm
Please kindly advise :)
Replace your for loop with:
$half_interval = $interval_time / 2;
$mid = $start + $half_interval;
for ( $i = 1; $i < $intervals; $i ++) {
echo date('H:i:s a', $mid) . " \n";
$mid += $interval_time;
}
echo date('H:i:s a', $mid) . " \n";
Admittedly a simple approach. I'm sure improvements are possible, but leave them as an exercise for the reader! ;-)
Related
I am trying to make a function in Laravel 5.6
I have a $start_time, $end_time and $duration variables.
I would like to get time slots from the start time until end time, in $duration periods, for example:
$duration = 30 min
$start_time = 9:00 am
$end_time = 9:00 pm
Results:
-9:00 - 9:30
-9:30 - 10:00
-10:00 - 10:30
.... etc
Also, I would like to not show the slot where time overlaps with appointments in my database.
$starttime = '9:00'; // your start time
$endtime = '21:00'; // End time
$duration = '30'; // split by 30 mins
$array_of_time = array ();
$start_time = strtotime ($starttime); //change to strtotime
$end_time = strtotime ($endtime); //change to strtotime
$add_mins = $duration * 60;
while ($start_time <= $end_time) // loop between time
{
$array_of_time[] = date ("h:i", $start_time);
$start_time += $add_mins; // to check endtie=me
}
$new_array_of_time = array ();
for($i = 0; $i < count($array_of_time) - 1; $i++)
{
$new_array_of_time[] = '' . $array_of_time[$i] . ' - ' . $array_of_time[$i + 1];
}
If you are using Laravel there is a dependency for times&dates called Carbon I'm sure you've heard of.
all you have to do is importing it like that:
use Carbon\Carbon;
Then we can see what will we do by this dependency, we just create a time then add minutes to it according to duration, that is what you want to.
$start_time = Carbon::createFromTime(9, 0, 0); // hours, minutes, seconds
$end_time = Carbon::createFromTime(21, 0, 0);
$time = $start_time;
$time_slots = array();
while($time < $end_time){
$time = $time->addMinutes(30);
$time_slots[] = $time;
}
This array will have the time slots you want and you can manipulate them whatever you like.
You can also look at this links below:
Documentation: https://github.com/briannesbitt/Carbon
String formats for Carbon: http://carbon.nesbot.com/docs/#api-formatting
I iterate through time by adding 86400 (the count of seconds in the 1 day) to list the dates.
define("DAY_SEC", 86400);
for ($i = strtotime("2016-10-01"); $i<=strtotime("2016-11-05"); $i = $i + DAY_SEC){
echo Date("Y-m-d, H:i:s", $i). ' = '. $i . '<br/>';
}
But look on the date "2016-10-30". It is there twice but with different hours
2016-10-28, 00:00:00 = 1477605600
2016-10-29, 00:00:00 = 1477692000
2016-10-30, 00:00:00 = 1477778400 <- here
2016-10-30, 23:00:00 = 1477864800 <- here
2016-10-31, 23:00:00 = 1477951200
What do I wrong?
thanx
Do not add or subtract or do any other math with timestamps to calculate past or future dates. Your code will fail after 2016-11-05 in U.S. and some other time zones because that is the end of Daylight Saving Time this year. strtotime() is aware of this, so use it with "+1 day" or something similar:
for ($i = strtotime("2016-10-01"); $i<=strtotime("2016-11-05"); $i = strtotime("+1 day", $i)){
echo Date("Y-m-d, H:i:s", $i). ' = '. $i . '<br/>';
}
It turns out 2016-10-30 is the end of Daylight Saving Time in many other places, so the time zone you are using is subject to that change.
It is called DST(Daylight Savings Time). Try using strtotime().
$start = strtotime("2016-10-01");
$end = strtotime("2016-11-05");
$interval = 1; //in days
for ($i = $start; $i<=$end; $i = $i + strtotime("+".$interval." days", $i)){
echo Date("Y-m-d, H:i:s", $i). ' = '. $i . '<br/>';
}
This question already has answers here:
Print time in 15-minute increments between two times in the same day
(10 answers)
Closed 9 years ago.
I've spent so much time on trying to figure out how to create a loop that will echo time between given $start_time and $end_time incrementing it by one hour in format HH:MM.
For example if i have $start_time = "09:00" and $end_time="15:00" the output should be like:
09:00
10:00
11:00
12:00
13:00
14:00
15:00
Any idea how to do it? I know i should use php timestamps and strtotime etc. by i have never used them, so i can't do anything, pls help...
You can do it with mktime()
$start = 7;
$end = 15;
for ($time = $start; $time <= $end; $time++) {
echo date("H:00", mktime($time+1)).'<br>';
}
EDIT:
Just for fun, here is another example
foreach(range(intval('07:00:00'),intval('16:00:00')) as $time) {
echo date("H:00", mktime($time+1)).'<br>';
}
$interval = date_interval_create_from_date_string('1 hour');
$begin = date_create('09:00');
$end = date_create('15:00')->add($interval);
foreach (new DatePeriod($begin, $interval, $end) as $dt) {
echo $dt->format('H:i') . "\n";
}
Demos:
https://eval.in/56289
https://eval.in/56291
https://eval.in/56292
If you just want to echo the times you can do something simple like this:
$start_time = 9;
$end_time = 15;
for ($time = $start_time; $time <= $end_time; $time++) {
if ($time < 10)
echo "0";
echo $time . ":00\n";
}
$start_time = "15:49";
$hours = 9;
list($h, $m) = explode(':', $start_time);
while ($hours-->0)
{
echo $h++ . ":" . $m . "\n";
}
Its been awhile since I've coded PHP but look at this link.
Note I posted this before the Question was edited.
while($starttime < $endtime)
{
echo $starttime;
$starttime = date_add($starttime, date_interval_create_from_date_string('1 hour'));
}
I'd like display dates by week number between giving 2 dates like example below. Is this possible in PHP?
if the dates are 2010-12-01 thru 2010-12-19, it will display it as follows.
week-1
2010-12-01
2010-12-02
2010-12-03
2010-12-04
2010-12-05
2010-12-06
2010-12-07
week-2
2010-12-08
2010-12-09
2010-12-10
2010-12-11
2010-12-12
2010-12-13
2010-12-14
week-3
2010-12-15
2010-12-16
2010-12-17
2010-12-18
2010-12-19
and so on...
I use mysql. It has startdate end enddate fields.
thank you in advance.
I can get how many weeks in those giving 2 dates and display them using a
datediff('ww', '2010-12-01', '2010-12-19', false); I found on the internet.
And I can display dates between two dates as follows. But I am having trouble grouping them by week.
$sdate = "2010-12-01";
$edate = "2010-12-19";
$days = getDaysInBetween($sdate, $edate);
foreach ($days as $val)
{
echo $val;
}
function getDaysInBetween($start, $end) {
// Vars
$day = 86400; // Day in seconds
$format = 'Y-m-d'; // Output format (see PHP date funciton)
$sTime = strtotime($start); // Start as time
$eTime = strtotime($end); // End as time
$numDays = round(($eTime - $sTime) / $day) + 1;
$days = array();
// Get days
for ($d = 0; $d < $numDays; $d++) {
$days[] = date($format, ($sTime + ($d * $day)));
}
// Return days
return $days;
}
New answer.
$current_date = strtotime('2010-12-01');
$end_date = strtotime('2010-12-19');
$day_count = 0;
$current_week = null;
do {
if ((int)($day_count / 7) + 1 != $current_week) {
$current_week = (int)($day_count / 7) + 1;
echo 'week-'.$current_week.'<br />';
}
echo date('Y-m-d', $current_date).'<br />';
$current_date = strtotime('+1 day', $current_date);
$day_count ++;
} while ($current_date <= $end_date);
You will definitely need this: Simplest way to increment a date in PHP?. Write a forloop and increment the day every time. You will also need the DateTime class and functions as date. Indeed asking for date('W', yourDateHere) is a nice idea.
You will get something like this (pseudocode)
$startDate;
$endDate;
$nrOfDays = dateDiffInDays($endDate, $startDate);
$currentWeek = date('W',$startDate);
for($i = 0; $i < $nrOfDays; $i++)
{
$newDay = date('+$i day', $startDate); // get the incremented day
$newWeek = date('W', $newDay); // get the week of the new day
if($newWeek != $currentWeek) // check if we must print the new week, or if we are still in the current
print $newWeek;
print $newDay; // print the day
}
Hope this helps. Good luck.
Tools sufficient to do the job:
strtotime('2010-11-23') - to get a timestamp from a date
strtotime('+1 day', $someTimestamp) - to get the next day
date('W', $someTimestamp) - to get the week number (if you want to group by ISO week number)
array_chunk($orderedListOfSuccessiveDates, 7) - to split in groups of seven days (if you don't want to group by ISO week number)
Warning: Never, ever increment days by adding 86400 to the timestamp! That is the easiest way to break everything when Daylight Saving comes along. Either use the strtotime function or the DateTime class.
Here you go. Although this is with weeks starting on sundays (just change it to monday if need be). And it doesnt work if the dates arent in the same year. But it should be pretty easy to fix that. If not_same_year then ...
$start_date = mktime(0, 0, 0, 12, 01, 2010);
$start_date_week_number = (int) date("W", $start_date);
$end_date = mktime(0, 0, 0, 12, 19, 2010);
$end_date_week_number = (int) date("W", $end_date);
$n = $start_date_week_number;
$w = 1;
$date = $start_date;
while($n <= $end_date_week_number) {
echo("<strong>Week " . $w . "</strong><br />");
$s = 0;
$e = 6;
if($n == $start_date_week_number) $s = (int) date("w", $start_date);
elseif($n == $end_date_week_number) $e = (int) date("w", $end_date);
while($s <= $e) {
echo(date("j-m-y", $date) . "<br />");
$c_date = getdate($date);
$date = mktime($c_date['hours'], $c_date['minutes'], $c_date['seconds'], $c_date['mon'], $c_date['mday'] + 1, $c_date['year']);
$s++;
}
$n++; $w++;
}
DEMO HERE
Edit: just fixed it when I realized you wanted to count the weeks (not get the actual week number)...
$startDate = new DateTime('2010-01-01');
$endDate = new DateTime('2010-01-14');
$weeksDays = getWeeksDaysBetween($startDate, $endDate);
foreach($weeksDays as $week => $days)
{
echo "Week $week<ul>";
foreach($days as $day){
echo "<li>$day</li>";
}
echo "</ul>";
}
function getWeeksDaysBetween($startDate, $endDate)
{
$weeksDays = array();
$dateDiff = $endDate->diff($startDate);
$fullDays = $dateDiff->d;
$numWeeks = floor($fullDays / 7) + 1;
$weeksDays[1][] = $startDate->format('Y-m-d');
for ($i = 1; $i <= $fullDays; $i++)
{
$weekNum = floor($i / 7) + 1;
$dateInterval = DateInterval::createFromDateString("1 day");
$weeksDays[$weekNum][] = $startDate->add($dateInterval)->format('Y-m-d');
}
return $weeksDays;
}
I am trying to create an array starting with today and going back the last 30 days with PHP and I am having trouble. I can estimate but I don’t know a good way of doing it and taking into account the number of days in the previous month etc. Does anyone have a good solution? I can’t get close but I need to make sure it is 100% accurate.
Try this:
<?php
$d = array();
for($i = 0; $i < 30; $i++)
$d[] = date("d", strtotime('-'. $i .' days'));
?>
Here is advance latest snippet for the same,
$today = new DateTime(); // today
$begin = $today->sub(new DateInterval('P30D')); //created 30 days interval back
$end = new DateTime();
$end = $end->modify('+1 day'); // interval generates upto last day
$interval = new DateInterval('P1D'); // 1d interval range
$daterange = new DatePeriod($begin, $interval, $end); // it always runs forwards in date
foreach ($daterange as $date) { // date object
$d[] = $date->format("Y-m-d"); // your date
}
print_r($d);
Working demo.
Official doc.
For those who want to show sales of the past X days,
As asked in this closed question (https://stackoverflow.com/questions/11193191/how-to-get-last-7-days-using-php#=), this worked for me.
$sales = Sale::find_all();//the sales object or array
for($i=0; $i<7; $i++){
$sale_sum = 0; //sum of sale initial
if($i==0){
$day = strtotime("today");
} else {
$day = strtotime("$i days ago");
}
$thisDayInWords = strftime("%A", $day);
foreach($sales as $sale){
$date = strtotime($sale->date_of_sale)); //May 30th 2018 10:00:00 AM
$dateInWords = strftime("%A", $date);
if($dateInWords == $thisDayInWords){
$sale_sum += $sale->total_sale;//add only sales of this date... or whatever
}
}
//display the results of each day's sale
echo $thisDayInWords."-".$sale_sum; ?>
}
Before you get angry:
I placed this answer here to help someone who was directed here from that question. Couldn't answer there :(
You can use time to control the days:
for ($i = 0; $i < 30; $i++)
{
$timestamp = time();
$tm = 86400 * $i; // 60 * 60 * 24 = 86400 = 1 day in seconds
$tm = $timestamp - $tm;
$the_date = date("m/d/Y", $tm);
}
Now, within the for loop you can use the $the_date variable for whatever purposes you might want to. :-)
$d = array();
for($i = 0; $i < 30; $i++)
array_unshift($d,strtotime('-'. $i .' days'));