Get the diff between two dates based on 360 days - php

How do I get the difference between two dates based on a 360 days?
360-days: http://en.wikipedia.org/wiki/360-day_calendar
I want to get the difference in days, years and months.
for example:
$fechaDT1 = new DateTime($fechauno);
$fechaDT2 = new DateTime($fechados);
//$initialdays = 30 - (float)$fechaDT1->format('d');
$years = $fechaDT1->format('Y') - $fechaDT2->format('Y');
$months = $fechaDT1->format('m') - $fechaDT2->format('m');
$days = (-$fechaDT1->format('d') + $fechaDT2->format('d'));
$totalDay = $months*30 +$days;
solution:
$startDate = new DateTime($startDate);
$endDate = new DateTime($endDate);
$initialDays = 30 - $startDate->format('d');
$year = ($endDate->format('Y') - $startDate->format('Y')) * 360;
$meses = ($endDate->format('m') - $startDate->format('m')) * 30;
$dias = ($endDate->format('d') - $startDate->format('d'));
$totalDays = $year+$meses+$dias;
$years = number_format($totalDias/360);
$diff = $years - ($endDate->diff($startDate)->y);
$daysR = $totalDays - (($years-$diff)*360);
$result = array("days" => $daysR, "years" => ($years-$diff), "initial days" => $initialDays);
return $result;

The very best solution:
<?php
$date1 = new DateTime('2013-03-24');
$date2 = new DateTime('2014-03-24');
$diff = $date1->diff($date2);
// Do whatever you want
echo $diff->days;
var_dump($diff);
Reference
Nettuts article
There are many other functional options as well, but today, OOP way is better.
Update: 360 days thing
Years:
$years = ($diff->days - ($diff->days % 360)) / 360; //+some remaining days if any
Month: According to the wiki page and following The US/NASD Method (30US/360):
$months = ($diff->days - ($diff->days % 30)) / 30; //+some remaining days if any

I am new to Python also but I think this will work:
import datetime as dt
import calendar
Calculate days difference based on 30/360 calendar
formats
date1 : date format (2020-01-01)
date2 : date format (2020-01-01)
def days_360 (date1, date2):
days_diff = (date2.year - date1.year) * 360;
days_diff += (date2.month - date1.month) * 30;
days_diff += (date2.day - date1.day);
return days_diff;

Related

Finding difference between two dates in PHP 5.2 or higher [duplicate]

