Skip to page content or skip to Accesskey List.
Search evolt.org
evolt.org login: or register

Work

Main Page Content

Using PHP for Date Processing in Forms

Rated 3.68 (Ratings: 9) (Add your rating)

Log in to add a comment
(5 comments so far)

Want more?

 
Picture of jacksonyee

Jackson Yee

Member info | Full bio

User since: July 10, 2002

Last login: July 10, 2002

Articles written: 1

Introduction

One of the most time-consuming tasks of any web application developer is dealing with forms. Not only must you decide what information to place onto the form and design the HTML for it, but you also must validate the submitted form data and process it. Fortunately, server-side scripting languages such as Perl and PHP have made our lives much easier, as we can use them to handle repetitive tasks rather than placing the work on ourselves. In this article, we'll take a look at a common task for applications such as calendars and appointment books: handling dates and times.

Selecting Dates and Times

The easiest way for a developer to deal with dates and times is to have the user enter them in a text field as a specific format such as "yyyy-mm-dd," and use PHP's strtotime() function on them. As all user interface developers should know though, users have a habit of not doing what you tell them to do. They might enter in an invalid date without realizing it, or they might mix up the syntax and type "mm-dd-yy" as U.S. users are prone to doing. In order to alleviate the possibility of errors, the <select> element can be used to limit input to specific ranges and ensure proper formats.

By replacing a text field such as

Enter Date (ex: 2002-06-07):

with the select fields

Date (Year-Month-Day): 2000 2001 2002 - 1 2 3 4 5 6 7 8 9 10 11 12 - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

You can ensure that the input will be in the correct format and within the range that you specified.

Of course, it can become a real hassle to write out the various <select> and <option> tags every time you want to use a date field in a form, so why not have PHP do it for you? The following function will write out a select date field for you given a prefix for the fields, the method of the form, the beginning year of the range, and the ending year of the range.

function WriteDateSelect($BeginYear = 0, 
                         $EndYear = 0, 
                         $IsPosted = true,
                         $Prefix = '')
{
  if (! $BeginYear)
  {
    $BeginYear = date('Y');
  }
		
  if (! $EndYear)
  {
    $EndYear = $BeginYear;
  }
	
  $Year = $IsPosted 
          ? (int) $_POST[$Prefix . 'Year']
          : (int) $_GET[$Prefix . 'Year'];
  $Month = $IsPosted 
          ? (int) $_POST[$Prefix . 'Month']
          : (int) $_GET[$Prefix . 'Month'];
  $Day = $IsPosted 
          ? (int) $_POST[$Prefix . 'Day']
          : (int) $_GET[$Prefix . 'Day'];
	
  echo '
         ';
	
  for ($i = $BeginYear; $i ', $i, '
         ';
  }
	
  echo '-
        
          ';	

  for ($i = 1; $i ', $i, '
         ';
  }

  echo '-
        
          ';	

  for ($i = 1; $i ', $i, '
         ';
  }

  echo '
       ';
  return;
}

As it stands, you can call the function in the middle of your form like

&lt;?php WriteDateSelect(2000, 2002); ?&gt;

and it will generate the field 2000 2001 2002 - 1 2 3 4 5 6 7 8 9 10 11 12 - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 , which will make date development in forms substantially easier. A similar function can easily be written to obtain the time of day from the user, but as for right now, let's take a look through this function and see how it operates.

Using The WriteDateSelect() Function

There are four arguments to be passed into the function: $BeginYear, $EndYear, $IsPosted, and $Prefix. There are default parameters for all of them, so you could literally call the function without any arguments at all like WriteDateSelect(), and it would produce the default field allowing the user to choose the current year only. Otherwise, you'll need to actually specify values in the function call. If you leave out the

  • $BeginYear and $EndYear are pretty self-explanatory, as they are the beginning and end years of the year select element. Thus, if you wanted the user to be able to select years ranging from 1995 to 2005, you would call the function as WriteDateSelect(1995, 2005);. If you leave $BeginYear blank, the function will assume the beginning and ending years to be the current year, and if you leave $EndYear blank, the function will assume that the ending year is the same as the beginning year.
  • $IsPosted is a boolean value specifying whether you are using the POST method or the GET method for the form. The default is POST, but if you are using GET, you'll need to set this parameter to false.
  • $Prefix is used only when you have multiple date field on a simple form, such as a calendar event where you need the user to enter a beginning date and an ending date. If you have two form elements with the same name, the value of the latter one will replace the value of the earlier one when the form is submitted, meaning that there would be no way for you to know what the user entered in for the first field. $Prefix solves this problem by appending the specified string to the beginning of the select fields names, thus if you wanted to have a beginning date and an ending date, you would make two calls with different prefixes, and your form would now be able to distinguish the dates upon submission.

    Specifying two date fields in one form using the code
    WriteDateSelect(1995, 2005, true, 'Begin'); and
    WriteDateSelect(1995, 2005, true, 'End');

    Beginning Date: 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 - 1 2 3 4 5 6 7 8 9 10 11 12 - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    Ending Date: 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 - 1 2 3 4 5 6 7 8 9 10 11 12 - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

