I have a small script that depending on the time and day; I would like it to output different things:
<?php
$currenttime = ((date("H")+7). ":" .date("i"));
if ($currenttime >= "16:30") {
$tomorrow = mktime(0, 0, 0, date("m") , date("d")+2, date("Y"));
$jsdate = (date("Y"). "-" .date("m"). "-" .(date("d")+1). "-16-30");
}
else{
$tomorrow = mktime(0, 0, 0, date("m") , date("d")+1, date("Y"));
$jsdate = (date("Y"). "-" .date("m"). "-" .date("d"). "-16-30");
}
echo " Time left for delivery on <b><center>" .date("l \\t\h\e jS F", $tomorrow). "</b>:</center>";
?>
<center>
<script>
// deadline(date, width, height, style, background, number color, small text color);
deadline("<? echo $jsdate; ?>", "220", "37", "digital2", "#FFFFFF", "#000099", "#000000");
</script>
</center>
For instance on a Monday before 16:30 it would need the following:
Time left for delivery on Tuesday the {date} of {month}
Then display how long left until 16:30 in DD HH MM SS format(Preferable to be servertime rather than users local time.)
Then after 16:30 on a Monday it would need to read:
Time left for delivery on Wednesday the {date} of {month}
Then display how long left until
16:30 in DD HH MM SS
format(Preferable to be servertime
rather than users local time.)
Then from 16:30 on Thursday until Monday 16:30 it would need to read:
Time left for delivery on Tuesday the {date} of {month}
Then display how long left until
16:30 in DD HH MM SS
format(Preferable to be servertime
rather than users local time.)
I hope this all make sense and thanks for looking.
Ta,
B.
You can use strtotime and the (php 5.3+) class DateTime to create, compare and format the timestamps and intervals.
e.g. (neither really tested nor exactly in the format you've described):
<?php
$now = new DateTime();
$deliveries = array(
'monday' => strtotime('monday 16:30'),
'tuesday' => strtotime('tuesday 16:30')
);
// timestamps in the past are "advanced" one week
foreach($deliveries as &$dt) {
if ( $dt < $now->getTimestamp() ) {
$dt = strtotime('+1 week', $dt);
}
}
// get the diff between 'Now' and the next delivery (smallest timestamp in $deliveries)
$nextDelivery = new DateTime();
$nextDelivery->setTimestamp( min($deliveries) );
$remaining = $nextDelivery->diff($now);
echo $nextDelivery->format(DateTime::RFC2822), " | ", $remaining->format('%d days %H:%i:%S'), "\n";
edit: without using DateTime:
<?php
$now = time();
$deliveries = array(
'monday' => strtotime('monday 16:30', $now),
'tuesday' => strtotime('tuesday 16:30', $now)
);
// timestamps in the past are "advanced" one week
foreach($deliveries as &$dt) {
if ( $dt < $now) {
$dt = strtotime('+1 week', $dt);
}
}
// get the diff between 'Now' and the next delivery (smallest timestamp in $deliveries)
$nextDelivery = min($deliveries);
// (when) a day has exactly 86400 seconds, an hour 3600 seconds, ...
$remaining = array(
'days'=> intval(($nextDelivery - $now) / 86400),
'hours'=> intval( ($nextDelivery - $now) / 3600) % 24,
'minutes'=> intval( ($nextDelivery - $now) / 60) % 60,
'seconds'=> ($nextDelivery - $now) % 60
);
echo 'next: ', date(DateTime::RFC2822, $nextDelivery), "\n";
printf('remaining: %d days %02d:%02d:%02d',
$remaining['days'], $remaining['hours'], $remaining['minutes'], $remaining['seconds']);
No fix for your program, but this line
$jsdate = (date("Y"). "-" .date("m"). "-" .date("d"). "-16-30");
could just as easy be
$jsdate = date("Y-m-d-16-30");
It's a lot more readable.
Related
For example
02-11-2018 03:00pm - 05-11-2018 11:00am should be 2hrs.
Because 3rd and 4th are weekends.
$date1 = "2018-03-01 11:12:45";
$date2 = "2018-03-04 15:37:04";
$date1Timestamp = strtotime($date1);
$date2Timestamp = strtotime($date2);
$difference = $date2Timestamp - $date1Timestamp;
echo $difference;
You can use mktime() to create UNIX timestamps for the two date/times you want to compare. These timestamps will represent the number of seconds between the Unix Epoch (January 1 1970 00:00:00 GMT) and the time specified. Since they will both be in seconds, it makes it very easy to calculate the seconds between the two timestamps:
<?php
//set start time and end time - mktime(hour, minute, second, month, day, year)
$startTime = mktime(15, 0, 0, 11, 2, 2018); // 2-11-2018 3:00PM
$endTime = mktime(11, 0, 0, 11, 5, 2018); // 5-11-2018 11:00AM
//calculate total number of seconds between two date/times
$totalSeconds = $endTime - $startTime;
//apply whatever other math you need...
?>
As far as accounting for weekends and business hours, you will need to get creative with determining how many weekend days exist between the two date/times and what hours fall within business hours on business days. The PHP manual for date functions will come in handy. The following code produces the results you are looking for:
<?php
//set business start and end hours
$businessStartHour = 10; //10 AM
$businessEndHour = 16; //4 PM
//set weekend days
$arrWeekendDays = array(6,0); //numeric representations of Saturday (6) and Sunday (0)
//set start and end dates and times
//2-11-2018 3 PM
$startHour = 15;
$startMinute = 0;
$startSecond = 0;
$startMonth = 11;
$startDay = 2;
$startYear = 2018;
//5-11-2018 11 AM
$endHour = 11;
$endMinute = 0;
$endSecond = 0;
$endMonth = 11;
$endDay = 5;
$endYear = 2018;
//create UNIX timestamps
$startTime = mktime($startHour, $startMinute, $startSecond, $startMonth, $startDay, $startYear);
$endTime = mktime($endHour, $endMinute, $endSecond, $endMonth, $endDay, $endYear);
//ensure $endTime is greater than $startTime
if($startTime >= $endTime){
//invalid start and end datetimes
die("Invalid start and end datetimes.");
}
//calculate eligible seconds from partial time on first and last day
$totalSeconds = 0;
$currentTime = mktime(0, 0, 0, $startMonth, $startDay, $startYear); //beginning of $startTime day
$lastFullDay = mktime(0, 0, 0, $endMonth, $endDay, $endYear); //beginning of $endTime day
$startingBusinessTime = mktime($businessStartHour, 0, 0, $startMonth, $startDay, $startYear);
$endingBusinessTime = mktime($businessEndHour, 0, 0, $endMonth, $endDay, $endYear);
if($startTime < $startingBusinessTime){
$startTime = $startingBusinessTime;
}
if($endTime > $endingBusinessTime){
$endTime = $endingBusinessTime;
}
if($currentTime == $lastFullDay){
//$startTime and $endTime occur on the same day
if($endTime > $startTime){
$totalSeconds += ($endTime - $startTime);
}
}else{
//$startTime and $endTime do not occur on the same day
$startingBusinessTime = mktime($businessStartHour, 0, 0, $endMonth, $endDay, $endYear);
$endingBusinessTime = mktime($businessEndHour, 0, 0, $startMonth, $startDay, $startYear);
if($endingBusinessTime > $startTime){
$totalSeconds += ($endingBusinessTime - $startTime);
}
if($endTime > $startingBusinessTime){
$totalSeconds += ($endTime - $startingBusinessTime);
}
}
//calculate eligible seconds from all full days in between start day and end day
$fullDayBusinessSeconds = (($businessEndHour - $businessStartHour) * 3600);
//set $currentTime to beginning of first full day
$nextDay = $currentTime + (26 * 3600); //add 26 hours to $currentTime to get into the next day, compensating for possible daylight savings
$currentTime = mktime(0, 0, 0, date('n', $nextDay), date('j', $nextDay), date('Y', $nextDay));
while($currentTime < $lastFullDay){
//determine if $currentTime is a weekday
if(!in_array(date('w', $currentTime), $arrWeekendDays)){
//it's a business day, add all business seconds to $totalSeconds
$totalSeconds += $fullDayBusinessSeconds;
}
//increment $currentTime to beginning of next day
$nextDay = $currentTime + (26 * 3600); //add 26 hours to $currentTime to get into the next day, compensating for possible daylight savings
$currentTime = mktime(0, 0, 0, date('n', $nextDay), date('j', $nextDay), date('Y', $nextDay));
}
echo "Total eligible time between start time and end time: " . $totalSeconds . " seconds (" . convertSecToTime($totalSeconds) . ")";
function convertSecToTime($sec)
{
$date1 = new DateTime("#0");
$date2 = new DateTime("#$sec");
$interval = date_diff($date1, $date2);
return $interval->format('%y Years, %m months, %d days, %h hours, %i minutes and %s seconds');
// convert into Days, Hours, Minutes
// return $interval->format('%a days, %h hours, %i minutes and %s seconds');
}
?>
Kindly have a look at this precise php function returning days count with weekends excluded.
$start= "2018-03-01 11:12:45";
$end= "2018-04-01 15:37:04";
echo Count_Days_Without_Weekends($start, $end);
function Count_Days_Without_Weekends($start, $end){
$days_diff = floor(((abs(strtotime($end) - strtotime($start))) / (60*60*24)));
$run_days=0;
for($i=0; $i<=$days_diff; $i++){
$newdays = $i-$days_diff;
$futuredate = strtotime("$newdays days");
$mydate = date("F d, Y", $futuredate);
$today = date("D", strtotime($mydate));
if(($today != "Sat") && ($today != "Sun")){
$run_days++;
}
}
return $run_days;
}
Try it out, it really works..
I am making a page to let the clients choose a date for an appointment, so I need to build a list of the dates like this :
always begin from tomorrow, end by 6 months
always from Mondy to Saturday, no Sunday
the day of the week need to be in chinese, like "Monday" is "星期一", but the timezone is in France
Here is the php
date_default_timezone_set('Europe/Paris');
$tomorrow = date("Y年m月d日 l", time() + 86400);
$end = date("Y年m月d日 l", time() + 86400 * 7); // just 7 days for a try
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($tomorrow, $interval, $end);
foreach ($daterange as $date) {
echo $date . '<br/>';
}
This code is not working.
I need to build an array, which store all the dates of next 6 months, begin from tomorrow, without Sunday, the days need to be in chinese and the timezone needs to be in Europe, is that possible?
I think strtotime and array_push is what you are looking for. Try this:
$curDate = date('Y-m-d', strtotime('+1 day'));
$endDate = date('Y-m-d', strtotime('+6 months +1 day'));
$myArr = array();
while ($endDate >= $curDate) {
if (date('w', strtotime($curDate)) !== '0') array_push($myArr, $curDate);
$curDate = date('Y-m-d', strtotime($curDate . " +1 days"));
}
var_dump($myArr);
For the Options, create an array from sunday to saturday.
$weekdays = array('Sunday', ..., 'Saturday');
echo date('Y/m/d', strtotime($curDate)) . ' ' . $weekdays[date('w', strtotime($curDate))];
I have a dynamic date, now what i want is that finding the date after exact one week, i have achieved that with the code below, but now i want that now many days are left for that week after date to come. i have got some sort of time stamp, but i don't know how to convert it to DAYS LEFT.
$weekDate = date( "d/m/Y", strtotime("19-05-2014") + 86400 * 7 );
echo $weekDate;// THATS PERFECT
////////////////////////////////////////////////////////////////
$future = strtotime( $weekDate ); //Future date.
$datediff = time() - $future;
$days = floor( ( ( $datediff / 24 ) / 60 ) / 60 ); //this is not perfect, returns some
sort of timestamp
I have tried other methods which are fine, but if week completes on 26, and today is 25th it gives me 0 days left, but it should say 1 day left. please help me.
In your $date_diff now is less than the future date thats why its zero. Inside strtotime() function, you can directly put a relative date inside. In this case, for one week you can use +1 week or +7 days. Consider this example:
$next_week = date('d/m/Y', strtotime('19-05-2014 +1 week')); // 26/05/2014
$next_week = strtotime('19-05-2014 +7 days');
$difference = $next_week - time(); // next weeks date minus todays date
$difference = date('j', $difference);
echo $difference . (($difference > 1) ? ' days ' : ' day ') . ' left';
// should output: 1 day left
Alright. I did something. Here's the code
$startDate = strtotime("19-05-2014");
$endDate = $startDate + 604800;
$diff = ($endDate - time()) / 60 / 60 / 24;
if ($diff < 1 && $diff > 0) {
$days = 1;
} else {
$days = floor($diff);
}
echo $days;
The problem you have with getting "1 day" if the date is tomorrow is the floor method. strtotime() gives you the time at 0 a.m. if you don't set it by your own. Because of that the difference between now and tomorrow is less than 1 which is 0 if you floor that. I created an if-clause for that.
But that will give you "1 day" for today and "1 day" for yesterday (last 2 days before the final date). If you want that better, you have to specify time in your initial date (19-05-2014).
Use DateTime for date and time calculations.
$weekDate = new \DateTime('+ 1 week');
$future = new \DateTime('+ 3 days');
$daysLeft = $weekDate->diff($future)->days;
echo $daysLeft; //4
See it working.
Reference http://php.net/datetime
How can I get the first week day in a given week number?
I'm making a function in PHP for a calendar app.
The idea: When I click on a link that basically uses strtotime with +1 month it only jumps to that same day of course. I need to get the week numbers correct.
Example: When I use the menu to move from August to September, it shouldn't select the same date I was in in August, but the first day of the first week number in September (Monday, 2th of September, week number 36).
And from September to October: Week number 40, Tuesday the 1th of October.
I found a function that exactly like you want it. This is setISODate
$date = new DateTime();
$date->setISODate(2013, 35, 1);
echo $date->format('Y-m-d');
You can change Y-m-d date format as you want
Output
2013-08-26 // This week number and monday
Usage
setISODate(year, week, day)
Try this code
<?php
$week = 3;
$year = 2009;
$timestamp = mktime( 0, 0, 0, 1, 1, $year ) + ( $week * 7 * 24 * 60 * 60 );
$timestamp_for_monday = $timestamp - 86400 * ( date( 'N', $timestamp ) - 1 );
$date_for_monday = date( 'Y-m-d', $timestamp_for_monday );
?>
Like every1 already said, ISO weeks start with monday. Quote from http://en.wikipedia.org/wiki/ISO_week_date : Weeks start with Monday.
If I understand your problem correctly, you need first-next-date in next month if selected week is in 2 different months?
function getFirstWeekDay($year, $week) {
$dt = (new DateTime)->setISODate($year, $week, 1);
$dtC = clone $dt;
for ($N = $dt->format('N'); $N < 7; $N++) {
$dtC->modify('+1 day');
if ($dt->format('m') !== $dtC->format('m')) {
return $dtC;
}
}
return $dt;
}
echo getFirstWeekDay(2013, 40)->format('W\t\h \w\e\e\k \i\s Y-m-d');
# 40th week is 2013-10-01
echo getFirstWeekDay(2013, 1)->format('W\t\h \w\e\e\k \i\s Y-m-d');
# 1th week is 2013-01-01
how can I find the next closest hour in php
so for example if current time is 4:15 the next hour will be 5, etc
$dateString = 'Tue, 13 Mar 2012 04:48:34 -0400';
$date = new DateTime( $dateString );
echo $date->format( 'H:i:s' );
gives me the time from the string and I want to expand on that and get the next closest hour
$nextHour = (intval($date->format('H'))+1) % 24;
echo $nextHour; // 5
Here we go:
<?php
echo date("H:00",strtotime($date. " + 1hour "));
?>
Can you just take pieces (hours, minutes, seconds) and get the next hour?
$dateString = 'Tue, 13 Mar 2012 04:48:34 -0400';
$date = new DateTime( $dateString );
echo $date->format( 'H:i:s' );
echo "\n";
$nexthour = ($date->format('H') + ($date->format('i') > 0 || $date->format('s') > 0 ? 1 : 0)) % 24;
echo "$nexthour:00:00";
Supply any eligible date() to:
function roundToNextHour($dateString) {
$date = new DateTime($dateString);
$minutes = $date->format('i');
if ($minutes > 0) {
$date->modify("+1 hour");
$date->modify('-'.$minutes.' minutes');
}
return $date;
}
<?php
$dateString = 'Tue, 13 Mar 2012 04:48:34 -0400';
$date = new DateTime( $dateString );
$date->modify('+1 hour');
echo $date->format('H:i:s').PHP_EOL;
// OR
echo date('H:i:s', strtotime($dateString) + 60 * 60).PHP_EOL;
As I just needed something similar (next full hour) here my solution:
$now = time();
$nextFullHour = date(DATE_ATOM, $now + (3600 - $now % 3600));
By replacing the 3600 e.g. with 60 you get the next full minute...
You can also replace the $now with any other timestamp if you do not need it relative to the current time.
That is my solution:
$dateTime = new \DateTime();
$dateTime->add(new \DateInterval('PT1H'))
->setTime($dateTime->format('H'), '00');
Nobody else used this one so I figured I'd drop it here, simplest one I saw above for an actual timestamp, not just the hour itself.
$now = ''; // empty uses current time, or you can insert a datetime string
$next_hour = date( 'Y-m-d H:00:00', strtotime( $now . ' +1 hour' ) );
try it for current time, if you need put second argument to date function
<?php echo date('H')+1; ?>
very nice stuff
One more:
$current_datetime = new DateTimeImmutable();
$next_full_hour_datetime = $current_datetime
->modify(
sprintf(
'+%d seconds',
3600 - ($current_datetime->getTimestamp() % 3600)
)
);
A little late to this party, but here's a more flexible function to round up a dateTime object by any interval in minutes. You pass in your dateTime object and a rounding interval in minutes, so for an hour you'd just pass in 60, etc.
public function round_up_time( $datetime, $rounding_interval ) {
// get total minutes from the start of the day
$minutes = ( intval( $datetime->format( 'H' ) ) * 60 ) + ( intval( $datetime->format( 'i' ) ) );
// round up the minutes based on the interval we are rounding to
$rounded_minutes = ( intval( $minutes / $rounding_interval ) + 1 ) * $rounding_interval;
// reset our dateTime to the very start of the day
$datetime->setTime( 0, 0 );
// then increase the dateTime by the rounded minutes value
$datetime->modify( '+ ' . $rounded_minutes . ' minutes' );
}
To get the next closest full hour in DateTime:
$date = new DateTime('+1 hour'); //set the next hour
$date->setTime($date->format('H'), '00', '00'); //keep the next hour, set minutes to 00 and seconds to 00