Is there any function equivalent to DateTime::diff() in PHP 5.2?
My local server is PHP 5.3 and using DateTime::diff(). then I found that my live site uses PHP 5.2 and gives an error.
Fatal error: Call to undefined method DateTime::diff() in /var/www/some/other/dir/web/daikon/modules/projects/views/admin/log/admin_log_list.php on line 40
The PHP code:
foreach ($logs as $key => $list){
...
// show date in European way dd-mm-yyyy not in MySQL way yyyy-mm-dd
$newdate =new DateTime($list['date']) ;
echo "<td class=\"left\" width=\"8%\">".$newdate->format('d-m-Y')."</td>\n";
$starttime = new DateTime($list['start_time']);
echo "<td width=\"7%\">".date_format($starttime, 'H:i')."</td>\n";
$finishtime = new DateTime($list['finish_time']);
echo "<td width=\"8%\">".date_format($finishtime, 'H:i')."</td>\n";
$timediff = 0;
$interval = $starttime->diff($finishtime);
$hours = $interval->format('%h');
$minutes = $interval->format('%i');
$timediff = $hours * 60 + $minutes;
Spudley's answer doesn't work for me--subtracting any DateTime from another gives 0 on my system.
I was able to get it to work by using DateTime::format with the 'U' specifier (seconds since Unix epoch):
$start = new DateTime('2010-10-12');
$end = new DateTime();
$days = round(($end->format('U') - $start->format('U')) / (60*60*24));
This works on both my dev system (5.3.4) and my deployment system (5.2.11).
I just needed that ( unfortunately ) for a WordPress plugin. This I use the function in 2 times:
In my class calling ->diff() ( my class extends DateTime, so $this is the reference DateTime )
function diff ($secondDate){
$firstDateTimeStamp = $this->format("U");
$secondDateTimeStamp = $secondDate->format("U");
$rv = ($secondDateTimeStamp - $firstDateTimeStamp);
$di = new DateInterval($rv);
return $di;
}
Then I recreated a fake DateInterval class ( because DateInterval is only valid in PHP >= 5.3 ) as follows:
Class DateInterval {
/* Properties */
public $y = 0;
public $m = 0;
public $d = 0;
public $h = 0;
public $i = 0;
public $s = 0;
/* Methods */
public function __construct ( $time_to_convert /** in seconds */) {
$FULL_YEAR = 60*60*24*365.25;
$FULL_MONTH = 60*60*24*(365.25/12);
$FULL_DAY = 60*60*24;
$FULL_HOUR = 60*60;
$FULL_MINUTE = 60;
$FULL_SECOND = 1;
// $time_to_convert = 176559;
$seconds = 0;
$minutes = 0;
$hours = 0;
$days = 0;
$months = 0;
$years = 0;
while($time_to_convert >= $FULL_YEAR) {
$years ++;
$time_to_convert = $time_to_convert - $FULL_YEAR;
}
while($time_to_convert >= $FULL_MONTH) {
$months ++;
$time_to_convert = $time_to_convert - $FULL_MONTH;
}
while($time_to_convert >= $FULL_DAY) {
$days ++;
$time_to_convert = $time_to_convert - $FULL_DAY;
}
while($time_to_convert >= $FULL_HOUR) {
$hours++;
$time_to_convert = $time_to_convert - $FULL_HOUR;
}
while($time_to_convert >= $FULL_MINUTE) {
$minutes++;
$time_to_convert = $time_to_convert - $FULL_MINUTE;
}
$seconds = $time_to_convert; // remaining seconds
$this->y = $years;
$this->m = $months;
$this->d = $days;
$this->h = $hours;
$this->i = $minutes;
$this->s = $seconds;
}
}
Hope that helps somebody.
I use this, seems to work alright - obviously you can add a second parameter to make it more flexible:
function GetDateDiffFromNow($originalDate)
{
$unixOriginalDate = strtotime($originalDate);
$unixNowDate = strtotime('now');
$difference = $unixNowDate - $unixOriginalDate ;
$days = (int)($difference / 86400);
$hours = (int)($difference / 3600);
$minutes = (int)($difference / 60);
$seconds = $difference;
// now do what you want with this now and return ...
}
I was trying to improve Christopher Pickslay's answer.
I made this function that returns and object with most of the properties from the original DateInterval object.
There is no "days" property, because it seems to be some bug in my test server (it always return 6015) .
Also, I am assuming every month has 30 days, which is definitely not precise, but may help.
function dateTimeDiff($date1, $date2) {
$alt_diff = new stdClass();
$alt_diff->y = floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24*365));
$alt_diff->m = floor((floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365))/30);
$alt_diff->d = floor(floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365) - ($alt_diff->m * 30));
$alt_diff->h = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60*60)) - ($alt_diff->y * 365*24) - ($alt_diff->m * 30 * 24 ) - ($alt_diff->d * 24) );
$alt_diff->i = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60)) - ($alt_diff->y * 365*24*60) - ($alt_diff->m * 30 * 24 *60) - ($alt_diff->d * 24 * 60) - ($alt_diff->h * 60) );
$alt_diff->s = floor( floor(abs($date1->format('U') - $date2->format('U'))) - ($alt_diff->y * 365*24*60*60) - ($alt_diff->m * 30 * 24 *60*60) - ($alt_diff->d * 24 * 60*60) - ($alt_diff->h * 60*60) - ($alt_diff->i * 60) );
$alt_diff->invert = (($date1->format('U') - $date2->format('U')) > 0)? 0 : 1 ;
return $alt_diff;
}
Yes, it's annoying that feature didn't make it into PHP5.2.
I'll assume you can't upgrade to 5.3? You should look into it; there's very little reason not to upgrade; but I'll assume you can't for whatever the reason.
First tip: If you only need a diff of less than 24hours, you can simply subtract the two time stamps, and do $time_diff = date('H:i:s',$subtracted_value);
If you're doing more than 24 hour diffs, but you're okay with just returning the number of days along with the time difference, you can expand on the above technique by doing a modulus calculation on the subtrated value, against the number of seconds in a day (ie 24*60*60, which is 86400)
$subtracted_value = $date1 - $date2;
$days_diff = $subtracted_value % 86400;
$time_diff = date('H:i:s',$subtracted_value);
If you need weeks, you can of course do $days_diff % 7.
Unfortunately, the manual technique breaks down after weeks, because months and years are variable in length (technically days are too, given daylight saving, but you can probably ignore that, especially as you're only ever going to be one hour out, at the most), but hopefully that's good enough to get you started.
Read the contrib notes in the PHP date_diff page
http://us3.php.net/manual/en/function.date-diff.php
Spudley was close, but you need to use gmdate not date.
So this works for 24 hours or less (if it's a positive value at least):
$difference = $date2->format('U') - $date1->format('U');
$time_diff = gmdate('H:i:s',$difference);
PHP has methods for working with Unix timestamps.
As has been noted by others, by working with seconds since the Unix date, it is easy to calculate times.
PHP's strtotime() converts a date to a timestamp:
$diff = round((strtotime($list['start']) - strtotime($list['finish'])) / 86400);
If you wish to calculate till the current time, time() provides the timestamp of "now":
$diff = round((time() - strtotime($list['date'])) / 86400);
86400 is the number of seconds in a day.
If you wish to convert to years use 31557000, which is almost exactly 365.24219 * 86400.
An added advantage here is that strtotime can take the input date in almost any human readable format, so it is very easy to work with within the code.
Please observe that if your DateTime object was created from a date string without any timezone information (as in '2012-01-01 05:00:00' like from mysql), then setting the timezone later with DateTimeZone objects via setTimeZone() does not change the DateTime objects internal timestamp.
$localtime = new DateTime('2012-01-01 08:00:00+02:00'); // Europe/Copenhagen (+ daylight savings)
$localtime->setTimezone(new DateTimeZone('UTC')); // convert local time to utc
$utctime = new DateTime('2012-01-01 06:00:00'); // timezone assumed utc, but is in fact unknown
$utctime->setTimezone(new DateTimeZone('UTC')); // trying to rectify missing timezone which fails, because the internal timestamp isn't modified, although any other format than 'U' may indicate so
#$utctime = new DateTime('2012-01-01 06:00:00+00:00'); // timezone stated, this works
$diff = intval($localtime->format('U')) - intval($utctime->format('U'));
echo $diff; // expecting zero
Here is the best solution for your question.
<?php
/* Find difference between two dates in days. PHP 5.2.x. */
$d1 = date('Y-m-d', strtotime('2013-06-13'));
$d2 = date("Y-m-d");
echo diff($d1, $d2);
function diff($date1, $date2) {
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24) / (60*60*24));
return $days;
}
?>

