Php Stored date from MySQL db convert to equivalent Ethiopian date - php

I want to convert any Gregorian date to an equivalent Ethiopian Date. The Gregorian date is generated on records created or updated using the PHP date function, date('Y-m-d H:i:s') from the server date. I want to show the changes made are in the Ethiopian date so the views are can easily understand it. I've made a function to change it. but the function date is not reliable in some leap years.
The function returns the date format in either Tigrigna or Amharic language.
Any hint?
function conver_to_ethiopian_date($date, $lang ="ti"){
$OFFSET=79372;
$DAY=86400;
$EYear=1745;
$EMonth=0;
$EDate=0;
$GC=0;
$timezone = 0;
$tot= gmdate($date, 3600*($timezone+date("I")));
$days=round(strtotime($tot)/$DAY);
$days +=$OFFSET;
$mark=0;
$EYear=1745;
while ($mark==0){
if ($EYear % 4 ==3){
if ($days>=366) {
$days-=366;
$EYear=$EYear+1;
}
else{
$mark=1;
}
}
else{
if ($days>=365){
$days-=365;
$EYear=$EYear+1;
}
else {$mark=1;}
}
}
if ($days==0){
$EYear-=1;
//leap year
$EMonth=12;
$EDate=5 + (($EYear%4==3)?1:0);
}
else{
$EMonth = (($days-1) / 30);
if ($days % 30 ==0){ $EDate = 30;}
else {$EDate=$days % 30;}
}
$months_am =array("መስከረም", "ጥቅምት", "ኅዳር", "ታኅሣሥ", "ጥር","የካቲት","መጋቢት","ሚያዝያ", "ግንቦት", "ሰኔ", "ሐምሌ", "ነሐሴ", 'ጳጉሜ');
$months_tg =array("መስከረም", "ጥቅምቲ", "ሕዳር", "ታሕሳስ", "ጥሪ","የካቲት","መጋቢት","ሚያዝያ", "ጉንበት", "ሰነ", "ሓምለ", "ነሓሰ", 'ጳጉሜን');
$days_am =array("እሁድ", "ሰኞ", "ማክሰኞ", "ሮብ", "ሓሙስ", "ኣርብ", "ቀዳሜ");
$days_tg =array("ሰንበት", "ሶኒ", "ሰሉስ", "ረቡዕ", "ሓሙስ", "ዓርቢ", "ቀዳም");
$date_time = explode(' - ', $date);
$year =$year?$year:date("Y") ;
$day_of_week = date("w", mktime(0, 0, 0, $date_time[1], $date_time[2], $date_time[0]));
if ("am" == $lang)
return $days_am[$day_of_week]." ".$months_am[$EMonth]." ".$EDate.", ".$EYear;
else
return $days_tg[$day_of_week]." ".$months_tg[$EMonth]." ". $EDate.", ".$EYear;
}

Related

PHP Dates Condition [duplicate]

