## The Date Widget

Templating System : Widget Reference : Date

### Overview

The date widget provides a versatile HTML control for entering dates in a variety of formats. The widget operates in conjunction with various `template::util::date` functions in order to validate and manipulate the user's input. Please see the demo pages for some examples of the widget's behavior.

### The Date Object

The widget's value is a Date object, defined in `template::util::date`. The date object stores 7 fields: the year, month, day, hours, minutes, seconds, and the format in which these values should be displayed. The function `template::util::date::create` can be used to instantiate a blank date:

>     proc template::util::date::create {
>       {year {}} {month {}} {day {}} {hours {}}
>       {minutes {}} {seconds {}} {format "YYYY/MM/DD"}
>     } {
>       return [list $year $month $day $hours $minutes $seconds $format]
>     }

The two functions `template::util::date::get_property` and `template::util::date::set_property` are used to get or set the fields of a Date object. The `get_property` function accepts the desired field and the Date object, and returns the value of the field:

>     proc template::util::date::get_property { what date } {
>     ...
>     }

The `set_property` function accepts the field, the Date object and the new value, and returns the modified Date object:

>     proc template::util::date::set_property { what date value } {
>     ...
>     }

The fields which can be accessed or changed are summarized below:

Field | Get ? | Set ? | Meaning | Sample Value
--- | --- | --- | --- | ---
`year` | Yes | Yes | The 4-digit year | `2000`
`month` | Yes | Yes | The month, January = 1 | `8`
`day` | Yes | Yes | The day of month | `21`
`hours` | Yes | Yes | The hour, in 24-hour format | `23`
`minutes` | Yes | Yes | The minute | `59`
`seconds` | Yes | Yes | The second | `59`
`format` | Yes | Yes | The format (see below for a detailed explanation) | `YYYY/MM/DD`
`long_month_name` | Yes |  | The symbolic month name | `January`
`short_month_name` | Yes |  | The abbreviated month name | `Jan`
`days_in_month` | Yes |  | The number of days in the month stored in the Date object; will return an empty string if the month or the year are undefiend. Takes into account the leap years. | `29`
`short_year` | Yes | Yes | The 2-digit year. When mutating, 2000 is added to the year if it is less than 69; otherwise, 1900 is added to the year. | `99`
`short_hours` | Yes | Yes | The hour, in 12-hour format. When mutating, the hour is always assumed to be in the "a.m." range; the `ampm` field may be used to change this. | `3`
`ampm` | Yes | Yes | The meridian indicator: either `am` or `pm`. Can be used in conjunction with the `short_hour` field in order to completely specify the hour. | `am`
`not_null` | Yes |  | This field will be 1 if and only if at least one of the date fields (year, month, date, hours, minutes or seconds) is present in the Date object. Otherwise, this field will be 0. | `1`
`sql_date` | Yes |  | The SQL code fragment representing the date stored in the Date object. | `to_date('2000/08/12 11:15:00', 'YYYY/MM/DD HH24:MI:SS')`
`clock` | Yes | Yes | The value of the date in the same format as the value returned by the `clock seconds` function. The `clock` function appears to be locale-dependent and therefore unreliable; however, manipulating the clock value with `clock scan` is currently the only way to perform arithmetic operations on dates, such as adding a day, comparing two dates, etc. | (An integer representing the number of elapsed seconds)

For example, the following code produces the tomorrow's date in SQL:

>     # Create a blank date
>     set today_date [template::util::date::create]

>     # Get the tomorrow's date
>     set clock_value [clock scan "1 day" -base [clock seconds]]
>     set tomorrow_date [template::util::date::set_property \
>       clock $today_date $clock_value]

>     # Get the SQL value
>     set tomorrow_sql [template::util::date::get_property \
>       sql_date $tomorrow_date]

### The Date Element

The widget is created with the usual `template::element create` statement, with the datatype and widget set to `date`. In addition, the element requires a `-format` switch, which specifies the format for the date, as follows:

Option | Format | Meaning
--- | --- | ---
`-format long` | `YYYY/MM/DD HH24:MI:SS` | The full widget including the date and the time
`-format short` | `YYYY/MM/DD` | The widget capable of entering the date only, without the time
`-format time` | `HH24/MI/SS` | The widget capable of entering the time only, without the date
`-format american` | `MM/DD/YY` | The widget representing the more familiar American date
`-format expiration` | `DD/YY` | An expiration date, as it may appear on a credit card
`-format` custom string | Custom format | See below

Any other value for the `format` flag is interpreted as a custom format string. The custom format string should consist of format specifiers separated by any of `/\-.:` or spaces. The valid format specifiers are as follows:

Format Specifier | Field | Default Widget |
--- | --- | --- | ---
`YYYY` | `year` | Input box, 4 characters
`YY` | `short_year` | Input box, 2 characters
`MM` | `month` | Selection list
`MON` | `month` | Selection list of abbreviated month names
`MONTH` | `month` | Selection list of full month names
`DD` | `day` | Selection list
`HH12` | `short_hours` | Selection list from 1 to 12
`HH24` | `hours` | Selection list from 0 to 23
`MI` | `minutes` | Selection list from 0 to 60, skipping every 5 minutes
`SS` | `seconds` | Selection list from 0 to 60, skipping every 5 seconds
`AM` | `ampm` | Selection list of "A.M." and "P.M."

Any format specifier may be followed by a lowercase `t`, in order to force the widget to use an input box (instead of a selection list) for entering the specified date fragment.

The `-format` switch is required, but the date widget also supports the following optional switches:

Switch | Meaning | Example
--- | --- | ---
`-`field`_interval` interval | Specifies a custom interval for the given field, as a list of three values: the starting value, the ending value, and the step | `-minute_interval {0 59 5}`
`-help` | Causes the date widget to display a description of each date fragment widget showing the purpose of the widget, such as "Year" or "24-Hour" | `-help`

Examples of various Date widgets can be found on the demo pages.

templating@arsdigita.com