php where is my percentage of the day being calculated wrong?

I been trying to fix this php percentage calculator of the day...basically right now here is about 230pm and I am getting 73% of the day completed....it should be more like 60% of the day. Here is the code:
$now = time();
$today = strtotime(date("m/d/Y"));
$seconds = $now - $today;
$day = 24*60*60;
$percent = $seconds / $day*100;
I attempted to write my own version but I am getting 100% of the day...Here is the code:
$todaysTime = time();
$todaysStart = time()-86400;
$todayCalc = $todaysTime - $todaysStart;
$dayPhpOne = 24*60*60;
$percentDay = $todayCalc / $dayPhpOne*100;
It is done in php where am I messing up my code?
Try this:
$percentDay = time() % 86400 / 864;
Edit
From the comments I take, that I didn't elaborate on time zones. Let me make clear, that this is meant to be UTC day percent.
This solution does respect timezone and other time-related complexities:
$d = new DateTime();
$h = $d->format('H');
$m = $d->format('i');
$s = $d->format('s');
$currentSecond = $h * 3600 + $m * 60 + $s;
$midnight = new DateTime($d->format('Y-m-d'), $d->getTimezone());
$tomorrow = clone $midnight;
$tomorrow = $tomorrow->add(new DateInterval('P1D'));
$secondsToday = $tomorrow->getTimestamp() - $midnight->getTimestamp();
$percent = $currentSecond / $secondsToday * 100;
var_dump($percent);
If necessary - it's possible to specify a particular timezone to be used as a second DateTime constructor argument.

