X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fdatetime.php;h=6d395fe3f25d06611d2c4f047c63bcc94f00e085;hb=9b6e91086b29554fd04362f6c87ea148718e8b1c;hp=540c436912d67898c870059c9f93e58f1a154ac5;hpb=44b19841360099cc3e78d1a3612f7aa23e2e6524;p=friendica.git diff --git a/include/datetime.php b/include/datetime.php old mode 100644 new mode 100755 index 540c436912..6d395fe3f2 --- a/include/datetime.php +++ b/include/datetime.php @@ -1,18 +1,20 @@ '; $continent = $ex[0]; - $o .= ""; + $o .= ''; } if(count($ex) > 2) $city = substr($value,strpos($value,'/')+1); @@ -38,13 +40,13 @@ function select_timezone($current = 'America/Los_Angeles') { } else { $city = $ex[0]; - if($continent != 'Miscellaneous') { + if($continent != t('Miscellaneous')) { $o .= ''; - $continent = 'Miscellaneous'; - $o .= ""; + $continent = t('Miscellaneous'); + $o .= ''; } } - $city = str_replace('_', ' ', $city); + $city = str_replace('_', ' ', t($city)); $selected = (($value == $current) ? " selected=\"selected\" " : ""); $o .= ""; } @@ -52,48 +54,167 @@ function select_timezone($current = 'America/Los_Angeles') { return $o; }} +// return a select using 'field_select_raw' template, with timezones +// groupped (primarily) by continent +// arguments follow convetion as other field_* template array: +// 'name', 'label', $value, 'help' +if (!function_exists('field_timezone')){ +function field_timezone($name='timezone', $label='', $current = 'America/Los_Angeles', $help){ + $options = select_timezone($current); + $options = str_replace('','', $options); + + $tpl = get_markup_template('field_select_raw.tpl'); + return replace_macros($tpl, array( + '$field' => array($name, $label, $current, $help, $options), + )); + +}} + +// General purpose date parse/convert function. +// $from = source timezone +// $to = dest timezone +// $s = some parseable date/time string +// $fmt = output format if(! function_exists('datetime_convert')) { function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s") { - $d = new DateTime($s, new DateTimeZone($from)); - $d->setTimeZone(new DateTimeZone($to)); - return($d->format($fmt)); + + // Slight hackish adjustment so that 'zero' datetime actually returns what is intended + // otherwise we end up with -0001-11-30 ... + // add 32 days so that we at least get year 00, and then hack around the fact that + // months and days always start with 1. + + if(substr($s,0,10) == '0000-00-00') { + $d = new DateTime($s . ' + 32 days', new DateTimeZone('UTC')); + return str_replace('1','0',$d->format($fmt)); + } + + $d = new DateTime($s, new DateTimeZone($from)); + $d->setTimeZone(new DateTimeZone($to)); + return($d->format($fmt)); }} +// wrapper for date selector, tailored for use in birthday fields + function dob($dob) { list($year,$month,$day) = sscanf($dob,'%4d-%2d-%2d'); $y = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); - $o = datesel('',1920,$y,true,$year,$month,$day); + $f = get_config('system','birthday_input_format'); + if(! $f) + $f = 'ymd'; + $o = datesel($f,'',1920,$y,true,$year,$month,$day); return $o; } + +function datesel_format($f) { + + $o = ''; + + if(strlen($f)) { + for($x = 0; $x < strlen($f); $x ++) { + switch($f[$x]) { + case 'y': + if(strlen($o)) + $o .= '-'; + $o .= t('year'); + break; + case 'm': + if(strlen($o)) + $o .= '-'; + $o .= t('month'); + break; + case 'd': + if(strlen($o)) + $o .= '-'; + $o .= t('day'); + break; + default: + break; + } + } + } + return $o; +} + + +// returns a date selector. +// $f = format string, e.g. 'ymd' or 'mdy' +// $pre = prefix (if needed) for HTML name and class fields +// $ymin = first year shown in selector dropdown +// $ymax = last year shown in selector dropdown +// $allow_blank = allow an empty response on any field +// $y = already selected year +// $m = already selected month +// $d = already selected day + if(! function_exists('datesel')) { -function datesel($pre,$ymin,$ymax,$allow_blank,$y,$m,$d) { +function datesel($f,$pre,$ymin,$ymax,$allow_blank,$y,$m,$d) { $o = ''; - $o .= ""; + if($allow_blank) { + $sel = (($y == '0000') ? " selected=\"selected\" " : ""); + $o .= ""; + } + + if($ymax > $ymin) { + for($x = $ymax; $x >= $ymin; $x --) { + $sel = (($x == $y) ? " selected=\"selected\" " : ""); + $o .= ""; + } + } + else { + for($x = $ymax; $x <= $ymin; $x ++) { + $sel = (($x == $y) ? " selected=\"selected\" " : ""); + $o .= ""; + } + } + } + elseif($f[$z] == 'm') { + + $o .= " "; + return $o; +}} + +if(! function_exists('timesel')) { +function timesel($pre,$h,$m) { + + $o = ''; + $o .= " : "; @@ -101,59 +222,67 @@ function datesel($pre,$ymin,$ymax,$allow_blank,$y,$m,$d) { }} -// TODO rewrite this buggy sucker + + + + + + +// implements "3 seconds ago" etc. +// based on $posted_date, (UTC). +// Results relative to current timezone +// Limited to range of timestamps + +if(! function_exists('relative_date')) { function relative_date($posted_date) { $localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date); + + $abs = strtotime($localtime); - $in_seconds = strtotime($localtime); + if (is_null($posted_date) || $posted_date === '0000-00-00 00:00:00' || $abs === False) { + return t('never'); + } - $diff = time() - $in_seconds; + $etime = time() - $abs; + + if ($etime < 1) { + return t('less than a second ago'); + } + + $a = array( 12 * 30 * 24 * 60 * 60 => array( t('year'), t('years')), + 30 * 24 * 60 * 60 => array( t('month'), t('months')), + 7 * 24 * 60 * 60 => array( t('week'), t('weeks')), + 24 * 60 * 60 => array( t('day'), t('days')), + 60 * 60 => array( t('hour'), t('hours')), + 60 => array( t('minute'), t('minutes')), + 1 => array( t('second'), t('seconds')) + ); - $months = floor($diff/2592000); - $diff -= $months*2419200; - $weeks = floor($diff/604800); - $diff -= $weeks*604800; - $days = floor($diff/86400); - $diff -= $days*86400; - $hours = floor($diff/3600); - $diff -= $hours*3600; - $minutes = floor($diff/60); - $diff -= $minutes*60; - $seconds = $diff; - - if($months > 2) - return(datetime_convert('UTC',date_default_timezone_get(),$posted_date,'\o\n Y-m-d \a\t H:i:s')); - if ($months>0) { - // over a month old, - return 'over a month ago'; - } else { - if ($weeks>0) { - // weeks and days - $relative_date .= ($relative_date?', ':'').$weeks.' week'.($weeks!=1 ?'s':''); - - } elseif ($days>0) { - // days and hours - $relative_date .= ($relative_date?', ':'').$days.' day'.($days!=1?'s':''); - - } elseif ($hours>0) { - // hours and minutes - $relative_date .= ($relative_date?', ':'').$hours.' hour'.($hours!=1?'s':''); - - } elseif ($minutes>0) { - // minutes only - $relative_date .= ($relative_date?', ':'').$minutes.' minute'.($minutes!=1?'s':''); - } else { - // seconds only - $relative_date .= ($relative_date?', ':'').$seconds.' second'.($seconds!=1?'s':''); + foreach ($a as $secs => $str) { + $d = $etime / $secs; + if ($d >= 1) { + $r = round($d); + // translators - e.g. 22 hours ago, 1 minute ago + return sprintf( t('%1$d %2$s ago'),$r, (($r == 1) ? $str[0] : $str[1])); } } - // show relative date and add proper verbiage - return $relative_date.' ago'; -} +}} + + +// Returns age in years, given a date of birth, +// the timezone of the person whose date of birth is provided, +// and the timezone of the person viewing the result. +// Why? Bear with me. Let's say I live in Mittagong, Australia, and my +// birthday is on New Year's. You live in San Bruno, California. +// When exactly are you going to see my age increase? +// A: 5:00 AM Dec 31 San Bruno time. That's precisely when I start +// celebrating and become a year older. If you wish me happy birthday +// on January 1 (San Bruno time), you'll be a day late. + function age($dob,$owner_tz = '',$viewer_tz = '') { - if(strlen($dob) != 10) + if(! intval($dob)) return 0; if(! $owner_tz) $owner_tz = date_default_timezone_get(); @@ -170,3 +299,168 @@ function age($dob,$owner_tz = '',$viewer_tz = '') { $year_diff--; return $year_diff; } + + + +// Get days in month +// get_dim($year, $month); +// returns number of days. +// $month[1] = 'January'; +// to match human usage. + +if(! function_exists('get_dim')) { +function get_dim($y,$m) { + + $dim = array( 0, + 31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31); + + if($m != 2) + return $dim[$m]; + if(((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0)) + return 29; + return $dim[2]; +}} + + +// Returns the first day in month for a given month, year +// get_first_dim($year,$month) +// returns 0 = Sunday through 6 = Saturday +// Months start at 1. + +if(! function_exists('get_first_dim')) { +function get_first_dim($y,$m) { + $d = sprintf('%04d-%02d-01 00:00', intval($y), intval($m)); + return datetime_convert('UTC','UTC',$d,'w'); +}} + +// output a calendar for the given month, year. +// if $links are provided (array), e.g. $links[12] => 'http://mylink' , +// date 12 will be linked appropriately. Today's date is also noted by +// altering td class. +// Months count from 1. + + +// TODO: provide (prev,next) links, define class variations for different size calendars + + +if(! function_exists('cal')) { +function cal($y = 0,$m = 0, $links = false, $class='') { + + + // month table - start at 1 to match human usage. + + $mtab = array(' ', + 'January','February','March', + 'April','May','June', + 'July','August','September', + 'October','November','December' + ); + + $thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); + $thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m'); + if(! $y) + $y = $thisyear; + if(! $m) + $m = intval($thismonth); + + $dn = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); + $f = get_first_dim($y,$m); + $l = get_dim($y,$m); + $d = 1; + $dow = 0; + $started = false; + + if(($y == $thisyear) && ($m == $thismonth)) + $tddate = intval(datetime_convert('UTC',date_default_timezone_get(),'now','j')); + + $str_month = day_translate($mtab[$m]); + $o = ''; + $o .= ""; + for($a = 0; $a < 7; $a ++) + $o .= ''; + $o .= ''; + + while($d <= $l) { + if(($dow == $f) && (! $started)) + $started = true; + $today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : ''); + $o .= "'; + $dow ++; + if(($dow == 7) && ($d <= $l)) { + $dow = 0; + $o .= ''; + } + } + if($dow) + for($a = $dow; $a < 7; $a ++) + $o .= ''; + $o .= '
$str_month $y
' . mb_substr(day_translate($dn[$a]),0,3,'UTF-8') . '
"; + $day = str_replace(' ',' ',sprintf('%2.2d', $d)); + if($started) { + if(is_array($links) && isset($links[$d])) + $o .= "$day"; + else + $o .= $day; + $d ++; + } + else + $o .= ' '; + $o .= '
 
