Add weeks in decimal value in php - php

I am trying to add weeks in decimal values like 1.5, 2.5 to date through strtotime() function. But its not giving correct result. I am using it like:
$start_date = "2015-01-01";
$date = strtotime(date("Y-m-d", strtotime($start_date)) . " +3.5 weeks");
$date = date("Y-m-d",$date);
echo $date;
And its giving 2015-02-04 as output. When added non decimal values like:
$date = strtotime(date("Y-m-d", strtotime($start_date)) . " +3 weeks");
It gives perfect results.
Any thought on it?

$date = '2015-01-01';
$weeks = "2,3,4,4.5";
foreach(explode(",", $weeks) as $week) {
print $week."\n";
$hours = $week * 24 * 7;
print $hours."\n";
print date("Y-m-d", strtotime("{$date} +{$hours} hours"))."\n";
}

You can use this logic, multiply your week decimal or not like 1,2,2.5,3,3.5 and multiply it by the amount of hours in a week :
$week = 2.5;
$desired = '+ '.$week*168.' hours';
$date = strtotime($desired, $start_date);
However, why playing with strings when you can just play with hours or seconds integers and doing a simple addition ?

Related

How to sum hours with existing datetime in PHP?

I have two fields which store data like 2018-03-26 11:20:35 and 02:25:10(2 hours 25 minutes and 10 seconds) first data is date and time. second one is only time. I want to sum it and finally my result should 2018-03-26 13:45:45
How to do that in php code?
I have tried this way:
<?php
$date = '2018-03-26 11:20:35';
//echo $date;
//echo "<br>";
$hours = '02:25:10'; /* this data dynamic */
$sumTime = strtotime($date) + strtotime($hours);
$new_time = date("Y-m-d H:i:s", $sumTime);
echo $new_time;
Output:
Warning: date() expects parameter 2 to be integer, float given in C:\my-project-path\test.php on line 7
Here's a simple solution, some checks are skipped:
// convert your date to DateTime object
$date = '2018-03-26 11:20:35';
$dt = new DateTime($date);
// convert your period to DateInterval
$hours = '02:25:10'; /* this data dynamic */
$parts = explode(':', $hours);
$interval = new DateInterval('PT' . (int)$parts[0] . 'H' . $parts[1] . 'M' . $parts[2] . 'S');
// Add interval to date
$dt->add($interval);
// Format date as you need
echo $dt->format('Y-m-d H:i:s');
You could create a duration in seconds by comparing today at "00:00:00" and today at $hours. Actually, strtotime($hours) returns the timestamp of today at $hours, so, the addition of the two timestamp don't give the expected result.
If $hours is lesser than 24 hours, you could use:
$date = '2018-03-26 11:20:35';
$hours = '02:25:10';
$d0 = strtotime(date('Y-m-d 00:00:00'));
$d1 = strtotime(date('Y-m-d ').$hours);
$sumTime = strtotime($date) + ($d1 - $d0);
$new_time = date("Y-m-d H:i:s", $sumTime);
echo $new_time;
Outputs:
2018-03-26 13:45:45
You should check DateTime::add:
http://php.net/manual/en/datetime.add.php
http://php.net/manual/en/datetime.examples-arithmetic.php
Example:
<?php
// Convert h:m:s format to PThHmMsS format
sscanf('02:25:10', '%d:%d:%d', $hour, $minute, $second);
$intervalSpec = sprintf('PT%dH%dM%dS', $hour, $minute, $second);
$datetime = new DateTimeImmutable('2018-03-26 11:20:35');
$newDatetime = $datetime->add (new DateInterval($intervalSpec));
echo $newDatetime->format(DateTime::W3C);
It could be done with some simple string manipulation:
$dt = new DateTime("$date UTC");
$modify = preg_replace('/:/', ' hours ', $hours, 1);
$modify = preg_replace('/:/', ' minutes ', $modify, 1);
$modify .= ' seconds';
$dt->modify($modify);
demo
If you have MySQL as your data storage, you could do:
DATE_ADD(field1, INTERVAL field2 HOUR_SECOND)
demo
you can do something like:
$hour = $hours->format('H'); //This way you get a string which contains the hours
$date->modify('+'.$hour.' hour'); //you modify your date adding the hours
I'm assuming you only need the hours, and not minutes and seconds
EDIT:
you can do like that using regexp
$date = new \DateTime('2018-03-26 11:20:35');
$hours ='02:25:10';
preg_match("/^([0-9].*):([0-9].*):([0-9].*)/",$hours,$matches);
$date->modify('+'.$matches[1].' hour');
$date->modify('+'.$matches[2].' minute');
echo $date->modify('+'.$matches[3].' second')->format('Y-m-d H:i:s');