php replacing old code with DateTime class

I have a function that creates time intervals between two time marks. The function works but I'm struggling to upgrade from strtotime() and use the DateTime class.
Below is a patch of code I wrote without getting errors
$timestart = new DateTime("14:00:00");
$timestop = new DateTime("20:00:00");
$date_diff = $timestop->diff($timestart);
$time_diff = $date_diff->format('%H');
Next is the entire code untouched. I get DateInterval could not be converted to int erros using the code above. Please kindly advise how to correctly implement the class.
Live example: http://codepad.org/jSFUxAnp
function timemarks()
{
//times are actually retrieved from db
$timestart = strtotime("14:00:00");
$timestop = strtotime("20:00:00");
$time_diff = $timestop - $timestart; //time difference
//if time difference equals negative value, it means that $timestop ends second day
if ($time_diff <= 0)
{
$timestop = strtotime( '+1 day' , strtotime( $row->timestop ) ); //add 1 day and change the timetsamp
$time_diff = $timestop - $timestart;
}
//create interval
$split = 3;
$interval = $time_diff/$split;
//get all timemarks
$half_interval = $interval / 2;
$mid = $timestart + $half_interval;
for ( $i = 1; $i < $split; $i ++) {
//round intervals
$round_mid = round($mid / (15 * 60)) * (15 * 60);
$result .= date('H:i:s', $round_mid) . ", ";
$mid += $interval;
}
$round_mid = round($mid / (15 * 60)) * (15 * 60);
$result .= date('H:i:s', $round_mid);
return $result;
}
outputs 15:00:00, 17:00:00, 19:00:00
Actually you're using DateTime, these are just aliases for creating DateTime instances
The equivalent would look like this:
$timestart = new DateTime("14:00:00");
$timestop = new DateTime("20:00:00");
$date_diff = $timestop->diff($timestart);
$time_diff = $date_diff->format('%H');
So this has to work, I tested it and I got correct results!

What can use for DateTime::diff() for PHP 5.2?

