1<?php 2/** 3 * DokuWiki Plugin relativetimehelper (Helper Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Michael Große <dokuwiki@cosmocode.de> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12class helper_plugin_relativetimehelper extends DokuWiki_Plugin { 13 14 const SECONDS_PER_YEAR = 31536000; 15 const SECONDS_PER_MONTH = 2635200; 16 const SECONDS_PER_WEEK = 604800; 17 const SECONDS_PER_DAY = 86400; 18 const SECONDS_PER_HOUR = 3600; 19 const SECONDS_PER_MINUTE = 60; 20 21 /** 22 * @param int $timestamp 23 * @param int $depth how fine the granularity should be 24 * @param int $now reference timestamp, defaults to time() 25 * @return string 26 */ 27 public function getRelativeTimeString($timestamp, $depth = 2, $now = null) { 28 if (!$now) { 29 $now = time(); 30 } 31 $timediff = abs($now - $timestamp); 32 $parts = array(); 33 $seconds = $timediff % $this::SECONDS_PER_MINUTE; 34 if ($seconds != 0) { 35 if ($seconds == 1) { 36 $parts[] = sprintf($this->getLang('second'), 1); 37 } else { 38 $parts[] = sprintf($this->getLang('seconds'), $seconds); 39 } 40 $timediff -= $seconds; 41 } else { 42 $parts[] = null; 43 } 44 45 $minuts = ($timediff % $this::SECONDS_PER_HOUR) / $this::SECONDS_PER_MINUTE; 46 if ($minuts != 0) { 47 if ($minuts == 1) { 48 array_unshift($parts, sprintf($this->getLang('minut'), 1)); 49 } else { 50 array_unshift($parts, sprintf($this->getLang('minuts'), $minuts)); 51 } 52 $timediff -= $timediff % $this::SECONDS_PER_HOUR; 53 } elseif ($timediff) { 54 array_unshift($parts, null); 55 } 56 57 $hours = ($timediff % $this::SECONDS_PER_DAY) / $this::SECONDS_PER_HOUR;; 58 if ($hours != 0) { 59 if ($hours == 1) { 60 array_unshift($parts, sprintf($this->getLang('hour'), 1)); 61 } else { 62 array_unshift($parts, sprintf($this->getLang('hours'), $hours)); 63 } 64 $timediff -= $timediff % $this::SECONDS_PER_DAY; 65 } elseif ($timediff) { 66 array_unshift($parts, null); 67 } 68 69 $days = ($timediff % $this::SECONDS_PER_WEEK) / $this::SECONDS_PER_DAY;; 70 if ($days != 0) { 71 if ($days == 1) { 72 array_unshift($parts, sprintf($this->getLang('day'), 1)); 73 } else { 74 array_unshift($parts, sprintf($this->getLang('days'), $days)); 75 } 76 $timediff -= $timediff % $this::SECONDS_PER_WEEK; 77 } elseif ($timediff) { 78 array_unshift($parts, null); 79 } 80 81 $weeks = $timediff / $this::SECONDS_PER_WEEK; // todo extend to cover months and years by date-calculation 82 if ($weeks != 0) { 83 if ($weeks == 1) { 84 array_unshift($parts, sprintf($this->getLang('week'), 1)); 85 } else { 86 array_unshift($parts, sprintf($this->getLang('weeks'), $weeks)); 87 } 88 } elseif ($timediff) { 89 array_unshift($parts, null); 90 } 91 92 while (count($parts) > $depth) { 93 array_pop($parts); 94 } 95 96 $parts = array_filter($parts); 97 98 if (count($parts) == 1) { 99 $relTime = $parts[0]; 100 } else { 101 $lastPart = array_pop($parts); 102 $relTime = join(', ', $parts) . ' ' . $this->getLang('and') . ' ' . $lastPart; 103 } 104 if ($now - $timestamp < 0) { 105 return sprintf($this->getLang('in future'), $relTime); 106 } 107 return sprintf($this->getLang('in past'), $relTime); 108 } 109 110 protected function round($number, $rounding){ 111 if ($rounding == 'ceil') { 112 return ceil($number); 113 } 114 if ($rounding == 'floor') { 115 return floor($number); 116 } 117 return round($number); 118 } 119 120} 121 122// vim:ts=4:sw=4:et: 123