How can I compare two dates in PHP?
The date is stored in the database in the following format
2011-10-2
If I wanted to compare today's date against the date in the database to see which one is greater, how would I do it?
I tried this,
$today = date("Y-m-d");
$expire = $row->expireDate //from db
if($today < $expireDate) { //do something; }
but it doesn't really work that way. What's another way of doing it?
If all your dates are posterior to the 1st of January of 1970, you could use something like:
$today = date("Y-m-d");
$expire = $row->expireDate; //from database
$today_time = strtotime($today);
$expire_time = strtotime($expire);
if ($expire_time < $today_time) { /* do Something */ }
If you are using PHP 5 >= 5.2.0, you could use the DateTime class:
$today_dt = new DateTime($today);
$expire_dt = new DateTime($expire);
if ($expire_dt < $today_dt) { /* Do something */ }
Or something along these lines.
in the database the date looks like this 2011-10-2
Store it in YYYY-MM-DD and then string comparison will work because '1' > '0', etc.
Just to compliment the already given answers, see the following example:
$today = new DateTime('');
$expireDate = new DateTime($row->expireDate); //from database
if($today->format("Y-m-d") < $expireDate->format("Y-m-d")) {
//do something;
}
Update:
Or simple use old-school date() function:
if(date('Y-m-d') < date('Y-m-d', strtotime($expire_date))){
//echo not yet expired!
}
I would'nt do this with PHP.
A database should know, what day is today.( use MySQL->NOW() for example ), so it will be very easy to compare within the Query and return the result, without any problems depending on the used Date-Types
SELECT IF(expireDate < NOW(),TRUE,FALSE) as isExpired FROM tableName
$today = date('Y-m-d');//Y-m-d H:i:s
$expireDate = new DateTime($row->expireDate);// From db
$date1=date_create($today);
$date2=date_create($expireDate->format('Y-m-d'));
$diff=date_diff($date1,$date2);
//echo $timeDiff;
if($diff->days >= 30){
echo "Expired.";
}else{
echo "Not expired.";
}
Here's a way on how to get the difference between two dates in minutes.
// set dates
$date_compare1= date("d-m-Y h:i:s a", strtotime($date1));
// date now
$date_compare2= date("d-m-Y h:i:s a", strtotime($date2));
// calculate the difference
$difference = strtotime($date_compare1) - strtotime($date_compare2);
$difference_in_minutes = $difference / 60;
echo $difference_in_minutes;
You can convert the dates into UNIX timestamps and compare the difference between them in seconds.
$today_date=date("Y-m-d");
$entered_date=$_POST['date'];
$dateTimestamp1 = strtotime($today_date);
$dateTimestamp2 = strtotime($entered_date);
$diff= $dateTimestamp1-$dateTimestamp2;
//echo $diff;
if ($diff<=0)
{
echo "Enter a valid date";
}
I had that problem too and I solve it by:
$today = date("Ymd");
$expire = str_replace('-', '', $row->expireDate); //from db
if(($today - $expire) > $NUMBER_OF_DAYS)
{
//do something;
}
Here's my spin on how to get the difference in days between two dates with PHP.
Note the use of '!' in the format to discard the time part of the dates, thanks to info from DateTime createFromFormat without time.
$today = DateTime::createFromFormat('!Y-m-d', date('Y-m-d'));
$wanted = DateTime::createFromFormat('!d-m-Y', $row["WANTED_DELIVERY_DATE"]);
$diff = $today->diff($wanted);
$days = $diff->days;
if (($diff->invert) != 0) $days = -1 * $days;
$overdue = (($days < 0) ? true : false);
print "<!-- (".(($days > 0) ? '+' : '').($days).") -->\n";
Found the answer on a blog and it's as simple as:
strtotime(date("Y"."-01-01")) -strtotime($newdate))/86400
And you'll get the days between the 2 dates.
This works because of PHP's string comparison logic. Simply you can check...
if ($startdate < $date) {// do something}
if ($startdate > $date) {// do something}
Both dates must be in the same format. Digits need to be zero-padded to the left and ordered from most significant to least significant. Y-m-d and Y-m-d H:i:s satisfy these conditions.
If you want a date ($date) to get expired in some interval for example a token expiration date when performing a password reset, here's how you can do:
$date = $row->expireDate;
$date->add(new DateInterval('PT24H')); // adds 24 hours
$now = new \DateTime();
if($now < $date) { /* expired after 24 hours */ }
But in your case you could do the comparison just as the following:
$today = new DateTime('Y-m-d');
$date = $row->expireDate;
if($today < $date) { /* do something */ }
first of all, try to give the format you want to the current date time of your server:
Obtain current date time
$current_date = getdate();
Separate date and time to manage them as you wish:
$current_date_only = $current_date[year].'-'.$current_date[mon].'-'.$current_date[mday];
$current_time_only = $current_date['hours'].':'.$current_date['minutes'].':'.$current_date['seconds'];
Compare it depending if you are using donly date or datetime in your DB:
$today = $current_date_only.' '.$current_time_only;
or
$today = $current_date_only;
if($today < $expireDate)
hope it helps

PHP: year when a date occurs the next time

I need a function that returns the year when a given date (day + month) occurs the first time from now on.
function year($day, $month) {
// ...
return $year;
}
$day and $year are two-digit numbers
E.g. the given date is '12/25' it should return '2016' (or '16'), but if the date is '02/25' it should return '2017' (or '17').
[Today is August 30, 2016]
Leap years may be disregarded and input doesn't have to be validated.
EDIT:
My attempt
year($day, $month) {
$today_day = date('d');
$today_month = date('m');
$year = date('y');
if($month > $today_month) {
return $year;
} else if ($month < $today_month) {
return $year + 1;
} else {
if($day >= $today_day) {
return $year;
} else {
return $year + 1;
}
}
}
Just compare the date you are checking against today. If it is today or earlier increment the year of the date. Otherwise do not. Then return that year.
DateTime() functionality makes this easy to do.
function year($day, $month) {
$date = new DateTime("{$month}/{$day}"); // defaults to current year
$today = new DateTime();
if ($date <= $today) {
$today->modify('+1 year');
}
return $today->format('Y');
}
echo year(6, 6); // 2017
echo year(12, 12); // 2016
Demo
I appreciate your effort! It was pretty good, but can certainly use some fine tuning. We could reduce the no. of unnecessary if statements.
The function accepts two parameters: month and date. Please be sure we follow the order while calling the function.
In the function, $date is the input date concatenated with the current year.
E.g: year(12,25) refers to the year where month is December (12) and day is 25.
year(12,25) would make $date as 2015-12-25.
function year($month, $day)
{
$date= date('Y').'-'.$month.'-'.$day;
if (strtotime($date) > time()) {
return date('y');
}
return (date('y')+1);
}
echo year(12,25); // 16
echo year(2,25); // 17
Now, all we need to do is check the timestamp of $date with the current timestamp- time().
strtotime($date) > time() input date timestamp is more than current timestamp. Which implies this date is yet to come in this year. So, we return the current year date('Y').
If the above if is not executed, it's obvious that this date has passed. Hence we return the next year date('Y') + 1.

PHP strtotime +1 month behaviour

I know about the unwanted behaviour of PHP's function
strtotime
For example, when adding a month (+1 month) to dates like: 31.01.2011 -> 03.03.2011
I know it's not officially a PHP bug, and that this solution has some arguments behind it, but at least for me, this behavior has caused a lot waste of time (in the past and present) and I personally hate it.
What I found even stranger is that for example in:
MySQL: DATE_ADD('2011-01-31', INTERVAL 1 MONTH) returns 2011-02-28
or
C# where new DateTime(2011, 01, 31).AddMonths(1); will return 28.02.2011
wolframalpha.com giving 31.01.2013 + 1 month as input; will return Thursday, February 28, 2013
It sees to me that others have found a more decent solution to the stupid question that I saw alot in PHP bug reports "what day will it be, if I say we meet in a month from now" or something like that. The answer is: if 31 does not exists in next month, get me the last day of that month, but please stick to next month.
So MY QUESTION IS: is there a PHP function (written by somebody) that resolves this not officially recognized bug? As I don't think I am the only one who wants another behavior when adding / subtracting months.
I am particulary interested in solutions what also work not just for the end of the month, but a complete replacement of strtotime. Also the case strotime +n months should be also dealt with.
Happy coding!
what you need is to tell PHP to be smarter
$the_date = strtotime('31.01.2011');
echo date('r', strtotime('last day of next month', $the_date));
$the_date = strtotime('31.03.2011');
echo date('r', strtotime('last day of next month', $the_date));
assuming you are only interesting on the last day of next month
reference - http://www.php.net/manual/en/datetime.formats.relative.php
PHP devs surely don't consider this as bug. But in strtotime's docs there are few comments with solutions for your problem (look for 28th Feb examples ;)), i.e. this one extending DateTime class:
<?php
// this will give us 2010-02-28 ()
echo PHPDateTime::DateNextMonth(strftime('%F', strtotime("2010-01-31 00:00:00")), 31);
?>
Class PHPDateTime:
<?php
/**
* IA FrameWork
* #package: Classes & Object Oriented Programming
* #subpackage: Date & Time Manipulation
* #author: ItsAsh <ash at itsash dot co dot uk>
*/
final class PHPDateTime extends DateTime {
// Public Methods
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Calculate time difference between two dates
* ...
*/
public static function TimeDifference($date1, $date2)
$date1 = is_int($date1) ? $date1 : strtotime($date1);
$date2 = is_int($date2) ? $date2 : strtotime($date2);
if (($date1 !== false) && ($date2 !== false)) {
if ($date2 >= $date1) {
$diff = ($date2 - $date1);
if ($days = intval((floor($diff / 86400))))
$diff %= 86400;
if ($hours = intval((floor($diff / 3600))))
$diff %= 3600;
if ($minutes = intval((floor($diff / 60))))
$diff %= 60;
return array($days, $hours, $minutes, intval($diff));
}
}
return false;
}
/**
* Formatted time difference between two dates
*
* ...
*/
public static function StringTimeDifference($date1, $date2) {
$i = array();
list($d, $h, $m, $s) = (array) self::TimeDifference($date1, $date2);
if ($d > 0)
$i[] = sprintf('%d Days', $d);
if ($h > 0)
$i[] = sprintf('%d Hours', $h);
if (($d == 0) && ($m > 0))
$i[] = sprintf('%d Minutes', $m);
if (($h == 0) && ($s > 0))
$i[] = sprintf('%d Seconds', $s);
return count($i) ? implode(' ', $i) : 'Just Now';
}
/**
* Calculate the date next month
*
* ...
*/
public static function DateNextMonth($now, $date = 0) {
$mdate = array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
list($y, $m, $d) = explode('-', (is_int($now) ? strftime('%F', $now) : $now));
if ($date)
$d = $date;
if (++$m == 2)
$d = (($y % 4) === 0) ? (($d <= 29) ? $d : 29) : (($d <= 28) ? $d : 28);
else
$d = ($d <= $mdate[$m]) ? $d : $mdate[$m];
return strftime('%F', mktime(0, 0, 0, $m, $d, $y));
}
}
?>
Here's the algorithm you can use. It should be simple enough to implement yourself.
Have the original date and the +1 month date in variables
Extract the month part of both variables
If the difference is greater than 1 month (or if the original is December and the other is not January) change the latter variable to the last day of the next month. You can use for example t in date() to get the last day: date( 't.m.Y' )
Had the same issue recently and ended up writing a class that handles adding/subtracting various time intervals to DateTime objects.
Here's the code:
https://gist.github.com/pavlepredic/6220041#file-gistfile1-php
I've been using this class for a while and it seems to work fine, but I'm really interested in some peer review. What you do is create a TimeInterval object (in your case, you would specify 1 month as the interval) and then call addToDate() method, making sure you set $preventMonthOverflow argument to true. The code will make sure that the resulting date does not overflow into next month.
Sample usage:
$int = new TimeInterval(1, TimeInterval::MONTH);
$date = date_create('2013-01-31');
$future = $int->addToDate($date, true);
echo $future->format('Y-m-d');
Resulting date is:
2013-02-28
Here is an implementation of an improved version of Juhana's answer above:
<?php
function sameDateNextMonth(DateTime $createdDate, DateTime $currentDate) {
$addMon = clone $currentDate;
$addMon->add(new DateInterval("P1M"));
$nextMon = clone $currentDate;
$nextMon->modify("last day of next month");
if ($addMon->format("n") == $nextMon->format("n")) {
$recurDay = $createdDate->format("j");
$daysInMon = $addMon->format("t");
$currentDay = $currentDate->format("j");
if ($recurDay > $currentDay && $recurDay <= $daysInMon) {
$addMon->setDate($addMon->format("Y"), $addMon->format("n"), $recurDay);
}
return $addMon;
} else {
return $nextMon;
}
}
This version takes $createdDate under the presumption that you are dealing with a recurring monthly period, such as a subscription, that started on a specific date, such as the 31st. It always takes $createdDate so late "recurs on" dates won't shift to lower values as they are pushed forward thru lesser-valued months (e.g., so all 29th, 30th or 31st recur dates won't eventually get stuck on the 28th after passing thru a non-leap-year February).
Here is some driver code to test the algorithm:
$createdDate = new DateTime("2015-03-31");
echo "created date = " . $createdDate->format("Y-m-d") . PHP_EOL;
$next = sameDateNextMonth($createdDate, $createdDate);
echo " next date = " . $next->format("Y-m-d") . PHP_EOL;
foreach(range(1, 12) as $i) {
$next = sameDateNextMonth($createdDate, $next);
echo " next date = " . $next->format("Y-m-d") . PHP_EOL;
}
Which outputs:
created date = 2015-03-31
next date = 2015-04-30
next date = 2015-05-31
next date = 2015-06-30
next date = 2015-07-31
next date = 2015-08-31
next date = 2015-09-30
next date = 2015-10-31
next date = 2015-11-30
next date = 2015-12-31
next date = 2016-01-31
next date = 2016-02-29
next date = 2016-03-31
next date = 2016-04-30
I have solved it by this way:
$startDate = date("Y-m-d");
$month = date("m",strtotime($startDate));
$nextmonth = date("m",strtotime("$startDate +1 month"));
if((($nextmonth-$month) > 1) || ($month == 12 && $nextmonth != 1))
{
$nextDate = date( 't.m.Y',strtotime("$initialDate +1 week"));
}else
{
$nextDate = date("Y-m-d",strtotime("$initialDate +1 month"));
}
echo $nextDate;
Somewhat similar to the Juhana's answer but more intuitive and less complications expected. Idea is like this:
Store original date and the +n month(s) date in variables
Extract the day part of both variables
If days do not match, subtract number of days from the future date
Plus side of this solution is that works for any date (not just the border dates) and it also works for subtracting months (by putting - instead of +).
Here is an example implementation:
$start = mktime(0,0,0,1,31,2015);
for ($contract = 0; $contract < 12; $contract++) {
$end = strtotime('+ ' . $contract . ' months', $start);
if (date('d', $start) != date('d', $end)) {
$end = strtotime('- ' . date('d', $end) . ' days', $end);
}
echo date('d-m-Y', $end) . '|';
}
And the output is following:
31-01-2015|28-02-2015|31-03-2015|30-04-2015|31-05-2015|30-06-2015|31-07-2015|31-08-2015|30-09-2015|31-10-2015|30-11-2015|31-12-2015|
function ldom($m,$y){
//return tha last date of a given month based on the month and the year
//(factors in leap years)
$first_day= strtotime (date($m.'/1/'.$y));
$next_month = date('m',strtotime ( '+32 day' , $first_day)) ;
$last_day= strtotime ( '-1 day' , strtotime (date($next_month.'/1/'.$y)) ) ;
return $last_day;
}