Comparing datetimes in php

I am comparing a date with a datetime and I get the result I expect however I also am wondering if there is a better way to display my output and I have a query on my current output also.
Here is a snippet of my current code:
<?php
$todayDate = date('Y-m-d');
$seconds = strtotime($todayDate) - strtotime($dueDate);
$hours = $seconds / 60 / 60;
echo number_format($hours, 2);
?>
in my case $dueDate in my database here is 2017-06-26 09:11:28 so the output is displaying as -57.19. My question, is there is a clean way to strip the - and also add h after the hours and m after the minutes so the output looks like this?
57h 19m
UPDATE
So After tinkering around I have managed to do this:
substr($dateFormat,0,3).'h '.substr($dateFormat,4).'m';
The output now is -57h 19m
I still have this negative character, im not sure if that is actually correct I cannot seem to work it out because the date in my database is a day ahead but it shows a negative value...
Using the DateTime class makes it very simple
$dueDate = '2017-06-26 09:11:28';
$due = DateTime::createFromFormat('Y-m-d H:i:s', $dueDate);
$today = new DateTime();
$diff = $today->diff($due);
echo $diff->format('%hh %im');
Result:
11h 37m
But as you asked about timezones, here is how to add those in as well. And also as you orignial date was in fact some days distant I added a more accurate difference output
$dueDate = '2017-06-25 00:00:00';
$due = DateTime::createFromFormat('Y-m-d H:i:s', $dueDate, new DateTimeZone('Europe/London'));
$today = new DateTime('now', new DateTimeZone('Europe/London'));
$diff = $today->diff($due);
echo $diff->format('%R %hh %im').PHP_EOL;
if ( $diff->invert ) {
echo $diff->format('Overdue by %dd %hh %im');
} else {
echo $diff->format('You have %dd %hh %im till overdue');
}
Results
+ 1h 6m
You have 0d 1h 6m till overdue
You need to keep date integer
$time = time();
after
you can use this every where and evert way
For example
$date1 = time();
$date2 = time();
$comparingdate = $date2 - $date1;
$myFormat = date("T-m-d h:i:s",$comparingdate); // Show how you want
use floor and round functions to get the minutes and hours after convert the date to positive sign using abs function
<?php
$todayDate = date('Y-m-d');
$dueDate = "2017-06-26 09:11:28";
$seconds =abs(strtotime($todayDate) - strtotime($dueDate));
$hours =floor($seconds / 60 / 60);
$minutes= round($seconds / 60 / 60 - $hours,2)*100;
echo "<br>";
echo $hours. " H :";
echo $minutes. " M ";
?>

PHP date calculate date between two day

I want to get number of weekends and number of bussiness day by I know only $startDate and $endDate, Is have any PHP's function that can calculate automatic ?
This is my code :
$endDate = strtotime($endDate);
$startDate = strtotime($startDate);
echo $days = ($endDate - $startDate) / 86400 + 1;
My code will return how many day, and how I need more is what day ?
How I can get it?
Example:
startDate:`2014-11-17`
endDate:`2014-11-19`
I want this Output:
it's 3 day
2014-11-17 is Monday
2014-11-18 is Tueday
2014-11-19 is Wendnesday
How about...
for ($time = $startDate; $time <= $endDate; $time += 86400) {
echo date('Y-m-d \i\s l', $time) . '<br>';
}
This might help you, or at least may give you some clue
$endDate = strtotime($endDate);
$startDate = strtotime($startDate);
echo $days = ($endDate - $startDate) / 86400 + 1;
$time = $startDate;
while ($time <= $endDate) {
echo date('Y-m-d', $time) . ' is ' . date('l', $time);
$time += 86400;
}
if ($time != $endDate) {
echo date('Y-m-d', $time) . ' is ' . date('l', $time);
}
This should work for you:
<?php
$startDate = strtotime("2014-11-17");
$endDate = strtotime("2014-11-19");
echo "It's " . $days = ($endDate - $startDate) / 86400 + 1 . " days";
for($count = 0; $count < $days; $count++)
echo "<br />" . date('Y-m-d', strtotime('+' . $count . ' day', $startDate)) . ' is ' . date('l', strtotime('+' . $count . ' day', $startDate));
?>
Output:
It's 3 days
2014-11-17 is Monday
2014-11-18 is Tuesday
2014-11-19 is Wednesday
There's no built-in. Excel has NETWORKDAYS(), but in PHP you must roll your own.
There is a PHP solution at Day difference without weekends
Note its limitations in the comments there e.g. if a public holiday falls on a weekend day.
The following page describes an alternative implementation of NETWORKDAYS(): http://www.cpearson.com/excel/betternetworkdays.aspx
It's not PHP but it demonstrates the logic.
Unfortunately there is no shortcut other than looping through each day in the period and deciding whether or not to count it. You need to accept arguments for (or hard-code) the weekend days and the dates of any public holidays (if you are excluding public holidays).
If you are doing this frequently and for long periods, you might pre-compute and cache the number of business days for each calendar month and year; then, at run-time, you look up the number of days in each whole year within the period, then the remaining whole months, then do the ordinary loop for the remaining days at the start and end of the period.
EDIT: If you just want to exclude weekends (not public holidays), then you can calculate 5 days for each whole week in the period, and then calculate any remaining days: https://github.com/bgarlock/scripts/blob/master/PHP%20Equivalent%20of%20MS%20Excel%20NETWORKDAYS%20function.php
Please find below code I am sure it works for you
NOTE : Parameter passed P1D is denoting 1 Day difference same way you can pass P1M for 1 month P1W for 1 week and P1Y for 1 Year.
$date1 = '29/08/2013';
$date2 = '03/09/2013';
function returnDates($fromdate, $todate) {
$fromdate = \DateTime::createFromFormat('d/m/Y', $fromdate);
$todate = \DateTime::createFromFormat('d/m/Y', $todate);
return new \DatePeriod(
$fromdate,
new \DateInterval('P1D'),
$todate->modify('+1 day')
);
}
$datePeriod = returnDates($date1, $date2);
foreach($datePeriod as $date) {
echo $date->format('d/m/Y'), PHP_EOL; //you can set any date format here
}