Retrieving the Submitted Date

So now you can easily place date select fields into forms and guarantee that the user will have to choose from a predetermined range of values. However, that's only half of the work that we need to do, since we also need to process the information after the form is submitted. In order to do so, we'll introduce another utility function: GetDateSelectString().

function GetDateSelectString($IsPosted = true,
                             $Prefix = '')
{
  if ($IsPosted)
  {
    return (int) $_POST[$Prefix . 'Year']
           . '-' . (int) $_POST[$Prefix . 'Month']
           . '-' . (int) $_POST[$Prefix . 'Day'];
  }

  return (int) $_GET[$Prefix . 'Year']
         . '-' . (int) $_GET[$Prefix . 'Month']
         . '-' . (int) $_GET[$Prefix . 'Day'];
}

As you can see, all this function does is to take the values in the POST or GET array, cast them to int to prevent any SQL injections, and then concatenate them together with dashes in between. Thus, if the user selected 2002 for the year, 5 for the month, and 12 for the day, this function will return the string "2002-5-12". This string can be used directly in a MySQL query statement such as

      
$PostedDate = GetDateSelectString();<br />
mysql_query("SELECT * FROM Table WHERE LastDate = '$PostedDate'");

since MySQL natively understands the "yyyy-mm-dd" syntax, or the string could be converted to a PHP timestamp via the strtotime() function if you require further processing.

Retaining Previous Values

If you glance through the code for the WriteDateSelect() function above, you might notice the lines which say

$Year = $IsPosted<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;? (int) $_POST[$Prefix . 'Year']<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: (int) $_GET[$Prefix . 'Year'];

and

if ($i == $Year)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo 'selected=&quot;yes&quot;';

The reason why these lines of code exist is that it's fairly common for a user to take more than one try to fill out a form correctly. Although you could use JavaScript to pre-validate the form client-side, that is not an guarantee that the data will be correct, as the user agent could not support JavaScript or have JavaScript disabled. Therefore, server-side validation is always needed for absolute assurance. The most common design is to have both the code which writes out the form and the code which validates and processes the form in the same script. In that way, if the user fails to complete a portion of the form, then the script writes out the form again for the user to make corrections.

Of course, the problem with this approach is that the form won't retain the previous data unless you explicitly write out the values which the user entered beforehand. That is exactly what these lines of code do: get the values of the elements from the $_POST or $_GET arrays, and then write out a selected attribute if the present option value matches that of the previous value. Thus, your users won't have to reselect the dates again, they will be happier, and you will be happier.

Downloading the Code

The code which I use in production is a bit different than the code posted here, as it has been organized into classes and some of the options have been moved into class variables. If you think that you would find it useful though, you can download it by going to my website and going to the section Downloads -> Jackson's Programs. I'm not posting a direct link because I may restructure the site in the future, but it will always be located in that section.

I'm current about to graduate from Virginia Tech in the U.S., and am also an aspiring web developer and long-time C++ programmer. For more information, please visit my website.

Class.DateForm

Submitted by newbienetwork on July 23, 2002 - 13:28.

A long while ago, I had to work on creating Date form elements as well, and I came up with this simple to use PHP Class. It handles the date and time elements for you, as well as handling the form elements if you submit the form, and then want to display the form elements again with the selected values. It's pretty nice, very simply, and I find it very handy. You can find it here: http://www.phpdeveloper.org/our_scripts.php under Class.DateForm

login or register to post comments

timestamps

Submitted by webqs on July 26, 2002 - 05:08.