Next business day of given date in PHP

Does anyone have a PHP snippet to calculate the next business day for a given date?
How does, for example, YYYY-MM-DD need to be converted to find out the next business day?
Example:
For 03.04.2011 (DD-MM-YYYY) the next business day is 04.04.2011.
For 08.04.2011 the next business day is 11.04.2011.
This is the variable containing the date I need to know the next business day for
$cubeTime['time'];
Variable contains: 2011-04-01
result of the snippet should be: 2011-04-04
Next Weekday
This finds the next weekday from a specific date (not including Saturday or Sunday):
echo date('Y-m-d', strtotime('2011-04-05 +1 Weekday'));
You could also do it with a date variable of course:
$myDate = '2011-04-05';
echo date('Y-m-d', strtotime($myDate . ' +1 Weekday'));
UPDATE: Or, if you have access to PHP's DateTime class (very likely):
$date = new DateTime('2018-01-27');
$date->modify('+7 weekday');
echo $date->format('Y-m-d');
Want to Skip Holidays?:
Although the original poster mentioned "I don't need to consider holidays", if you DO happen to want to ignore holidays, just remember - "Holidays" is just an array of whatever dates you don't want to include and differs by country, region, company, person...etc.
Simply put the above code into a function that excludes/loops past the dates you don't want included. Something like this:
$tmpDate = '2015-06-22';
$holidays = ['2015-07-04', '2015-10-31', '2015-12-25'];
$i = 1;
$nextBusinessDay = date('Y-m-d', strtotime($tmpDate . ' +' . $i . ' Weekday'));
while (in_array($nextBusinessDay, $holidays)) {
$i++;
$nextBusinessDay = date('Y-m-d', strtotime($tmpDate . ' +' . $i . ' Weekday'));
}
I'm sure the above code can be simplified or shortened if you want. I tried to write it in an easy-to-understand way.
For UK holidays you can use
https://www.gov.uk/bank-holidays#england-and-wales
The ICS format data is easy to parse. My suggestion is...
# $date must be in YYYY-MM-DD format
# You can pass in either an array of holidays in YYYYMMDD format
# OR a URL for a .ics file containing holidays
# this defaults to the UK government holiday data for England and Wales
function addBusinessDays($date,$numDays=1,$holidays='') {
if ($holidays==='') $holidays = 'https://www.gov.uk/bank-holidays/england-and-wales.ics';
if (!is_array($holidays)) {
$ch = curl_init($holidays);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$ics = curl_exec($ch);
curl_close($ch);
$ics = explode("\n",$ics);
$ics = preg_grep('/^DTSTART;/',$ics);
$holidays = preg_replace('/^DTSTART;VALUE=DATE:(\\d{4})(\\d{2})(\\d{2}).*/s','$1-$2-$3',$ics);
}
$addDay = 0;
while ($numDays--) {
while (true) {
$addDay++;
$newDate = date('Y-m-d', strtotime("$date +$addDay Days"));
$newDayOfWeek = date('w', strtotime($newDate));
if ( $newDayOfWeek>0 && $newDayOfWeek<6 && !in_array($newDate,$holidays)) break;
}
}
return $newDate;
}
function next_business_day($date) {
$add_day = 0;
do {
$add_day++;
$new_date = date('Y-m-d', strtotime("$date +$add_day Days"));
$new_day_of_week = date('w', strtotime($new_date));
} while($new_day_of_week == 6 || $new_day_of_week == 0);
return $new_date;
}
This function should ignore weekends (6 = Saturday and 0 = Sunday).
This function will calculate the business day in the future or past. Arguments are number of days, forward (1) or backwards(0), and a date. If no date is supplied todays date will be used:
// returned $date Y/m/d
function work_days_from_date($days, $forward, $date=NULL)
{
if(!$date)
{
$date = date('Y-m-d'); // if no date given, use todays date
}
while ($days != 0)
{
$forward == 1 ? $day = strtotime($date.' +1 day') : $day = strtotime($date.' -1 day');
$date = date('Y-m-d',$day);
if( date('N', strtotime($date)) <= 5) // if it's a weekday
{
$days--;
}
}
return $date;
}
What you need to do is:
Convert the provided date into a timestamp.
Use this along with the or w or N formatters for PHP's date command to tell you what day of the week it is.
If it isn't a "business day", you can then increment the timestamp by a day (86400 seconds) and check again until you hit a business day.
N.B.: For this is really work, you'd also need to exclude any bank or public holidays, etc.
I stumbled apon this thread when I was working on a Danish website where I needed to code a "Next day delivery" PHP script.
Here is what I came up with (This will display the name of the next working day in Danish, and the next working + 1 if current time is more than a given limit)
$day["Mon"] = "Mandag";
$day["Tue"] = "Tirsdag";
$day["Wed"] = "Onsdag";
$day["Thu"] = "Torsdag";
$day["Fri"] = "Fredag";
$day["Sat"] = "Lørdag";
$day["Sun"] = "Søndag";
date_default_timezone_set('Europe/Copenhagen');
$date = date('l');
$checkTime = '1400';
$date2 = date(strtotime($date.' +1 Weekday'));
if( date( 'Hi' ) >= $checkTime) {
$date2 = date(strtotime($date.' +2 Weekday'));
}
if (date('l') == 'Saturday'){
$date2 = date(strtotime($date.' +2 Weekday'));
}
if (date('l') == 'Sunday') {
$date2 = date(strtotime($date.' +2 Weekday'));
}
echo '<p>Næste levering: <span>'.$day[date("D", $date2)].'</span></p>';
As you can see in the sample code $checkTime is where I set the time limit which determines if the next day delivery will be +1 working day or +2 working days.
'1400' = 14:00 hours
I know that the if statements can be made more compressed, but I show my code for people to easily understand the way it works.
I hope someone out there can use this little snippet.
Here is the best way to get business days (Mon-Fri) in PHP.
function days()
{
$week=array();
$weekday=["Monday","Tuesday","Wednesday","Thursday","Friday"];
foreach ($weekday as $key => $value)
{
$sort=$value." this week";
$day=date('D', strtotime($sort));
$date=date('d', strtotime($sort));
$year=date('Y-m-d', strtotime($sort));
$weeks['day']= $day;
$weeks['date']= $date;
$weeks['year']= $year;
$week[]=$weeks;
}
return $week;
}
Hope this will help you guys.
Thanks,.
See the example below:
$startDate = new DateTime( '2013-04-01' ); //intialize start date
$endDate = new DateTime( '2013-04-30' ); //initialize end date
$holiday = array('2013-04-11','2013-04-25'); //this is assumed list of holiday
$interval = new DateInterval('P1D'); // set the interval as 1 day
$daterange = new DatePeriod($startDate, $interval ,$endDate);
foreach($daterange as $date){
if($date->format("N") <6 AND !in_array($date->format("Y-m-d"),$holiday))
$result[] = $date->format("Y-m-d");
}
echo "<pre>";print_r($result);
For more info: http://goo.gl/YOsfPX
You could do something like this.
/**
* #param string $date
* #param DateTimeZone|null|null $DateTimeZone
* #return \NavigableDate\NavigableDateInterface
*/
function getNextBusinessDay(string $date, ? DateTimeZone $DateTimeZone = null):\NavigableDate\NavigableDateInterface
{
$Date = \NavigableDate\NavigableDateFacade::create($date, $DateTimeZone);
$NextDay = $Date->nextDay();
while(true)
{
$nextDayIndexInTheWeek = (int) $NextDay->format('N');
// check if the day is between Monday and Friday. In DateTime class php, Monday is 1 and Friday is 5
if ($nextDayIndexInTheWeek >= 1 && $nextDayIndexInTheWeek <= 5)
{
break;
}
$NextDay = $NextDay->nextDay();
}
return $NextDay;
}
$date = '2017-02-24';
$NextBussinessDay = getNextBusinessDay($date);
var_dump($NextBussinessDay->format('Y-m-d'));
Output:
string(10) "2017-02-27"
\NavigableDate\NavigableDateFacade::create($date, $DateTimeZone), is provided by php library available at https://packagist.org/packages/ishworkh/navigable-date. You need to first include this library in your project with composer or direct download.
I used below methods in PHP, strtotime() does not work specially in leap year February month.
public static function nextWorkingDay($date, $addDays = 1)
{
if (strlen(trim($date)) <= 10) {
$date = trim($date)." 09:00:00";
}
$date = new DateTime($date);
//Add days
$date->add(new DateInterval('P'.$addDays.'D'));
while ($date->format('N') >= 5)
{
$date->add(new DateInterval('P1D'));
}
return $date->format('Y-m-d H:i:s');
}
This solution for 5 working days (you can change if you required for 6 or 4 days working). if you want to exclude more days like holidays then just check another condition in while loop.
//
while ($date->format('N') >= 5 && !in_array($date->format('Y-m-d'), self::holidayArray()))