Correct way to add days

I've tried to add 7 days to 2013-10-26 and got back 2013-11-01. But it have to be 2013-11-02. My old function was something like this:
public static function add($date, $years = 0, $months = 0, $days = 0)
{
$date = explode('-', $date);
return date(
'Y-m-d',
mktime(0, 0, 0, $date[1] + $months, $date[2] + $days, $date[0] + $years)
);
}
This was correct but too slow. I've made a new one that is more specialized:
public static function adddays($date, $days = 1)
{
if ($days == 0) return $date;
return date('Y-m-d', strtotime($date) + 86400 * $days);
}
It works mostly correct. Not in this case. If you let calculate strtotime('2013-10-26') % 86400 then you will find out it is 10p.m. and for some reason it makes a difference.
I'm working with version 5.3.2.
Speed test:
Repeated 1000 runs for the 3 versions
DateTime : +7 day : strtotime
26ms : 43ms : 41ms
30ms : 44ms : 42ms
25ms : 42ms : 43ms
30ms : 48ms : 49ms
So more lines and a faster result. I choose DateTime of Amal.
$date = new DateTime('2013-10-26');
$days_to_add = 7;
$date->add(new DateInterval('P' . $days_to_add . 'D'));
$date->format('Y-m-d');
Thank you. But there is still the question why it wasn't working correctly from the beginning.
The best method is to use DateTime class:
$date = new DateTime('2013-10-26');
$days_to_add = 7;
$date->add(new DateInterval('P' . $days_to_add . 'D'));
echo $date->format('Y-m-d');
Output:
2013-11-02
Demo!
You can use DateTime class to manipulate dates:
function add($date, $years = 0, $months = 0, $days = 0)
{
return date_create($date)->modify("$years year $months month $days day")->format('Y-m-d');
}
Demo
But there is still the question why it wasn't working correctly from the beginning.
Because you are using date function that is timezone and DST aware with combination with strtotime which isn't. For your example, you could use gmdate that will always return time in UTC/GMT.
Speed test different combinations, and you will see that fastest one is gmdate+strtotime combination. My run on 1M loops:
addDays_v1 needed 4.5433s
addDays_v2 needed 7.4234s
addDays_v3 needed 7.6924s
addDays_v4 needed 24.1624s
Try like
return date('Y-m-d', strtotime("+7 day",$date));
You can try like this-
<?php
$date = date_create('2000-01-01');
date_add($date, date_interval_create_from_date_string('7 days'));
echo date_format($date, 'Y-m-d');
?>
Reff: http://in1.php.net/manual/en/datetime.add.php
Changing the last line to:
return date('Y-m-d', strtotime($date . ' 00:00:00 UTC') + 86400 * $days);
And everything is working fine. I've got my 2013-11-02.

Adding days to $Date in PHP