when working with dates I find it easier to use timestamps rather than formatted date strings. Why? ease of use - I only have to worry about dealing with Integers within a database table and I can perform mathematical functions on them etc etc. When it comes time to display a human readable date I use the relevant PHP functions to format a string from the timestamp. For the uninitiated., PHP timestamps are - time() - are the number of seconds since 1-1-1970. rgds James

login or register to post comments

Timestamp Conversions

Submitted by jacksonyee on July 26, 2002 - 14:12.

Using timestamps is indeed much easier for doing calculations, but timestamps can be easily obtained from the formatted date string by using the strtotime() function as noted in the introduction to the article. If you need to do calculations on your submitted dates and times, then you can convert them to timestamps, but the advantage of returning a formatted date is that you can immediately display it to the user or use it within a MySQL query such as "SELECT * FROM Articles WHERE Date='$DateString'".

Also, very few people can read and understand timestamps ;-), and for a form, usability is key.

login or register to post comments

Validation is always required

Submitted by jma on October 30, 2002 - 13:51.

Date validation is always required, even if it is from dropdown menus. If you're able to select Feburary 31st, then the system is not performing well. Therefore the programmers must utilize JavaScript to warn the user about an error in the field, and they must program guard in their code to prevent any erroneous date to get through. "Fixing" the invalid dates to their closest valid date might seem a good solution, but it is not. It is more likely the user mis-selected either the month or the day and did not notice it, than that the user actually tried to enter invalid values.

Besides the validation issue, using dropdown menus -- preferrably with month names written out -- is the best way to avoid problems with international users who might write months and days in different order than you do.

login or register to post comments

Standard Date: YYYY-MM-DD

Submitted by g1smd on November 15, 2002 - 16:18.

The YYYY-MM-DD date format that you mention is defined in a whole host of official standards adopted around the world:

  • USA Standard: ANSI X3.30-1985(R1991)
  • USA Standard: NIST FIPS 4-1 [now FIPS 4-2]
  • Canada: CSA Z234.5:1989
  • European Norm: EN 28601:1992
  • Australia: AS 3802:1997
  • South Africa: ARP 010:1989
  • Austria: OENORM EN 28601
  • Belgium: NBN EN 28601 (1993)
  • Czech Republic: CSN EN 28601
  • Denmark: DS/EN 28601
  • Finland: SFS-EN 28601
  • France: NF EN 28601 (1993)
  • Germany: DIN EN 28601 (1993) & DIN 5008 (1996)
  • Greece: ELOT EN 28601
  • Iceland: IST EN 28601:1992
  • Ireland: IS/EN 28601:1993
  • Italy: UNI EN 28601 (1993)
  • Luxembourg: ITM-EN 28601
  • Netherlands: NEN ISO 8601 (1994) & NEN EN 28601 (1994)
  • Norway: NS-ISO 8601
  • Portugal: EN 28601
  • Spain: UNE EN 28601
  • Sweden: SS-EN 28601 (1991)
  • Switzerland: SN-EN 28601-1994
  • United Kingdom: BS EN 28601:1992 (replaces BS 7151)
  • Poland: PN-90/N-01204
  • Taiwan (ROC): CNS 7648
  • Thailand: TIS 1111-2535
  • China: GB/T 7408-94 = Adopted directly from ISO 8601:1988
  • Hong Kong: ISO 8601
  • India: IS 7900:1976 = Method for writing calendar dates in all numeric forms (IS 7900:1976 = ISO/R 2014:1971)
  • India: IS 10934:1984 = Representation of the time date (24 hr) - (IS 10934:1984 = ISO 3307:1975)
  • Japan: JIS X 0301-1992 [previously JIS X 0301-1977] = Identification Code of Dates
  • Japan: JIS X 0302-1977 = Identification Code of Times
  • Korea: KS A 5401-1972 = Writing of calendar dates in all-numeric form
  • Korea: KS A 5402-1986 = Numbering of weeks
  • Korea: KS C 5610-1992 = Identification code of dates and times
  • Philippines: PNS 293-1991 = Representation of date and times
  • Thailand: TIS 1111:2535 = Representation of Date and Time (1992).
  • ISO/R 2014:1971 = was revised to form ISO 2014:1976, and then replaced by ISO/IEC 8601:1988
  • ISO 3307:1975 = This standard is replaced by ISO 8601:1988
  • ISO 8601:1988 = has been replaced by ISO 8601:2000.

There is an RFC that also refers to this: RFC 3339.

login or register to post comments

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.orgEvolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.