DateTime and Time Attributes with AM PM time
Appearance
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]