Forestville NSW Australia tel 0410 532 923 email toivo@totaldata.biz
The repetitive tasks of converting, validating and comparing date and time entries are defined here as functions. The date functions rely on the hard coded date format in an array, supporting three formats (dmY, mdY, Ymd). The date parameters are passed from the calling module to the validation routines.
The subroutine library subtimedate.php contains the following functions:
Call: sec_to_hhmm($seconds)
Returns: hh:mm
Purpose: Converts seconds to hours and minutes
<?php
/* subtimedate.php */
/* Time and Date Functions */
/* Copyright (C) 2005 Toivo Talikka */
/* ----------------------------------------------------*/
/* Modification history */
/* 09/12/05 TJT Initial version */
/* */
/* ----------------------------------------------------*/
/* ----------------------------------------------------*/
/* convert seconds to hours and minutes */
function sec_to_hhmm($seconds) {
if ($seconds >= 3600) {
$hours = floor($seconds/3600);
$remainder = $seconds % 3600;
} else {
$hours="0";
$remainder = $seconds;
}
$minutes = floor($remainder/60);
if ($minutes < "10") {
$minutes = "0$minutes";
}
return "$hours:$minutes";
}
Call: sec_to_hours($seconds)
Returns: hh.dec where hh = hours, dec = decimals
Purpose: Converts seconds to hours and decimals
/* ---------------------------------------------------------*/
/* convert seconds to hours and decimals */
function sec_to_hours($seconds) {
if ($seconds >= 3600) {
$hours = floor($seconds/3600);
$remainder = $seconds % 3600;
} else {
$hours="0";
$remainder = $seconds;
}
$decimals = 100*(round($remainder/3600,2));
if ($decimals < "10") {
$decimals = "0$decimals";
}
return "$hours.$decimals";
}
Call: get_date_format($format_key, $date_separator)
Returns:
Date format description, e.g. dd/mm/yyyy
Date format mask, e.g. d/m/Y
Day sequence number in the date format string
Month sequence number in the date format string
Year sequence number in the date format string
Purpose: Looks up the date format description from the date format array, using a format key like dmY as the argument. Uses the date separator character provided as input parameter and inserts it into the date format description and the date format mask. The sequence numbers of the day, month and year components of the date are also returned.
/* ---------------------------------------------------------*/
// get date format description, mask, date element mapping, insert date separator
function get_date_format($date_format_key, $date_sep) {
global $date_format_array;
list($date_format_description, $date_mask, $day_seq_out, $month_seq_out, $year_seq_out) = $date_format_array["$date_format_key"];
$date_format_desc_out = str_replace(" ","$date_sep", $date_format_description);
$date_mask_out = str_replace(" ","$date_sep", $date_mask);
return array($date_format_desc_out, $date_mask_out, $day_seq_out, $month_seq_out, $year_seq_out);
}
Call: get_long_date_format($format_key, $date_separator)
Returns: Date format mask, e.g. d/m/Y
Purpose: Looks up the date format description from the date format array, using a format key like dmY as the argument. Uses the date separator character provided as input parameter and inserts it into the date format mask.
/* ---------------------------------------------------------*/
// get long date format mask, insert date separator
function get_long_date_format($date_format_key, $date_sep) {
global $date_format_array;
list($date_format_description, $date_mask, $day_seq_out, $month_seq_out, $year_seq_out) = $date_format_array["$date_format_key"];
$date_mask_out = str_replace(" ","$date_sep", $date_mask);
return $date_mask_out;
}
Call: get_short_date_format($format_key, $date_separator)
Returns: Date format mask for day and month, e.g. d/m
Purpose: Looks up the date format description, from the date format array, using a format key like dmY as the argument. Uses the date separator character provided as input parameter and inserts it into the date format mask for day and month.
/* ---------------------------------------------------------*/
// get short date format mask, insert date separator
function get_short_date_format($date_format_key, $date_sep) {
global $date_format_array;
global $short_date_format_array;
list($date_format_description, $date_mask, $day_seq_out, $month_seq_out, $year_seq_out) = $date_format_array["$date_format_key"];
$short_date_mask = substr($date_mask, $short_date_format_array["$date_format_key"], 3);
$short_date_mask_out = str_replace(" ","$date_sep", $short_date_mask);
return $short_date_mask_out;
}
// columns 3 - 5 date element position mapping: day month year
// 0=day 1=month 2=year
$date_format_array = array (
"dmY" => array("dd mm YYYY", "d m Y", "0", "1", "2"),
"mdY" => array("mm dd YYYY", "m d Y", "1", "0", "2"),
"Ymd" => array("YYYY mm dd", "Y m d", "2", "1", "0")
);
// column 0 short date element start position in date mask
$short_date_format_array = array (
"dmY" => "0",
"mdY" => "0",
"Ymd" => "2"
);
Call: get_date($format_key, $separator)
Returns: Today's date and time in timestamp format, Y-m-d format and in local format, e.g. dd/mm/yyyy
Purpose: Looks up the date format description from the date format array, using a format key like dmY as the argument. Uses the date separator character provided as input parameter and inserts it into the date format mask for day and month.
/* --------------------------------------------------*/
/* get today's date */
/* return array with date 1 - date in date format */
/* 2 - yyyy-mm-dd */
/* 3 - date in local format */
function get_date($in_format, $in_separator) {
// default date separator and date format
if (!$in_separator) {
$in_separator = "/";
}
if (!$in_format) {
$in_format = "dmY";
}
// today's date in YYYY-mm-dd
$today = date('Y-m-d');
// local format
list($timestamp, $local_date) = make_local_date($today, $in_separator, $in_format);
return array($timestamp, $today, $local_date);
}
Call: valid_date($in_date, $separator, $format_key)
Returns: Valid date in yyyy-mm-dd or blank, valid date in local format or blank.
Purpose: Validates the date in local format and converts a valid date to yyyy-mm-dd. If the date is not valid, returns blank. The input date can be a full date in the local format, with the date separator character, or a short date with just the day and the month.
/* ---------------------------------------------------------*/
/* validate date in local format and convert to yyyy-mm-dd */
/* default separator= / default date format= dd/mm/yyyy */
/* accepts yy as 20yy, blank year as current year */
/* checkdate() ignores invalid characters e.g. 8:/3:/2004 */
/* return array with date 1 - yyyy-mm-dd */
/* 2 - date in local format */
function valid_date($in_date, $separator, $in_format) {
// default date separator and date format
if (!$separator) {
$separator = "/";
}
if (!$in_format) {
$in_format = "dmY";
}
// look up date format details from array
list($date_format_desc, $date_format_mask, $day_seq, $month_seq, $year_seq) = get_date_format($in_format, $separator);
$test_date = "";
$out_date = "";
$out_local_date = "";
// if no separators, date can be max 2 chars
if (strstr($in_date, $separator)) {
$date = explode($separator, $in_date);
$parts = count($date);
} elseif ( strlen($in_date) > 2) {
$parts = 0;
} else {
$parts = 1;
$date[0] = $in_date;
}
// if no year, use current year
// if only day is given, use current month and year
// if two parts, day and month - sequence from local date format
// if three parts - sequence from local date format
// if nothing, or case '0', reject date
switch($parts) {
case '1':
$day = $date[0];
$month = date("m");
$year = date("Y");
break;
// dependent on YYYY
case '2':
if ($in_format == "Ymd") {
$day_seq = 1;
$month_seq = 0;
}
$day = $date[$day_seq];
$month = $date[$month_seq];
$year = date("Y");
break;
case '3':
$day = $date[$day_seq];
$month = $date[$month_seq];
$year = $date[$year_seq];
break;
default:
$day = "0";
$month = "0";
$year = "0";
}
settype($day, "integer");
settype($month, "integer");
settype($year, "integer");
// if dd/mm/yy, add 2000 to year
if ($year < 100) {
$year = $year +2000;
}
// check day-month logic
$result = checkdate($month, $day, $year);
if ($result == 1) {
$test_date = "$year-";
$test_date .= "$month-";
$test_date .= "$day";
// strtime() converts to time format and tests the date
if (($timestamp = strtotime($test_date)) <> -1) {
$out_date = date('Y-m-d', $timestamp);
$out_local_date = date($date_format_mask, $timestamp);
}
}
return array($out_date, $out_local_date);
}
Call: make_std_date($in_date, $separator, $format_key)
Returns: Valid date in a timestamp format or null, in yyyy-mm-dd or blank, valid date in local format or blank.
Purpose: Validates the date in local format and converts it to a timestamp and to yyyy-mm-dd. If the date is not valid, returns blank. Uses valid_date to validate the date input variable.
/* ---------------------------------------------------------*/
/* validate date in local format and convert to yyyy-mm-dd */
/* accepts yy as 20yy, blank year as current year */
/* checkdate() ignores invalid characters e.g. 8:/3:/2004 */
/* return array with date 1 - date in date format */
/* 2 - yyyy-mm-dd */
/* 3 - date in local format */
function make_std_date($in_date, $separator, $in_format) {
// default date separator and date format
if (!$separator) {
$separator = "/";
}
if (!$in_format) {
$in_format = "dmY";
}
if (!$in_date) {
$in_date="";
}
list($date_format_desc, $date_format_mask, $day_seq, $month_seq, $year_seq) = get_date_format($in_format, $separator);
list($std_date, $local_date) = valid_date($in_date, $separator, $in_format);
if (($timestamp = strtotime($std_date)) === -1) {
$timestamp = "";
}
return array($timestamp, $std_date, $local_date);
}
Call: make_local_date($in_date, $separator, $format_key)
Returns: Date in timestamp format, date in local format.
Purpose: Converts the already validated date into local format and converts it also to a timestamp format.
/* --------------------------------------------------------------------------------------*/
/* accept an already validated date in std format yyyy-mm-dd and convert to local format */
/* return array with date 1 - date as a date variable */
/* 2 - date in local format */
function make_local_date($in_std_date, $separator, $in_local_format) {
// default date separator and date format
if (!$separator) {
$separator = "/";
}
if (!$in_local_format) {
$in_local_format = "dmY";
}
list($date_format_desc, $date_format_mask, $day_seq, $month_seq, $year_seq) = get_date_format($in_local_format, $separator);
// if date invalid, use today's date
$std_separator = "-";
if (!(strstr($in_std_date, $std_separator))) {
$in_std_date = date('Y-m-d');
}
$date = explode($std_separator, $in_std_date);
// reverse map of date components
$new_date[$day_seq] = $date[(2 - $day_seq)];
$new_date[$month_seq] = $date[(2 - $month_seq)];
$new_date[$year_seq] = $date[(2 - $year_seq)];
$local_date = implode($separator, $new_date);
$timestamp = strtotime($in_std_date);
return array($timestamp, $local_date);
}
Call: later_date($first_date, $second_date)
Returns: 1 or 0
Purpose: Returns 1 if the first date is later than the second date, otherwise 0.
/* ---------------------------------------------------------*/
/* check if first date later than second date, both already validated */
function later_date($first_date,$second_date) {
if ((strtotime($first_date)) > (strtotime($second_date))) {
return 1;
} else {
return 0;
}
}
Call: earlier_date($first_date, $second_date)
Returns: 1 or 0
Purpose: Returns 1 if the first date is earlier than the second date, otherwise 0.
/* ---------------------------------------------------------*/
/* check if first date is earlier than second date, both already validated */
function earlier_date($first_date,$second_date) {
if ((strtotime($first_date)) > (strtotime($second_date))) {
return 1;
} else {
return 0;
}
}
Call: equal_date($first_date, $second_date)
Returns: 1 or 0
Purpose: Returns 1 if the dates are equal, otherwise 0.
/* ---------------------------------------------------------*/
/* check if two dates are equal, both already validated */
function equal_date($first_date,$second_date) {
if ((strtotime($first_date)) == (strtotime($second_date))) {
return 1;
} else {
return 0;
}
}
Call: valid_time($in_time)
Returns: valid time as hh:mm or blank
Purpose: validates the time 00:00 - 24:59. If one or two digits are only entered, validates the input as hours.
/* ---------------------------------------------------------*/
/* validate time hh:mm */
/* settype() gets rid of non-numeric input */
/* range check for hours and minutes */
/* adds leading zeroes, max hh 24, min 59 */
/* hh interpreted as hh:00 */
/* returns valid time or blank */
function valid_time($in_time) {
// check if any separators
// if no separators, time can be max 2 chars
if (strstr($in_time,":")) {
$time = explode(":",$in_time);
$parts = count($time);
} elseif (strlen(trim($in_time)) > 2) {
$parts = 0;
} else {
$parts = 1;
$time[0] = trim($in_time);
}
switch($parts) {
case '1':
$hour = $time[0];
$min = "00";
break;
case '2':
$hour = $time[0];
$min = $time[1];
break;
default:
$hour = "99";
$min = "99";
}
$out_time="";
settype($hour,"integer");
settype($min,"integer");
if ( ! ((($hour >= 0) and ($hour <= 24)) and (($min >= 0) and ($min < 60)))) {
return $out_time;
}
if (strlen($hour) < 2) {
$out_time = "0";
}
$out_time .= "$hour:";
if (strlen($min) < 2) {
$out_time .= "0";
}
$out_time .= "$min";
return $out_time;
}
?>