Calendar dates, times of the day and timestamps (date-times) are
special data values, which are often only supported for the Gregorian calendar. We use the datatype names
Date
, TimeOfDay
and Timestamp
in
information design models.
Both JavaScript and Java have a built-in Date
class
that does actually not represent calendar
dates, but rather timestamps
(or date-times) in the specific form of
the number of milliseconds since 1 January, 1970 UTC.
JavaScript's Date
class allows to represent Gregorian
calendar timestamps in the interval of +/- 100 Million days or
approximately 285,000 years either forward or backward, from 01 January,
1970 UTC.
A JS data-time can be created in several ways:
var firstDateManOnMoon = new Date( 1969, 7, 20); var firstDateManOnMoon = new Date("1969-07-20"); var firstTimeManOnMoon = new Date ( 1969, 7, 20, 20, 18, 0) ; var firstTimeManOnMoon = new Date("1969-07-20T20:18:00");
A timestamp with the current date and time can be created in the following way:
var currentDateTime = new Date();
Assume that the Book
model class defined above has an
additional attribute publicationDate
, the values of which
have to be included in HTML tables and forms. While date/time
information items have to be formatted as strings in a human-readable
form on web pages, preferably in localized form based on the settings of
the user's browser, it's not a good idea to store date/time values in
this form in a database. Rather we use instances of the predefined
JavaScript class Date
for representing date/time values
internally and for storing them. The predefined functions
toISOString()
and toLocaleDateString()
can be
used for turning Date
values into ISO standard date/time
strings of the form "2015-01-27", or to localized date/time strings like
"27.1.2015" (for simplicity, we have omitted the time part in these
strings).
In summary, date/time values may be expressed in three different forms:
Internally, for storage and computations, as a
Date
value.
Internally, for annotating localized date/time strings, or
externally, for displaying a date/time value in a standard form,
as an ISO standard date/time string, e.g., with the help of
toISOString()
.
Externally, for displaying a date/time value in a localized
form, as a localized date/time string, e.g., with the help of
toLocaleDateString()
.
Since the calendar arithmetic and calendar date manipulation
functionality of the built-in Date
class is limited, using
a library like date-fns
may be helpful for doing more advanced calendar computations.
For showing a date/time value as an information item in a web
page, we can use the HTML <time>
element that allows
displaying a human-readable representation (typically a localized
date/time string) that is annotated with a standard (machine-readable)
form of the date/time value.
We illustrate the use of the <time>
element with the following
example of a web page that includes two <time>
elements: one for displaying a
fixed date, and another (initially empty) element for displaying the date of today, which is
computed with the help of a JavaScript function. In both cases we use the datetime
attribute for annotating the displayed human-readable date with the corresponding
machine-readable representation.
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta charset="UTF-8" /> <title>Using the HTML5 Time Element</title> <script src="assignDate.js"></script> <script>window.addEventListener("load", assignDate);</script> </head> <body> <h1>HTML5 Time Element</h1> <p>HTML 2.0 was published on <time datetime="1995-11-24">November 24, 1995</time>.</p> <p>Today is <time id="today" datetime=""></time>.</p> </body> </html>
This web page loads and executes the following JS function for
computing today's date as a Date
value and assigning its
ISO standard representation and its localized representation to the
<time>
element:
function assignDate() { var dateEl = document.getElementById("today"); var today = new Date(); dateEl.textContent = today.toLocaleDateString(); dateEl.setAttribute("datetime", today.toISOString()); }
For providing better support concerning the user input of a calendar date value in an
HTML form
-based user interface, HTML5 has introduced the input
element
types "date" and "time", which are supposed to instruct browsers to render special UI widgets
for picking a date or time. For instance, the following HTML form is supposed to be rendered
with a date picker widget as shown in Figure 13.2 below:
<form id="Person">
<p><label>Name: <input name="name" type="text"/></label></p>
<p><label>Date of birth:
<input name="dateOfBirth" type="date"/></label></p>
</form>
Unfortunately, in April 2017, a date picker widget has still not been implemented in the Firefox browser, so a progressive enhancement approach is required, where a date picker widget is created with the help of a JS library (like flatpickr) whenever the current browser does not provide one.
When the user has picked a date in a widget, the
input
element's value
attribute contains a
date string. A simple way to convert this string into a
Date
value is provided by using the DOM attribute
valueAsDate
like so:
var formEl = document.forms["Person"];
var dateOfBirth = formEl.dateOfBirth.valueAsDate;
In Java, we have two important built-in classes for dealing with date-times:
java.util.Calendar
is an abstract class, which provides methods for
dealing with calendar timestamps and
which has concrete subclasses for specific calendars like the GregorianCalendar
.
Notice that an instance of Calendar
is not a calendar, but a wrapped date-time
value. For getting a specific date or date-time, we can invoke the constructor of a suitable
calendar class with the desired values:
Calendar birthDate = new GregorianCalendar( 2017,3,26); Calendar birthDateTime = new GregorianCalendar( 2017,3,26, 20,18,32);
java.util.Date
is a class that represents timestamps (or date-times)
in the specific form of the number of milliseconds since 1 January, 1970 UTC. Most of the
methods and constructors of the Date
class have been depreciated (because they
do not support internationalization), but not the class itself. It is recommended to either
avoid using it and use a suitable Calendar
subclass instead of
Date
, or, if an instance of Date
is needed, create a
Date
object by first creating a Calendar
object and then
converting it to a Date
object with the help of the getTime
method:
Calendar calendarDateTime = new GregorianCalendar( 2017,3,26); Date dateTime = calendarDateTime.getTime();
For getting a Date
object that holds the
current date-time, we can use the constructor without
parameters:
Date currentDateTime = new Date();
It is important to notice that months are represented as integers in the range [0, 11], where 0 denotes the month January and 11 the month December. The days of the month are represented as integers in the range [1, 31]. The hours of the day are integers in the range [0, 23] and the minutes are integers in the range [0, 59].
In many cases, we need to deal directly with values for date-time
components like the month, day, hour and so on, instead of just having
these values wrapped in an object. The Calendar
class
defines the get
method, taking an integer parameter that
allows to specify the desired date-time component in the form of static
Calendar
properties. For example, if we need to extract the
current year, month, day, hour, minute and second, we use the following
code:
Calendar calendar = new GregorianCalendar( 2017,3,26, 20,18,32); // 26 March 2017, 20:18:32 int year = calendar.get( Calendar.YEAR); // 2017 int month = calendar.get( Calendar.MONTH); // 2 (=March) int dayOfMonth = calendar.get( Calendar.DAY_OF_MONTH); // 26 int hourOfDay = calendar.get( Calendar.HOUR_OF_DAY); // 20 int minute = calendar.get( Calendar.MINUTE); // 18 int second = calendar.get( Calendar.SECOND); // 32
For more about date/time handling in Java see Chua Hock-Chuan's Java Date webpage.
In an entity class with temporal attributes, having
Date
or Calendar
as their range, we use the
@Temporal
annotation:
@Entity
public class Person {
@Temporal( TemporalType.DATE)
private java.util.Date dateOfBirth;
@Temporal( TemporalType.TIMESTAMP)
private java.util.Calendar firstDayOfSchool;
}
The TemporalType
enumeration has three possible
values: DATE
, TIME
and TIMESTAMP
,
which allow to specify the serialization format used when a
Date
or Calendar
object is persisted in a
database. These values correspond to the classes
java.sql.Date
, java.sql.Time
and
java.sql.Timestamp
, all being subclasses of
java.util.Date
.
Rendering Date
-valued attributes requires using the JSF element
h:inputText
with the attribute p:type="date"
. This creates an HTML
input
element of type date
. For example, a person's
dateOfBirth
attribute can be rendered in a facelet like so:
<h:form id="createPersonForm"> ... <h:inputText id="dateOfBirth" p:type="date" value="#{person.dateOfBirth}"> <f:convertDateTime pattern="yyyy-MM-dd" /> </h:inputText> ... </h:form>
The JSF converter f:convertDateTime
allows specifying an output format for
date values. In the above example, we specify four digits for the year, two digits for the month
and two digits for the day (e.g., 2015-07-23).
As a result, the following HTML code is generated:
<input id="createPersonForm:dateOfBirth"
name="createPersonForm:dateOfBirth" type="date"/>