DateTime and Time Attributes with AM PM time
From Achievo/ATK Wiki
The modified atkTimeAttribute below allows display of time in AM PM format for atkTimeAttribute and atkDateTimeAttribute.
Usage to show AM/PM our for atkTimeAttribute:
$time = &$this->add(new atkTimeAttribute("stime",0,23,array("00","15","30","45"),"", 0),NULL,400); $time->setTimeFormat('12h'); // display hour in AM/PM format
Usage to show AM/PM our for atkDateTimeAttribute:
$modified_date = &$this->add(new atkDateTimeAttribute("modified_date", AF_HIDE_ADD | AF_READONLY),NULL,500); $modified_date->m_time->setTimeFormat('12h'); // display hour in AM/PM format
Modified class.atktimeattribute.inc from ATK 6.5.0
<?php /** * This file is part of the Achievo ATK distribution. * Detailed copyright and licensing information can be found * in the doc/COPYRIGHT and doc/LICENSE files which should be * included in the distribution. * * @package atk * @subpackage attributes * * @copyright (c)2000-2004 Ibuildings.nl BV * @license http://www.achievo.org/atk/licensing ATK Open Source License * * @version $Revision: 6185 $ * $Id: class.atktimeattribute.inc 6478 2009-08-22 03:49:07Z marc $ */ /** * Flags for atkTimeAttribute */ define("AF_TIME_SECONDS", AF_SPECIFIC_1); /** * The atkTimeAttribute class represents an attribute of a node * that has a selectbox to select from predefined time values. * * @author Wim Kosten <wim@ibuildings.nl> * @package atk * @subpackage attributes * */ class atkTimeAttribute extends atkAttribute { var $m_beginTime = 0; var $m_endTime = 23; var $m_steps = array("0","30"); var $m_default = ""; /* defines the format of the time in: 24h - display hour from 00 to 23 12h - display hour from 12am to 11pm */ var $m_timeFormat = "24h"; /** * Constructor * @param string $name Name of the attribute * @param int $beginTime Time to start with (eg 8) * @param int $endTime Time to end with (eg 24) * @param int|array $steps containing possible minute or seconds values (eg array("00","15","30","45")) * or the interval (eg 5 for 00,05,10,15, etc.) * if the flag AF_TIME_SECONDS is set, this is for seconds, the minutes will be range(0, 59) * else this is for the minutes and the seconds will not be displayed * @param string $default Start Time (exp: 20:30) * @param int $flags Flags for this attribute */ function atkTimeAttribute($name, $beginTime=0, $endTime=23, $steps=array("00","15","30","45"), $default="", $flags=0) { $this->atkAttribute($name,$flags); // base class constructor $this->m_beginTime = $beginTime; $this->m_endTime = $endTime; if (is_array($steps)) $this->m_steps = $steps; else $this->m_steps = $this->intervalToSteps($steps); $this->m_default = $default; } /* Jorge Garifuna 2/10/11 sets the time format @param string $m_timeFormat 24h - display hour from 00 to 23 12h - display hour from 12am to 11pm */ function setTimeFormat($m_timeFormat){ $this->m_timeFormat = $m_timeFormat; }// end function /** * Convert an interval (integer) to an array with steps. * * @param int $interval The interval to convert * @return array The array with steps. */ function intervalToSteps($interval) { $steps=array(); for ($i=0;$i<=59;$i++) { if ($i%$interval===0) { $steps[] = $i; } } return $steps; } /** * Converts a date string (HHMISS) to an * array with 2 fields (hours, minutes, seconds). * @param string $time the time string * @return array with 3 fields (hours, minutes, seconds) */ function timeArray($time) { return array("hours" => substr($time, 0, 2), "minutes" => substr($time, 2, 2), "seconds" => substr($time, 4, 2)); } /** * Display's text version of Record * @param array $record * @return text string of $record */ function display($record) { $value = $record[$this->fieldName()]; if ($value["hours"] === "") return ""; /* Jorge Garifuna 2/10/11 set AM/PM for display */ $ampmlabel =''; if($this->m_timeFormat=='12h'){ if($value["hours"]==0){ $value["hours"]='12'; $ampmlabel = 'am'; }elseif($value["hours"]>12){ $value["hours"] = ($value["hours"]-12); $ampmlabel = 'pm'; }else{ $ampmlabel = 'am'; }// end if AM/PM }// end if $tmp_time = sprintf("%02d:%02d", $value["hours"], $value["minutes"]); if ($value["seconds"] && $this->hasFlag(AF_TIME_SECONDS)) $tmp_time.=sprintf(":%02d", $value["seconds"]); return $tmp_time.$ampmlabel; } /** * Convert values from an HTML form posting to an internal value for * this attribute. * * For the regular atkAttribute, this means getting the field with the * same name as the attribute from the html posting. * * @param array $postvars The array with html posted values ($_POST, for * example) that holds this attribute's value. * @return String The internal value */ function fetchValue($postvars) { $result = $postvars[$this->fieldName()]; if(!is_array($result)) { $exploded = explode(":",$postvars[$this->fieldName()]); if (count($exploded)<=1) return ""; $result= array(); $result["hours"] = $exploded[0]; $result["minutes"]= $exploded[1]; if ($exploded[2]) $result["seconds"]= $exploded[2]; } else if (strlen($result['hours']) == 0 || strlen($result['minutes']) == 0) { return NULL; } else { $result = array( 'hours' => $result['hours'], 'minutes' => $result['minutes'], 'seconds' => $result['seconds'] ); } return $result; } /** * Returns a piece of html code that can be used in a form to edit this * attribute's value. * * @param array $record The record that holds the value for this attribute. * @param String $fieldprefix The fieldprefix to put in front of the name * of any html form element for this attribute. * @param String $mode The mode we're in ('add' or 'edit') * @return String A piece of htmlcode for editing this attribute */ function edit($record="", $fieldprefix="", $mode="") { if(($this->m_default=="NOW" && $this->m_ownerInstance->m_action=="add") || ($this->m_default=="" && $this->hasFlag(AF_OBLIGATORY))) { $this->m_default=date("H:i:s"); } $default = explode(":",$this->m_default); $id = $fieldprefix.$this->fieldName(); $field = $record[$this->fieldName()]; $onChangeCode = ''; if(count($this->m_onchangecode)) { $this->_renderChangeHandler($fieldprefix); $onChangeCode = ' onChange="' . $this->getHtmlId($fieldprefix) . '_onChange(this);"'; } // set vars for hour / minutes dropdowns $this->registerKeyListener($id.'[hours]', KB_CTRLCURSOR|KB_LEFTRIGHT); $this->registerKeyListener($id.'[minutes]', KB_CTRLCURSOR|KB_LEFTRIGHT); $this->registerKeyListener($id.'[seconds]', KB_CTRLCURSOR|KB_LEFTRIGHT); $m_hourBox = '<select id="'.$id.'[hours]" name="'.$id."[hours]\" class=\"atktimeattribute\"{$onChangeCode}>\n"; $m_minBox = '<select id="'.$id.'[minutes]" name="'.$id."[minutes]\" class=\"atktimeattribute\"{$onChangeCode}>\n"; $m_secBox = '<select id="'.$id.'[seconds]" name="'.$id."[seconds]\" class=\"atktimeattribute\"{$onChangeCode}>\n"; // set default values for both boxes // depends upon atkaction // if add/admin, use $default param, else use time in $record if (is_array($field)) { $m_defHour = $field["hours"]; $m_defMin = $field["minutes"]; $m_defSec = $field["seconds"]; } else { $m_defHour = $default[0]; $m_defMin = $default[1]; $m_defSec = $default[2]; } atkdebug("defhour=$m_defHour defmin=$m_defMin"); // generate hour dropdown if (!$this->hasflag(AF_OBLIGATORY)) $m_hourBox .= '<option value=""'.($m_defHour === "" ? ' selected' : '').'></option>'; for ($i=$this->m_beginTime;$i<=$this->m_endTime;$i++) { if ($m_defHour!=="" && ($i == $m_defHour)) { $sel = " selected"; } else { $sel = ""; } /* Jorge Garifuna 2/10/11 set AM/PM for display */ $tlabel = $i; if($this->m_timeFormat=='12h'){ if($i==0){ $tlabel = '12am'; }elseif($i>12){ $tlabel = ($i-12).'pm'; }else{ $tlabel = $i.'am'; }// end if AM/PM }// end if // $m_hourBox .= sprintf("<option value='%02d'%s>%02d</option>\n",$i,$sel,$i); $m_hourBox .= sprintf("<option value='%02d'%s>%s</option>\n",$i,$sel,$tlabel); } // generate minute dropdown if (!$this->hasflag(AF_OBLIGATORY)) $m_minBox .= '<option value=""'.($m_defMin === "" ? ' selected' : '').'></option>'; if ($this->hasFlag(AF_TIME_SECONDS)) { $minute_steps = range(00, 59); } else { $minute_steps = $this->m_steps; } for ($i=0;$i<=count($minute_steps)-1;$i++) { if($i!=0) $prev = $minute_steps[$i-1]; else $prev= -1; if ($minute_steps[$i] >= $m_defMin && $prev < $m_defMin&&($m_defMin!="")) { $sel = " selected"; } else { $sel = ""; } $m_minBox .= sprintf("<option value='%02d'%s>%02d</option>\n",$minute_steps[$i],$sel,$minute_steps[$i]); } // generate second dropdown if (!$this->hasFlag(AF_OBLIGATORY)) $m_secBox .= '<option value""'.($m_defSec === "" ? ' selected' : '').'></option>'; for ($i=0;$i<=count($this->m_steps)-1;$i++) { if($i!=0) $prev= $this->m_steps[$i-1]; else $prev= -1; if ($this->m_steps[$i] >= $m_defSec && $prev < $m_defSec&&($m_defSec!="")) { $sel = " selected"; } else { $sel = ""; } $m_secBox .= sprintf("<option value='%02d' %s>%02d</option>\n",$this->m_steps[$i],$sel,$this->m_steps[$i]); } // close dropdown structures $m_hourBox .= "</select>"; $m_minBox .= "</select>"; if($this->hasFlag(AF_TIME_SECONDS)) { $m_secBox .= "</select>"; $m_secBox = ":" . $m_secBox; } else { $m_secBox = "<input type=\"hidden\" name=\"".$fieldprefix.$this->fieldName()."[seconds]\" value=\"00\">\n"; } // assemble display version return $m_hourBox.":".$m_minBox.$m_secBox; } /** * Converts the internal attribute value to one that is understood by the * database. * * @param array $rec The record that holds this attribute's value. * @return String The database compatible value */ function value2db($rec) { $hours = $rec[$this->fieldName()]["hours"]; $minutes = $rec[$this->fieldName()]["minutes"]; $seconds = $rec[$this->fieldName()]["seconds"]; if ($hours=="" || $minutes=="" || ($this->hasFlag(AF_TIME_SECONDS) && $seconds=="")) return NULL; $result = sprintf("%02d",$hours).":".sprintf("%02d",$minutes).":".sprintf("%02d",$seconds); return $result; } /** * Convert database value to time array * @param array $rec database record with date field * @return array with 3 fields (hours:minutes:seconds) */ function db2value($rec) { if (strlen($rec[$this->fieldName()]) == 0 ) { $retval=NULL; } else { $retval = array("hours"=>substr($rec[$this->fieldName()], 0, 2), "minutes"=>substr($rec[$this->fieldName()], 3, 2), "seconds"=>substr($rec[$this->fieldName()], 6, 2)); } return $retval; } /** * Returns a piece of html code that can be used in a form to search values * @param array $record Array with fields * @param boolean $extended if set to false, a simple search input is * returned for use in the searchbar of the * recordlist. If set to true, a more extended * search may be returned for the 'extended' * search page. The atkAttribute does not * make a difference for $extended is true, but * derived attributes may reimplement this. * @param string $fieldprefix The fieldprefix of this attribute's HTML element. * @return piece of html code with a checkbox */ function search($record="", $extended=false, $fieldprefix="") { return parent::search($record, $extended, $fieldprefix); } /** * Retrieve the list of searchmodes supported by the attribute. * * @return array List of supported searchmodes */ function getSearchModes() { // exact match and substring search should be supported by any database. // (the LIKE function is ANSI standard SQL, and both substring and wildcard // searches can be implemented using LIKE) // Possible values //"regexp","exact","substring", "wildcard","greaterthan","greaterthanequal","lessthan","lessthanequal" return array("exact"); } /** * Checks if a value is valid. * * @param array $rec The record that holds the value for this * attribute. If an error occurs, the error will * be stored in the 'atkerror' field of the record. * @param String $mode The mode for which should be validated ("add" or * "update") */ function validate(&$rec, $mode) { $value = $rec[$this->fieldName()]; if ($this->hasFlag(AF_OBLIGATORY) && ($value["hours"]==-1 || $value['minutes']==-1)) { triggerError($rec, $this->fieldName(), 'error_obligatoryfield'); } } /** * Adds this attribute to database queries. * * Database queries (select, insert and update) are passed to this method * so the attribute can 'hook' itself into the query. * * @param atkQuery $query The SQL query object * @param String $tablename The name of the table of this attribute * @param String $fieldaliasprefix Prefix to use in front of the alias * in the query. * @param Array $rec The record that contains the value of this attribute. * @param int $level Recursion level if relations point to eachother, an * endless loop could occur if they keep loading * eachothers data. The $level is used to detect this * loop. If overriden in a derived class, any subcall to * an addToQuery method should pass the $level+1. * @param String $mode Indicates what kind of query is being processing: * This can be any action performed on a node (edit, * add, etc) Mind you that "add" and "update" are the * actions that store something in the database, * whereas the rest are probably select queries. */ function addToQuery(&$query, $tablename="", $fieldaliasprefix="", $rec="", $level, $mode) { if ($mode == "add" || $mode == "update") { $value = $this->value2db($rec); if($value == NULL) $query->addField($this->fieldName(),'NULL',"","",false); else $query->addField($this->fieldName(),$value,"","",!$this->hasFlag(AF_NO_QUOTES)); } else $query->addField($this->fieldName(),"",$tablename,$fieldaliasprefix,!$this->hasFlag(AF_NO_QUOTES)); } /** * Return the database field type of the attribute. * * @return String The 'generic' type of the database field for this * attribute. */ function dbFieldType() { return "time"; } /** * Returns a piece of html code that can be used in a form to display * hidden values for this attribute. * @param array $record Array with values * @param String $fieldprefix The fieldprefix to put in front of the name * of any html form element for this attribute. * @return Piece of htmlcode */ function hide($record="", $fieldprefix) { $field = $record[$this->fieldName()]; if (is_array($field)) foreach ($field as $key => $value) $result .= '<input type="hidden" name="'.$fieldprefix.$this->formName().'['.$key.']" '.'value="'.$value.'">'; else $result = '<input type="hidden" name="'.$fieldprefix.$this->formName().'" value="'.$field.'">'; return $result; } /** * Creates a searchcondition for the field, * was once part of searchCondition, however, * searchcondition() also immediately adds the search condition. * * @param atkQuery $query The query object where the search condition should be placed on * @param String $table The name of the table in which this attribute * is stored * @param mixed $value The value the user has entered in the searchbox * @param String $searchmode The searchmode to use. This can be any one * of the supported modes, as returned by this * attribute's getSearchModes() method. * @return String The searchcondition to use. */ function getSearchCondition(&$query, $table, $value, $searchmode) { // When we get $value as a substring, we autocomplete the time // So 9 becomes 09:00:00 and 11:15 becomes 11:15:00 if (!is_array($value)) { $retval = array("hours"=>substr($value, 0, 2), "minutes"=>substr($value, 3, 2), "seconds"=>substr($value, 6, 2)); if (!$retval["seconds"]) $retval["seconds"]="00"; if (!$retval["minutes"]) $retval["minutes"]="00"; if (strlen($retval["hours"])==1) $retval["hours"] = "0".$retval["hours"]; if (strlen($retval["minutes"])==1) $retval["minutes"] = "0".$retval["minutes"]; if (strlen($retval["seconds"])==1) $retval["seconds"] = "0".$retval["seconds"]; $value = implode(":",$retval); } return parent::getSearchCondition($query, $table, $value, $searchmode); } /** * Parse a timestring to an array * * @param string $stringvalue The time to parse * @return array array with hours, minutes and seconds */ function parseTime($stringvalue) { //Assuming hh:mm:ss $retval = array("hours"=>substr($stringvalue, 0, 2), "minutes"=>substr($stringvalue, 3, 2), "seconds"=>substr($stringvalue, 6, 2)); if (!$retval["seconds"]) $retval["seconds"]="00"; if (!$retval["minutes"]) $retval["minutes"]="00"; if (strlen($retval["hours"])==1) $retval["hours"] = "0".$retval["hours"]; if (strlen($retval["minutes"])==1) $retval["minutes"] = "0".$retval["minutes"]; if (strlen($retval["seconds"])==1) $retval["seconds"] = "0".$retval["seconds"]; return $retval; } } ?>
Until next time,
Jorge Garifuna [1]