PHP calculate age

I'm looking for a way to calculate the age of a person, given their DOB in the format dd/mm/yyyy.
I was using the following function which worked fine for several months until some kind of glitch caused the while loop to never end and grind the entire site to a halt. Since there are almost 100,000 DOBs going through this function several times a day, it's hard to pin down what was causing this.
Does anyone have a more reliable way of calculating the age?
//replace / with - so strtotime works
$dob = strtotime(str_replace("/","-",$birthdayDate));
$tdate = time();
$age = 0;
while( $tdate > $dob = strtotime('+1 year', $dob))
{
++$age;
}
return $age;
EDIT: this function seems to work OK some of the time, but returns "40" for a DOB of 14/09/1986
return floor((time() - strtotime($birthdayDate))/31556926);
This works fine.
<?php
//date in mm/dd/yyyy format; or it can be in other formats as well
$birthDate = "12/17/1983";
//explode the date to get month, day and year
$birthDate = explode("/", $birthDate);
//get age from date or birthdate
$age = (date("md", date("U", mktime(0, 0, 0, $birthDate[0], $birthDate[1], $birthDate[2]))) > date("md")
? ((date("Y") - $birthDate[2]) - 1)
: (date("Y") - $birthDate[2]));
echo "Age is:" . $age;
?>
$tz = new DateTimeZone('Europe/Brussels');
$age = DateTime::createFromFormat('d/m/Y', '12/02/1973', $tz)
->diff(new DateTime('now', $tz))
->y;
As of PHP 5.3.0 you can use the handy DateTime::createFromFormat to ensure that your date does not get mistaken for m/d/Y format and the DateInterval class (via DateTime::diff) to get the number of years between now and the target date.
$date = new DateTime($bithdayDate);
$now = new DateTime();
$interval = $now->diff($date);
return $interval->y;
I use Date/Time for this:
$age = date_diff(date_create($bdate), date_create('now'))->y;
Simple method for calculating Age from dob:
$_age = floor((time() - strtotime('1986-09-16')) / 31556926);
31556926 is the number of seconds in a year.
I find this works and is simple.
Subtract from 1970 because strtotime calculates time from 1970-01-01 (http://php.net/manual/en/function.strtotime.php)
function getAge($date) {
return intval(date('Y', time() - strtotime($date))) - 1970;
}
Results:
Current Time: 2015-10-22 10:04:23
getAge('2005-10-22') // => 10
getAge('1997-10-22 10:06:52') // one 1s before => 17
getAge('1997-10-22 10:06:50') // one 1s after => 18
getAge('1985-02-04') // => 30
getAge('1920-02-29') // => 95
// Age Calculator
function getAge($dob,$condate){
$birthdate = new DateTime(date("Y-m-d", strtotime(implode('-', array_reverse(explode('/', $dob))))));
$today= new DateTime(date("Y-m-d", strtotime(implode('-', array_reverse(explode('/', $condate))))));
$age = $birthdate->diff($today)->y;
return $age;
}
$dob='06/06/1996'; //date of Birth
$condate='07/02/16'; //Certain fix Date of Age
echo getAge($dob,$condate);
Write a PHP script to calculate the current age of a person.
Sample date of birth : 11.4.1987
Sample Solution:
PHP Code:
<?php
$bday = new DateTime('11.4.1987'); // Your date of birth
$today = new Datetime(date('m.d.y'));
$diff = $today->diff($bday);
printf(' Your age : %d years, %d month, %d days', $diff->y, $diff->m, $diff->d);
printf("\n");
?>
Sample Output:
Your age : 30 years, 3 month, 0 days
Figured I'd throw this on here since this seems to be most popular form of this question.
I ran a 100 year comparison on 3 of the most popular types of age funcs i could find for PHP and posted my results (as well as the functions) to my blog.
As you can see there, all 3 funcs preform well with just a slight difference on the 2nd function. My suggestion based on my results is to use the 3rd function unless you want to do something specific on a person's birthday, in which case the 1st function provides a simple way to do exactly that.
Found small issue with test, and another issue with 2nd method! Update coming to blog soon! For now, I'd take note, 2nd method is still most popular one I find online, and yet still the one I'm finding the most inaccuracies with!
My suggestions after my 100 year review:
If you want something more elongated so that you can include occasions like birthdays and such:
function getAge($date) { // Y-m-d format
$now = explode("-", date('Y-m-d'));
$dob = explode("-", $date);
$dif = $now[0] - $dob[0];
if ($dob[1] > $now[1]) { // birthday month has not hit this year
$dif -= 1;
}
elseif ($dob[1] == $now[1]) { // birthday month is this month, check day
if ($dob[2] > $now[2]) {
$dif -= 1;
}
elseif ($dob[2] == $now[2]) { // Happy Birthday!
$dif = $dif." Happy Birthday!";
};
};
return $dif;
}
getAge('1980-02-29');
But if you just simply want to know the age and nothing more, then:
function getAge($date) { // Y-m-d format
return intval(substr(date('Ymd') - date('Ymd', strtotime($date)), 0, -4));
}
getAge('1980-02-29');
See BLOG
A key note about the strtotime method:
Note:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at the
separator between the various components: if the separator is a slash (/),
then the American m/d/y is assumed; whereas if the separator is a dash (-)
or a dot (.), then the European d-m-y format is assumed. If, however, the
year is given in a two digit format and the separator is a dash (-, the date
string is parsed as y-m-d.
To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates or
DateTime::createFromFormat() when possible.
You can use the Carbon library, which is an API extension for DateTime.
You can:
function calculate_age($date) {
$date = new \Carbon\Carbon($date);
return (int) $date->diffInYears();
}
or:
$age = (new \Carbon\Carbon($date))->age;
If you want to caculate the Age of using the dob, you can also use this function.
It uses the DateTime object.
function calcutateAge($dob){
$dob = date("Y-m-d",strtotime($dob));
$dobObject = new DateTime($dob);
$nowObject = new DateTime();
$diff = $dobObject->diff($nowObject);
return $diff->y;
}
If you don't need great precision, just the number of years, you could consider using the code below ...
print floor((time() - strtotime("1971-11-20")) / (60*60*24*365));
You only need to put this into a function and replace the date "1971-11-20" with a variable.
Please note that precision of the code above is not high because of the leap years, i.e. about every 4 years the days are 366 instead of 365. The expression 60*60*24*365 calculates the number of seconds in one year - you can replace it with 31536000.
Another important thing is that because of the use of UNIX Timestamp it has both the Year 1901 and Year 2038 problem which means the the expression above will not work correctly for dates before year 1901 and after year 2038.
If you can live with the limitations mentioned above that code should work for you.
$birthday_timestamp = strtotime('1988-12-10');
// Calculates age correctly
// Just need birthday in timestamp
$age = date('md', $birthday_timestamp) > date('md') ? date('Y') - date('Y', $birthday_timestamp) - 1 : date('Y') - date('Y', $birthday_timestamp);
//replace / with - so strtotime works
$dob = strtotime(str_replace("/","-",$birthdayDate));
$tdate = time();
return date('Y', $tdate) - date('Y', $dob);
function dob ($birthday){
list($day,$month,$year) = explode("/",$birthday);
$year_diff = date("Y") - $year;
$month_diff = date("m") - $month;
$day_diff = date("d") - $day;
if ($day_diff < 0 || $month_diff < 0)
$year_diff--;
return $year_diff;
}
I have found this script reliable. It takes the date format as YYYY-mm-dd, but it could be modified for other formats pretty easily.
/*
* Get age from dob
* #param dob string The dob to validate in mysql format (yyyy-mm-dd)
* #return integer The age in years as of the current date
*/
function getAge($dob) {
//calculate years of age (input string: YYYY-MM-DD)
list($year, $month, $day) = explode("-", $dob);
$year_diff = date("Y") - $year;
$month_diff = date("m") - $month;
$day_diff = date("d") - $day;
if ($day_diff < 0 || $month_diff < 0)
$year_diff--;
return $year_diff;
}
i18n :
function getAge($birthdate, $pattern = 'eu')
{
$patterns = array(
'eu' => 'd/m/Y',
'mysql' => 'Y-m-d',
'us' => 'm/d/Y',
);
$now = new DateTime();
$in = DateTime::createFromFormat($patterns[$pattern], $birthdate);
$interval = $now->diff($in);
return $interval->y;
}
// Usage
echo getAge('05/29/1984', 'us');
// return 28
Try any of these using DateTime object
$hours_in_day = 24;
$minutes_in_hour= 60;
$seconds_in_mins= 60;
$birth_date = new DateTime("1988-07-31T00:00:00");
$current_date = new DateTime();
$diff = $birth_date->diff($current_date);
echo $years = $diff->y . " years " . $diff->m . " months " . $diff->d . " day(s)"; echo "<br/>";
echo $months = ($diff->y * 12) + $diff->m . " months " . $diff->d . " day(s)"; echo "<br/>";
echo $weeks = floor($diff->days/7) . " weeks " . $diff->d%7 . " day(s)"; echo "<br/>";
echo $days = $diff->days . " days"; echo "<br/>";
echo $hours = $diff->h + ($diff->days * $hours_in_day) . " hours"; echo "<br/>";
echo $mins = $diff->h + ($diff->days * $hours_in_day * $minutes_in_hour) . " minutest"; echo "<br/>";
echo $seconds = $diff->h + ($diff->days * $hours_in_day * $minutes_in_hour * $seconds_in_mins) . " seconds"; echo "<br/>";
Reference http://www.calculator.net/age-calculator.html
this is my function to calculating DOB with the specific return of age by year, month, and day
function ageDOB($y=2014,$m=12,$d=31){ /* $y = year, $m = month, $d = day */
date_default_timezone_set("Asia/Jakarta"); /* can change with others time zone */
$ageY = date("Y")-intval($y);
$ageM = date("n")-intval($m);
$ageD = date("j")-intval($d);
if ($ageD < 0){
$ageD = $ageD += date("t");
$ageM--;
}
if ($ageM < 0){
$ageM+=12;
$ageY--;
}
if ($ageY < 0){ $ageD = $ageM = $ageY = -1; }
return array( 'y'=>$ageY, 'm'=>$ageM, 'd'=>$ageD );
}
this how to use it
$age = ageDOB(1984,5,8); /* with my local time is 2014-07-01 */
echo sprintf("age = %d years %d months %d days",$age['y'],$age['m'],$age['d']); /* output -> age = 29 year 1 month 24 day */
This function will return the age in years. Input value is a date formated (YYYY-MM-DD) day of birth string eg: 2000-01-01
It works with day - precision
function getAge($dob) {
//calculate years of age (input string: YYYY-MM-DD)
list($year, $month, $day) = explode("-", $dob);
$year_diff = date("Y") - $year;
$month_diff = date("m") - $month;
$day_diff = date("d") - $day;
// if we are any month before the birthdate: year - 1
// OR if we are in the month of birth but on a day
// before the actual birth day: year - 1
if ( ($month_diff < 0 ) || ($month_diff === 0 && $day_diff < 0))
$year_diff--;
return $year_diff;
}
Cheers, nira
If you want to only get fullyears as age, there is a supersimple way on doing that. treat dates formatted as 'YYYYMMDD' as numbers and substract them. After that cancel out the MMDD part by dividing the result with 10000 and floor it down. Simple and never fails, even takes to account leapyears and your current server time ;)
Since birthdays or mostly provided by full dates on birth location and they are relevant to CURRENT LOCAL TIME (where the age check is actually done).
$now = date['Ymd'];
$birthday = '19780917'; #september 17th, 1978
$age = floor(($now-$birthday)/10000);
so if you want to check if someone is 18 or 21 or below 100 on your timezone (nevermind the origin timezone) by birthday, this is my way to do this
If you can't seem to use some of the newer functions, here's something I whipped up. Probably more than you need, and I'm sure there are better ways, but it's easy to read, so it should do the job:
function get_age($date, $units='years')
{
$modifier = date('n') - date('n', strtotime($date)) ? 1 : (date('j') - date('j', strtotime($date)) ? 1 : 0);
$seconds = (time()-strtotime($date));
$years = (date('Y')-date('Y', strtotime($date))-$modifier);
switch($units)
{
case 'seconds':
return $seconds;
case 'minutes':
return round($seconds/60);
case 'hours':
return round($seconds/60/60);
case 'days':
return round($seconds/60/60/24);
case 'months':
return ($years*12+date('n'));
case 'decades':
return ($years/10);
case 'centuries':
return ($years/100);
case 'years':
default:
return $years;
}
}
Example Use:
echo 'I am '.get_age('September 19th, 1984', 'days').' days old';
Hope this helps.
Due to leap year, it is not wise just to subtract one date from another and floor it to number of years. To calculate the age like the humans, you will need something like this:
$birthday_date = '1977-04-01';
$age = date('Y') - substr($birthday_date, 0, 4);
if (strtotime(date('Y-m-d')) - strtotime(date('Y') . substr($birthday_date, 4, 6)) < 0)
{
$age--;
}
The following works great for me and seems to be a lot simpler than the examples that have already been given.
$dob_date = "01";
$dob_month = "01";
$dob_year = "1970";
$year = gmdate("Y");
$month = gmdate("m");
$day = gmdate("d");
$age = $year-$dob_year; // $age calculates the user's age determined by only the year
if($month < $dob_month) { // this checks if the current month is before the user's month of birth
$age = $age-1;
} else if($month == $dob_month && $day >= $dob_date) { // this checks if the current month is the same as the user's month of birth and then checks if it is the user's birthday or if it is after it
$age = $age;
} else if($month == $dob_month && $day < $dob_date) { //this checks if the current month is the user's month of birth and checks if it before the user's birthday
$age = $age-1;
} else {
$age = $age;
}
I've tested and actively use this code, it might seem a little cumbersome but it is very simple to use and edit and is quite accurate.
Following the first logic, you have to use = in the comparison.
<?php
function age($birthdate) {
$birthdate = strtotime($birthdate);
$now = time();
$age = 0;
while ($now >= ($birthdate = strtotime("+1 YEAR", $birthdate))) {
$age++;
}
return $age;
}
// Usage:
echo age(implode("-",array_reverse(explode("/",'14/09/1986')))); // format yyyy-mm-dd is safe!
echo age("-10 YEARS") // without = in the comparison, will returns 9.
?>
It is a problem when you use strtotime with DD/MM/YYYY. You cant use that format. Instead of it you can use MM/DD/YYYY (or many others like YYYYMMDD or YYYY-MM-DD) and it should work properly.
How about launching this query and having MySQL calculating it for you:
SELECT
username
,date_of_birth
,(PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m') )) DIV 12 AS years
,(PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m') )) MOD 12 AS months
FROM users
Result:
r2d2, 1986-12-23 00:00:00, 27 , 6
The user has 27 years and 6 months (it counts an entire month)
I did it like this.
$geboortedatum = 1980-01-30 00:00:00;
echo leeftijd($geboortedatum)
function leeftijd($geboortedatum) {
$leeftijd = date('Y')-date('Y', strtotime($geboortedatum));
if (date('m')<date('m', strtotime($geboortedatum)))
$leeftijd = $leeftijd-1;
elseif (date('m')==date('m', strtotime($geboortedatum)))
if (date('d')<date('d', strtotime($geboortedatum)))
$leeftijd = $leeftijd-1;
return $leeftijd;
}
The top answer for this is OK but only calualtes the year a person was born, I tweaked it for my own purposes to work out the day and month. But thought it was worth sharing.
This works by taken a timestamp of the the users DOB, but feel free to change that
$birthDate = date('d-m-Y',$usersDOBtimestamp);
$currentDate = date('d-m-Y', time());
//explode the date to get month, day and year
$birthDate = explode("-", $birthDate);
$currentDate = explode("-", $currentDate);
$birthDate[0] = ltrim($birthDate[0],'0');
$currentDate[0] = ltrim($currentDate[0],'0');
//that gets a rough age
$age = $currentDate[2] - $birthDate[2];
//check if month has passed
if($birthDate[1] > $currentDate[1]){
//user birthday has not passed
$age = $age - 1;
} else if($birthDate[1] == $currentDate[1]){
//check if birthday is in current month
if($birthDate[0] > $currentDate[0]){
$age - 1;
}
}
echo $age;
Here is the process that is more simple and works both for the formats dd/mm/yyyy and dd-mm-yyyy. This is working great for me:
<?php
$birthday = '26/04/1994';
$dob = strtotime(str_replace("/", "-", $birthday));
$tdate = time();
echo date('Y', $tdate) - date('Y', $dob);
?>

Categories