X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fdatetime.php;h=ea98f01fe0999e63bc45400470f76c6fdb2c9a25;hb=18bd7f5eb7153726d616297981e04816798b5463;hp=15d688530c0136de198d182ea75fa484c014b429;hpb=35e29e10e69dfb086e990d852aa6b5006ce31d1b;p=friendica.git diff --git a/include/datetime.php b/include/datetime.php index 15d688530c..ea98f01fe0 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -1,23 +1,39 @@ '; usort($timezone_identifiers, 'timezone_cmp'); @@ -38,100 +54,349 @@ 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('_', ' ', t($city)); $selected = (($value == $current) ? " selected=\"selected\" " : ""); $o .= ""; - } + } $o .= ''; return $o; -}} +} -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)); -}} -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); - return $o; +/** + * @brief Generating a Timezone selector + * + * 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' + * + * @param string $name Name of the selector + * @param string $label Label for the selector + * @param string $current Timezone + * @param string $help Help text + * + * @return string Parsed HTML + */ +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), + )); + } -if(! function_exists('datesel')) { -function datesel($pre,$ymin,$ymax,$allow_blank,$y,$m,$d) { +/** + * @brief General purpose date parse/convert function. + * + * @param string $from Source timezone + * @param string $to Dest timezone + * @param string $s Some parseable date/time string + * @param string $fmt Output format recognised from php's DateTime class + * http://www.php.net/manual/en/datetime.format.php + * + * @return string Formatted date according to given format + */ +function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s") { - $o = ''; - $o .= " "; return $o; -}} +} + +/** + * @brief Returns a date selector + * + * @param string $format + * Format string, e.g. 'ymd' or 'mdy'. Not currently supported + * @param string $min + * Unix timestamp of minimum date + * @param string $max + * Unix timestap of maximum date + * @param string $default + * Unix timestamp of default date + * @param string $id + * ID and name of datetimepicker (defaults to "datetimepicker") + * + * @return string Parsed HTML output. + */ +function datesel($format, $min, $max, $default, $id = 'datepicker') { + return datetimesel($format,$min,$max,$default,'',$id,true,false, '',''); +} + +/** + * @brief Returns a time selector + * + * @param string $format + * Format string, e.g. 'ymd' or 'mdy'. Not currently supported + * @param $h + * Already selected hour + * @param $m + * Already selected minute + * @param string $id + * ID and name of datetimepicker (defaults to "timepicker") + * + * @return string Parsed HTML output. + */ +function timesel($format, $h, $m, $id='timepicker') { + return datetimesel($format,new DateTime(),new DateTime(),new DateTime("$h:$m"),'',$id,false,true); +} + +/** + * @brief Returns a datetime selector. + * + * @param string $format + * format string, e.g. 'ymd' or 'mdy'. Not currently supported + * @param string $min + * unix timestamp of minimum date + * @param string $max + * unix timestap of maximum date + * @param string $default + * unix timestamp of default date + * @param string $id + * id and name of datetimepicker (defaults to "datetimepicker") + * @param bool $pickdate + * true to show date picker (default) + * @param boolean $picktime + * true to show time picker (default) + * @param $minfrom + * set minimum date from picker with id $minfrom (none by default) + * @param $maxfrom + * set maximum date from picker with id $maxfrom (none by default) + * @param bool $required default false + * + * @return string Parsed HTML output. + * + * @todo Once browser support is better this could probably be replaced with + * native HTML5 date picker. + */ +function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) { + + // First day of the week (0 = Sunday) + $firstDay = get_pconfig(local_user(),'system','first_day_of_week'); + if ($firstDay === false) $firstDay=0; + + $lang = substr(get_browser_language(), 0, 2); + + // Check if the detected language is supported by the picker + if (!in_array($lang, array("ar", "ro", "id", "bg", "fa", "ru", "uk", "en", "el", "de", "nl", "tr", "fr", "es", "th", "pl", "pt", "ch", "se", "kr", "it", "da", "no", "ja", "vi", "sl", "cs", "hu"))) + $lang = ((isset($a->config['system']['language'])) ? $a->config['system']['language'] : 'en'); + $o = ''; + $dateformat = ''; + + if($pickdate) $dateformat .= 'Y-m-d'; + if($pickdate && $picktime) $dateformat .= ' '; + if($picktime) $dateformat .= 'H:i'; + + $minjs = $min ? ",minDate: new Date({$min->getTimestamp()}*1000), yearStart: " . $min->format('Y') : ''; + $maxjs = $max ? ",maxDate: new Date({$max->getTimestamp()}*1000), yearEnd: " . $max->format('Y') : ''; + + $input_text = $default ? date($dateformat, $default->getTimestamp()) : ''; + $defaultdatejs = $default ? ",defaultDate: new Date({$default->getTimestamp()}*1000)" : ''; + + $pickers = ''; + if(!$pickdate) $pickers .= ',datepicker: false'; + if(!$picktime) $pickers .= ',timepicker: false'; + + $extra_js = ''; + $pickers .= ",dayOfWeekStart: ".$firstDay.",lang:'".$lang."'"; + if($minfrom != '') + $extra_js .= "\$('#id_$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})"; + if($maxfrom != '') + $extra_js .= "\$('#id_$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})"; + + $readable_format = $dateformat; + $readable_format = str_replace('Y','yyyy',$readable_format); + $readable_format = str_replace('m','mm',$readable_format); + $readable_format = str_replace('d','dd',$readable_format); + $readable_format = str_replace('H','HH',$readable_format); + $readable_format = str_replace('i','MM',$readable_format); -if(! function_exists('relative_date')) { -function relative_date($posted_date) { + $tpl = get_markup_template('field_input.tpl'); + $o .= replace_macros($tpl,array( + '$field' => array($id, $label, $input_text, '', (($required) ? '*' : ''), 'placeholder="' . $readable_format . '"'), + )); - $localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date); + $o .= ""; + + return $o; +} + +/** + * @brief Returns a relative date string. + * + * Implements "3 seconds ago" etc. + * Based on $posted_date, (UTC). + * Results relative to current timezone. + * Limited to range of timestamps. + * + * @param string $posted_date + * @param string $format (optional) Parsed with sprintf() + * %1$d %2$s ago, e.g. 22 hours ago, 1 minute ago + * + * @return string with relative date + */ +function relative_date($posted_date,$format = null) { + + $localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date); $abs = strtotime($localtime); + + if (is_null($posted_date) || $posted_date === '0000-00-00 00:00:00' || $abs === False) { + return t('never'); + } + $etime = time() - $abs; - + if ($etime < 1) { return t('less than a second ago'); } - + + /* + $time_append = ''; + if ($etime >= 86400) { + $time_append = ' ('.$localtime.')'; + } + */ + $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')) + 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')) ); - + foreach ($a as $secs => $str) { - $d = $etime / $secs; - if ($d >= 1) { - $r = round($d); - return $r . ' ' . (($r == 1) ? $str[0] : $str[1]) . t(' ago'); - } - } -}} + $d = $etime / $secs; + if ($d >= 1) { + $r = round($d); + // translators - e.g. 22 hours ago, 1 minute ago + if(! $format) + $format = t('%1$d %2$s ago'); + return sprintf( $format,$r, (($r == 1) ? $str[0] : $str[1])); + } + } +} +/** + * @brief Returns timezone correct age in years. + * + * Returns the 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. + * + * @param string $dob Date of Birth + * @param string $owner_tz (optional) Timezone of the person of interest + * @param string $viewer_tz (optional) Timezone of the person viewing + * + * @return int Age in years + */ function age($dob,$owner_tz = '',$viewer_tz = '') { if(! intval($dob)) return 0; @@ -148,5 +413,195 @@ function age($dob,$owner_tz = '',$viewer_tz = '') { if(($curr_month < $month) || (($curr_month == $month) && ($curr_day < $day))) $year_diff--; + return $year_diff; } + +/** + * @brief Get days of a month in a given year. + * + * Returns number of days in the month of the given year. + * $m = 1 is 'January' to match human usage. + * + * @param int $y Year + * @param int $m Month (1=January, 12=December) + * + * @return int Number of days in the given month + */ +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]; +} + +/** + * @brief Returns the first day in month for a given month, year. + * + * Months start at 1. + * + * @param int $y Year + * @param int $m Month (1=January, 12=December) + * + * @return string day 0 = Sunday through 6 = Saturday + */ +function get_first_dim($y,$m) { + $d = sprintf('%04d-%02d-01 00:00', intval($y), intval($m)); + + return datetime_convert('UTC','UTC',$d,'w'); +} + +/** + * @brief 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. + * + * @param int $y Year + * @param int $m Month + * @param bool $links (default false) + * @param string $class + * + * @return string + * + * @todo Provide (prev,next) links, define class variations for different size calendars + */ +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; +} + +/** + * @brief Create a birthday event. + * + * Update the year and the birthday. + */ +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 = sprintf( t('%s\'s birthday'), $rr['name']); + $bdtext2 = sprintf( t('Happy Birthday %s'), ' [url=' . $rr['url'] . ']' . $rr['name'] . '[/url]') ; + + $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`,`adjust`) + VALUES ( %d, %d, '%s', '%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($bdtext2), + dbesc('birthday'), + intval(0) + ); + + + // update bdyear + + q("UPDATE `contact` SET `bdyear` = '%s', `bd` = '%s' WHERE `uid` = %d AND `id` = %d", + dbesc(substr($nextbd,0,4)), + dbesc($nextbd), + intval($rr['uid']), + intval($rr['id']) + ); + + } + } +}