'."\r\n"; + + return $o; +}} + + +function update_contact_birthdays() { + + // This only handles foreign or alien networks where a birthday has been provided. + // In-network birthdays are handled within local_delivery + + $r = q("SELECT * FROM contact WHERE `bd` != '' AND `bd` != '0000-00-00' AND SUBSTRING(`bd`,1,4) != `bdyear` "); + if(count($r)) { + foreach($r as $rr) { + + logger('update_contact_birthday: ' . $rr['bd']); + + $nextbd = datetime_convert('UTC','UTC','now','Y') . substr($rr['bd'],4); + + /** + * + * Add new birthday event for this person + * + * $bdtext is just a readable placeholder in case the event is shared + * with others. We will replace it during presentation to our $importer + * to contain a sparkle link and perhaps a photo. + * + */ + + $bdtext = t('Birthday:') . ' [url=' . $rr['url'] . ']' . $rr['name'] . '[/url]' ; + + + $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`desc`,`type`,`adjust`) + VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%d' ) ", + intval($rr['uid']), + intval($rr['id']), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc(datetime_convert('UTC','UTC', $nextbd)), + dbesc(datetime_convert('UTC','UTC', $nextbd . ' + 1 day ')), + dbesc($bdtext), + dbesc('birthday'), + intval(0) + ); + + + // update bdyear + + q("UPDATE `contact` SET `bdyear` = '%s', `bd` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", + dbesc(substr($nextbd,0,4)), + dbesc($nextbd), + intval($rr['uid']), + intval($rr['id']) + ); + + } + } +}