I have a date returned as part of a MySQL query in the form 2010-09-17.
I would like to set the variables $Date2 to $Date5 as follows:
$Date2 = $Date + 1
$Date3 = $Date + 2
etc., so that it returns 2010-09-18, 2010-09-19, etc.
I have tried
date('Y-m-d', strtotime($Date. ' + 1 day'))
but this gives me the date before $Date.
What is the correct way to get my Dates in the format form 'Y-m-d' so that they may be used in another query?
All you have to do is use days instead of day like this:
<?php
$Date = "2010-09-17";
echo date('Y-m-d', strtotime($Date. ' + 1 days'));
echo date('Y-m-d', strtotime($Date. ' + 2 days'));
?>
And it outputs correctly:
2010-09-18
2010-09-19
If you're using PHP 5.3, you can use a DateTime object and its add method:
$Date1 = '2010-09-17';
$date = new DateTime($Date1);
$date->add(new DateInterval('P1D')); // P1D means a period of 1 day
$Date2 = $date->format('Y-m-d');
Take a look at the DateInterval constructor manual page to see how to construct other periods to add to your date (2 days would be 'P2D', 3 would be 'P3D', and so on).
Without PHP 5.3, you should be able to use strtotime the way you did it (I've tested it and it works in both 5.1.6 and 5.2.10):
$Date1 = '2010-09-17';
$Date2 = date('Y-m-d', strtotime($Date1 . " + 1 day"));
// var_dump($Date2) returns "2010-09-18"
From PHP 5.2 on you can use modify with a DateTime object:
http://php.net/manual/en/datetime.modify.php
$Date1 = '2010-09-17';
$date = new DateTime($Date1);
$date->modify('+1 day');
$Date2 = $date->format('Y-m-d');
Be careful when adding months... (and to a lesser extent, years)
Here is a small snippet to demonstrate the date modifications:
$date = date("Y-m-d");
//increment 2 days
$mod_date = strtotime($date."+ 2 days");
echo date("Y-m-d",$mod_date) . "\n";
//decrement 2 days
$mod_date = strtotime($date."- 2 days");
echo date("Y-m-d",$mod_date) . "\n";
//increment 1 month
$mod_date = strtotime($date."+ 1 months");
echo date("Y-m-d",$mod_date) . "\n";
//increment 1 year
$mod_date = strtotime($date."+ 1 years");
echo date("Y-m-d",$mod_date) . "\n";
You can also use the following format
strtotime("-3 days", time());
strtotime("+1 day", strtotime($date));
You can stack changes this way:
strtotime("+1 day", strtotime("+1 year", strtotime($date)));
Note the difference between this approach and the one in other answers: instead of concatenating the values +1 day and <timestamp>, you can just pass in the timestamp as the second parameter of strtotime.
Here has an easy way to solve this.
<?php
$date = "2015-11-17";
echo date('Y-m-d', strtotime($date. ' + 5 days'));
?>
Output will be:
2015-11-22
Solution has found from here - How to Add Days to Date in PHP
Using a variable for Number of days
$myDate = "2014-01-16";
$nDays = 16;
$newDate = strtotime($myDate . '+ '.$nDays.' days');
echo new Date('d/m/Y', $newDate); //format new date
Here is the simplest solution to your query
$date=date_create("2013-03-15"); // or your date string
date_add($date,date_interval_create_from_date_string("40 days"));// add number of days
echo date_format($date,"Y-m-d"); //set date format of the result
This works. You can use it for days, months, seconds and reformat the date as you require
public function reformatDate($date, $difference_str, $return_format)
{
return date($return_format, strtotime($date. ' ' . $difference_str));
}
Examples
echo $this->reformatDate('2021-10-8', '+ 15 minutes', 'Y-m-d H:i:s');
echo $this->reformatDate('2021-10-8', '+ 1 hour', 'Y-m-d H:i:s');
echo $this->reformatDate('2021-10-8', '+ 1 day', 'Y-m-d H:i:s');
To add a certain number of days to a date, use the following function.
function add_days_to_date($date1,$number_of_days){
/*
//$date1 is a string representing a date such as '2021-04-17 14:34:05'
//$date1 =date('Y-m-d H:i:s');
// function date without a secrod argument returns the current datetime as a string in the specified format
*/
$str =' + '. $number_of_days. ' days';
$date2= date('Y-m-d H:i:s', strtotime($date1. $str));
return $date2; //$date2 is a string
}//[end function]
All have to use bellow code:
$nday = time() + ( 24 * 60 * 60);
echo 'Now: '. date('Y-m-d') ."\n";
echo 'Next Day: '. date('Y-m-d', $nday) ."\n";
Another option is to convert your date string into a timestamp and then add the appropriate number of seconds to it.
$datetime_string = '2022-05-12 12:56:45';
$days_to_add = 1;
$new_timestamp = strtotime($datetime_string) + ($days_to_add * 60 * 60 * 24);
After which, you can use one of PHP's various date functions to turn the timestamp into a date object or format it into a human-readable string.
$new_datetime_string = date('Y-m-d H:i:s', $new_timestamp);

Categories