Is there any function equivalent to DateTime::diff() in PHP 5.2?
My local server is PHP 5.3 and using DateTime::diff(). then I found that my live site uses PHP 5.2 and gives an error.
Fatal error: Call to undefined method DateTime::diff() in /var/www/some/other/dir/web/daikon/modules/projects/views/admin/log/admin_log_list.php on line 40
The PHP code:
foreach ($logs as $key => $list){
...
// show date in European way dd-mm-yyyy not in MySQL way yyyy-mm-dd
$newdate =new DateTime($list['date']) ;
echo "<td class=\"left\" width=\"8%\">".$newdate->format('d-m-Y')."</td>\n";
$starttime = new DateTime($list['start_time']);
echo "<td width=\"7%\">".date_format($starttime, 'H:i')."</td>\n";
$finishtime = new DateTime($list['finish_time']);
echo "<td width=\"8%\">".date_format($finishtime, 'H:i')."</td>\n";
$timediff = 0;
$interval = $starttime->diff($finishtime);
$hours = $interval->format('%h');
$minutes = $interval->format('%i');
$timediff = $hours * 60 + $minutes;
Spudley's answer doesn't work for me--subtracting any DateTime from another gives 0 on my system.
I was able to get it to work by using DateTime::format with the 'U' specifier (seconds since Unix epoch):
$start = new DateTime('2010-10-12');
$end = new DateTime();
$days = round(($end->format('U') - $start->format('U')) / (60*60*24));
This works on both my dev system (5.3.4) and my deployment system (5.2.11).
I just needed that ( unfortunately ) for a WordPress plugin. This I use the function in 2 times:
In my class calling ->diff() ( my class extends DateTime, so $this is the reference DateTime )
function diff ($secondDate){
$firstDateTimeStamp = $this->format("U");
$secondDateTimeStamp = $secondDate->format("U");
$rv = ($secondDateTimeStamp - $firstDateTimeStamp);
$di = new DateInterval($rv);
return $di;
}
Then I recreated a fake DateInterval class ( because DateInterval is only valid in PHP >= 5.3 ) as follows:
Class DateInterval {
/* Properties */
public $y = 0;
public $m = 0;
public $d = 0;
public $h = 0;
public $i = 0;
public $s = 0;
/* Methods */
public function __construct ( $time_to_convert /** in seconds */) {
$FULL_YEAR = 60*60*24*365.25;
$FULL_MONTH = 60*60*24*(365.25/12);
$FULL_DAY = 60*60*24;
$FULL_HOUR = 60*60;
$FULL_MINUTE = 60;
$FULL_SECOND = 1;
// $time_to_convert = 176559;
$seconds = 0;
$minutes = 0;
$hours = 0;
$days = 0;
$months = 0;
$years = 0;
while($time_to_convert >= $FULL_YEAR) {
$years ++;
$time_to_convert = $time_to_convert - $FULL_YEAR;
}
while($time_to_convert >= $FULL_MONTH) {
$months ++;
$time_to_convert = $time_to_convert - $FULL_MONTH;
}
while($time_to_convert >= $FULL_DAY) {
$days ++;
$time_to_convert = $time_to_convert - $FULL_DAY;
}
while($time_to_convert >= $FULL_HOUR) {
$hours++;
$time_to_convert = $time_to_convert - $FULL_HOUR;
}
while($time_to_convert >= $FULL_MINUTE) {
$minutes++;
$time_to_convert = $time_to_convert - $FULL_MINUTE;
}
$seconds = $time_to_convert; // remaining seconds
$this->y = $years;
$this->m = $months;
$this->d = $days;
$this->h = $hours;
$this->i = $minutes;
$this->s = $seconds;
}
}
Hope that helps somebody.
I use this, seems to work alright - obviously you can add a second parameter to make it more flexible:
function GetDateDiffFromNow($originalDate)
{
$unixOriginalDate = strtotime($originalDate);
$unixNowDate = strtotime('now');
$difference = $unixNowDate - $unixOriginalDate ;
$days = (int)($difference / 86400);
$hours = (int)($difference / 3600);
$minutes = (int)($difference / 60);
$seconds = $difference;
// now do what you want with this now and return ...
}
I was trying to improve Christopher Pickslay's answer.
I made this function that returns and object with most of the properties from the original DateInterval object.
There is no "days" property, because it seems to be some bug in my test server (it always return 6015) .
Also, I am assuming every month has 30 days, which is definitely not precise, but may help.
function dateTimeDiff($date1, $date2) {
$alt_diff = new stdClass();
$alt_diff->y = floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24*365));
$alt_diff->m = floor((floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365))/30);
$alt_diff->d = floor(floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365) - ($alt_diff->m * 30));
$alt_diff->h = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60*60)) - ($alt_diff->y * 365*24) - ($alt_diff->m * 30 * 24 ) - ($alt_diff->d * 24) );
$alt_diff->i = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60)) - ($alt_diff->y * 365*24*60) - ($alt_diff->m * 30 * 24 *60) - ($alt_diff->d * 24 * 60) - ($alt_diff->h * 60) );
$alt_diff->s = floor( floor(abs($date1->format('U') - $date2->format('U'))) - ($alt_diff->y * 365*24*60*60) - ($alt_diff->m * 30 * 24 *60*60) - ($alt_diff->d * 24 * 60*60) - ($alt_diff->h * 60*60) - ($alt_diff->i * 60) );
$alt_diff->invert = (($date1->format('U') - $date2->format('U')) > 0)? 0 : 1 ;
return $alt_diff;
}
Yes, it's annoying that feature didn't make it into PHP5.2.
I'll assume you can't upgrade to 5.3? You should look into it; there's very little reason not to upgrade; but I'll assume you can't for whatever the reason.
First tip: If you only need a diff of less than 24hours, you can simply subtract the two time stamps, and do $time_diff = date('H:i:s',$subtracted_value);
If you're doing more than 24 hour diffs, but you're okay with just returning the number of days along with the time difference, you can expand on the above technique by doing a modulus calculation on the subtrated value, against the number of seconds in a day (ie 24*60*60, which is 86400)
$subtracted_value = $date1 - $date2;
$days_diff = $subtracted_value % 86400;
$time_diff = date('H:i:s',$subtracted_value);
If you need weeks, you can of course do $days_diff % 7.
Unfortunately, the manual technique breaks down after weeks, because months and years are variable in length (technically days are too, given daylight saving, but you can probably ignore that, especially as you're only ever going to be one hour out, at the most), but hopefully that's good enough to get you started.
Read the contrib notes in the PHP date_diff page
http://us3.php.net/manual/en/function.date-diff.php
Spudley was close, but you need to use gmdate not date.
So this works for 24 hours or less (if it's a positive value at least):
$difference = $date2->format('U') - $date1->format('U');
$time_diff = gmdate('H:i:s',$difference);
PHP has methods for working with Unix timestamps.
As has been noted by others, by working with seconds since the Unix date, it is easy to calculate times.
PHP's strtotime() converts a date to a timestamp:
$diff = round((strtotime($list['start']) - strtotime($list['finish'])) / 86400);
If you wish to calculate till the current time, time() provides the timestamp of "now":
$diff = round((time() - strtotime($list['date'])) / 86400);
86400 is the number of seconds in a day.
If you wish to convert to years use 31557000, which is almost exactly 365.24219 * 86400.
An added advantage here is that strtotime can take the input date in almost any human readable format, so it is very easy to work with within the code.
Please observe that if your DateTime object was created from a date string without any timezone information (as in '2012-01-01 05:00:00' like from mysql), then setting the timezone later with DateTimeZone objects via setTimeZone() does not change the DateTime objects internal timestamp.
$localtime = new DateTime('2012-01-01 08:00:00+02:00'); // Europe/Copenhagen (+ daylight savings)
$localtime->setTimezone(new DateTimeZone('UTC')); // convert local time to utc
$utctime = new DateTime('2012-01-01 06:00:00'); // timezone assumed utc, but is in fact unknown
$utctime->setTimezone(new DateTimeZone('UTC')); // trying to rectify missing timezone which fails, because the internal timestamp isn't modified, although any other format than 'U' may indicate so
#$utctime = new DateTime('2012-01-01 06:00:00+00:00'); // timezone stated, this works
$diff = intval($localtime->format('U')) - intval($utctime->format('U'));
echo $diff; // expecting zero
Here is the best solution for your question.
<?php
/* Find difference between two dates in days. PHP 5.2.x. */
$d1 = date('Y-m-d', strtotime('2013-06-13'));
$d2 = date("Y-m-d");
echo diff($d1, $d2);
function diff($date1, $date2) {
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24) / (60*60*24));
return $days;
}
?>

how get calc saturday+monday in range date

i hope some help to me ...
i am trouble with some code IN PHP ,maybe you can see function about this :
I need to check is there on Saturday in one period ($date_start ,$date_end )
so :
input : $date_Start (ex: "2010-07-01")
$date_end (ex: "2010-07-12")
output : total saturday : 2 in your range date
but the way thanks before
JOKONARDI
Efficient implementation with no loops for number of Saturdays in the range:
$d1 = new DateTime("2010-07-01"); //including
$d2 = new DateTime("2010-07-12"); //excluding
$diff = $d2->diff($d1);
$days = $diff->format("%a");
$num = floor($days / 7);
$remaining = $days % 7;
$d = $d1->format("w");
if ($d + $remaining > 6)
$num++;
//result in $num

Categories