39 function easy_datetime($then=
'')
42 if (!is_int($then))
return 0;
45 $now_date = date(
'Y-m-d');
46 $then_date = date(
'Y-m-d', $then);
48 if ($then_date == $now_date) {
50 return date(
'g:ia', $then).
' today';
54 if ($then_date == date(
'Y-m-d', $now - 86400)) {
56 return date(
'g:ia', $then).
' yesterday';
57 }
else if ($now - $then < 604800) {
59 return date(
'g:ia', $then).
' on '.date(
'l', $then);
63 if ($then_date == date(
'Y-m-d', $now + 86400)) {
65 return date(
'g:ia', $then).
' tomorrow';
66 }
else if ($then - $now < 604800) {
68 return date(
'g:ia', $then).
' this '.date(
'l', $then);
72 return date(
'g:ia \o\n jS F Y', $then);
88 function easy_time_total($secs=0, $full_format=FALSE, $return_array=FALSE, $units=Array(
'd',
'h',
'm',
's'))
91 if (!is_numeric($secs) || !is_bool($full_format) || !is_bool($return_array) || !is_array($units)) {
105 $hour = 60 * $minute;
115 $num_days = intval(floor($secs/$day));
117 $secs -= ($day * $num_days);
121 if ($secs >= $hour) {
122 $num_hours = intval(floor($secs/$hour));
124 $secs -= ($hour * $num_hours);
128 if ($secs >= $minute) {
129 $num_minutes = intval(floor($secs/$minute));
131 $secs -= ($minute * $num_minutes);
134 $num_seconds = $secs;
139 if (!in_array(
'd', $units)) $num_days = 0;
140 if (!in_array(
'h', $units)) $num_hours = 0;
141 if (!in_array(
'm', $units)) $num_minutes = 0;
142 if (!in_array(
's', $units)) $num_seconds = 0;
148 $str .= $num_days.
' day'.(($num_days > 1) ?
's' :
'');
155 }
else if (!$num_minutes && !$num_seconds) {
163 $str .= $joiner.$num_hours.
' hour'.(($num_hours > 1) ?
's' :
'');
168 if (!$num_days && !$num_hours) {
170 }
else if (!$num_seconds) {
178 $str .= $joiner.$num_minutes.
' minute'.(($num_minutes > 1) ?
's' :
'');
183 if (!$num_days && !$num_hours && !$num_minutes) {
190 $str .= $joiner.$num_seconds.
' second'.(($num_seconds > 1) ?
's' :
'');
193 }
else if (!$return_array) {
200 $str .= $num_days.
' day'.(($num_days > 1) ?
's' :
'');
207 }
else if ($num_minutes || $num_seconds) {
215 if (!$num_minutes && !$num_seconds) {
216 $time_type =
'hour'.(($num_hours > 1) ?
's' :
'');
221 $str .= $joiner.$num_hours;
224 if ($num_minutes || ($num_hours && $num_seconds)) {
227 if (!$num_days && !$num_hours) {
229 }
else if ($num_hours) {
232 }
else if ($num_seconds) {
240 if (!$num_hours && !$num_seconds) {
241 $time_type =
'minute'.(($num_minutes > 1) ?
's' :
'');
242 $str .= $joiner.$num_minutes;
244 $time_type .= $joiner.
'm';
247 $str .= $joiner.sprintf(
'%02d', $num_minutes);
249 $str .= $joiner.$num_minutes;
256 if (!$num_days && !$num_hours && !$num_minutes) {
258 }
else if ($num_hours || $num_minutes) {
266 if (!$num_hours && !$num_minutes) {
267 $time_type =
'second'.(($num_seconds > 1) ?
's' :
'');
268 $str .= $joiner.$num_seconds;
270 $time_type .= $joiner.
's';
271 $str .= $joiner.sprintf(
'%02d', $num_seconds);
276 $str .=
' '.((strstr($time_type,
':')) ?
'('.trim($time_type).
')' : trim($time_type));
282 $return_value = Array(
'd' => 0,
'h' => 0,
'm' => 0,
's' => 0);
284 if ($num_days) $return_value[
'd'] = $num_days;
285 if ($num_hours) $return_value[
'h'] = $num_hours;
286 if ($num_minutes) $return_value[
'm'] = $num_minutes;
287 if ($num_seconds) $return_value[
's'] = $num_seconds;
289 return $return_value;
320 function easy_short_relative_datetime($timestamp, $with_day=TRUE)
322 if (is_numeric($timestamp) === FALSE)
return FALSE;
323 $timestamp = (int)$timestamp;
325 $current_time = time();
326 $time_diff = $current_time - $timestamp;
327 $duration_bits = easy_time_total(abs($time_diff), FALSE, TRUE);
331 if (empty($duration_bits) === FALSE) {
332 if (strtotime(
'-1 year', $current_time) > $timestamp) {
333 $years = (int)date(
'Y', $current_time) - (int)date(
'Y', $timestamp);
334 if (date(
'm-d H:i:s', $current_time) < date(
'm-d H:i:s', $timestamp)) {
337 $duration_text = $years.
' year';
338 if ($years !== 1) $duration_text .=
's';
340 }
else if (strtotime(
'-1 year', $timestamp) > $current_time) {
341 $years = (int)date(
'Y', $timestamp) - (int)date(
'Y', $current_time);
342 if (date(
'm-d H:i:s', $timestamp) < date(
'm-d H:i:s', $current_time)) {
345 $duration_text = $years.
' year';
346 if ($years !== 1) $duration_text .=
's';
348 }
else if (strtotime(
'-1 month', $current_time) > $timestamp) {
349 $months = 12 * ((int)date(
'Y', $current_time) - (int)date(
'Y', $timestamp));
350 $months += (int)date(
'm', $current_time) - (int)date(
'm', $timestamp);
351 if (date(
'd H:i:s', $current_time) < date(
'd H:i:s', $timestamp)) {
354 $duration_text = $months.
' month';
355 if ($months !== 1) $duration_text .=
's';
357 }
else if (strtotime(
'-1 month', $timestamp) > $current_time) {
358 $months = 12 * ((int)date(
'Y', $timestamp) - (int)date(
'Y', $current_time));
359 $months += (int)date(
'm', $timestamp) - (int)date(
'm', $current_time);
360 if (date(
'd H:i:s', $timestamp) < date(
'd H:i:s', $current_time)) {
363 $duration_text = $months.
' month';
364 if ($months !== 1) $duration_text .=
's';
366 }
else if (abs($time_diff) >= 14*86400) {
367 $duration_text = floor(abs($time_diff) / (7*86400)).
' weeks';
368 }
else if (($with_day === TRUE) && (abs(strtotime(
'00:00:00 today', $current_time) - strtotime(
'00:00:00 today', $timestamp)) < 7*86400)) {
369 return easy_datetime($timestamp);
371 reset($duration_bits);
375 while (key($duration_bits) !== NULL) {
376 if (current($duration_bits) > 0) {
377 switch (key($duration_bits)) {
379 $duration_text = $duration_bits[
'd'].
' day';
380 if ($duration_bits[
'd'] !== 1) $duration_text .=
's';
384 $duration_text = $duration_bits[
'h'].
' hour';
385 if ($duration_bits[
'h'] !== 1) $duration_text .=
's';
389 $duration_text = $duration_bits[
'm'].
' minute';
390 if ($duration_bits[
'm'] !== 1) $duration_text .=
's';
394 $duration_text = $duration_bits[
's'].
' second';
395 if ($duration_bits[
's'] !== 1) $duration_text .=
's';
401 if ($duration_text !==
'') {
404 next($duration_bits);
409 if (empty($duration_text) === TRUE) $duration_text =
'now';
412 if ($add_ago === TRUE) {
413 if ($timestamp > $current_time) {
414 $duration_text .=
' in the future';
415 }
else if ($timestamp < $current_time) {
416 $duration_text .=
' ago';
422 return $duration_text;
434 function readable_datetime($then=NULL)
436 return (is_null($then)) ? date(
'jS M Y g:ia') : date(
'jS M Y g:ia', $then);
449 function is_leap_year($year=NULL)
451 if (is_null($year)) $year = (int) date(
'Y');
452 if ($year % 4 != 0)
return FALSE;
455 if ($year % 100 == 0)
return (($year / 100) % 4 == 0);
471 function days_in_month($month, $year)
473 if (is_null($month)) $month = (int) date(
'n');
474 if (is_null($year)) $year = (
int) date(
'Y');
478 return (is_leap_year($year)) ? 29 : 28;
495 trigger_error(
'UNKNOWN MONTH : '.$month, E_USER_ERROR);
514 function increment_date(&$day, &$month, &$year, $days_to_add=1)
516 if ($days_to_add < 0) {
517 decrement_date($day, $month, $year, -$days_to_add);
521 $day += $days_to_add;
522 while ($day > days_in_month($month, $year)) {
523 $day = $day - days_in_month($month, $year);
524 increment_month($month, $year);
543 function decrement_date(&$day, &$month, &$year, $days_to_sub=1)
545 if ($days_to_sub < 0) {
546 increment_date($day, $month, $year, -$days_to_sub);
550 $day = $day - $days_to_sub;
552 decrement_month($month, $year);
553 $day = days_in_month($month, $year) + $day;
571 function increment_month(&$month, &$year, $months_to_add=1)
573 if ($months_to_add < 0) {
574 decrement_month($month, $year, -$months_to_add);
578 $month += $months_to_add;
579 while ($month > 12) {
580 $month = $month - 12;
599 function decrement_month(&$month, &$year, $months_to_sub=1)
601 if ($months_to_sub < 0) {
602 increment_month($month, $year, -$months_to_sub);
606 $month = $month - $months_to_sub;
608 $month = 12 + $month;
624 function add_days_to_iso($iso, $days_to_add=1)
626 list($year,$month,$day) = sscanf($iso,
'%04d-%02d-%02d');
627 increment_date($day, $month, $year, $days_to_add);
628 return sprintf(
'%04d-%02d-%02d', $year, $month, $day);
642 function add_months_to_iso($iso, $months_to_add=1)
644 list($year,$month) = explode(
'-', $iso);
645 increment_month($month, $year, $months_to_add);
646 return sprintf(
'%04d-%02d', $year, $month);
666 function days_between_isos($higher, $lower)
668 $higher_ts = iso8601_ts(substr($higher,0,10));
669 $lower_ts = iso8601_ts(substr($lower,0,10));
672 return round(($higher_ts - $lower_ts) / 86400);
685 function int_to_roman($num=0)
688 10 => Array(
'X',
'C',
'M'),
689 5 => Array(
'V',
'L',
'D'),
690 1 => Array(
'I',
'X',
'C'),
696 $digit = (int) ($num / 1000);
697 $num -= $digit * 1000;
698 $roman = str_repeat(
'M',$digit);
700 for ($i = 2; $i >= 0; $i--) {
701 $power = pow(10, $i);
702 $digit = (int) ($num / $power);
703 $num -= $digit * $power;
705 if (($digit == 9) || ($digit == 4)) {
706 $roman .= $conv[1][$i].$conv[$digit+1][$i];
709 $roman .= $conv[5][$i];
714 $roman .= $conv[1][$i];
735 function weekday_dates_in_month($weekday, $month, $year)
737 $day = mktime(0, 0, 0, (
int) $month, 1, (
int) $year);
738 $first_weekday = (int) date(
'w', $day);
740 if ((
int) $weekday < $first_weekday) {
741 $day_add = 7 - $first_weekday + (int) $weekday;
743 $day_add = (int) $weekday - $first_weekday;
745 $day = strtotime(
'+'.$day_add.
' days', $day);
749 $days[] = date(
'd', $day);
750 $day = strtotime(
'+1 week', $day);
751 }
while ((
int) date(
'n', $day) == $month);
770 function iso8601_date_component($iso8601)
772 if (!is_iso8601($iso8601))
return FALSE;
773 if (substr($iso8601,0,10) ==
'----------') {
776 return substr($iso8601,0,10);
792 function iso8601_time_component($iso8601)
794 if (!is_iso8601($iso8601))
return FALSE;
795 if (strlen($iso8601) < 13)
return FALSE;
796 if (substr($iso8601,11) ==
'--:--:--')
return FALSE;
797 return substr($iso8601,11,8);
820 function is_iso8601($iso8601)
822 return (
boolean)preg_match(
"/^\-?[0-9\-]{4}-[0-9\-]{2}-[0-9\-]{2}([ T]([0-9\-]{2}\:?){3}(Z|([+-]([0-9\-]{2}\:?){2}))?)?$/",$iso8601);