4. Calendar Dates and Times

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.

4.1. Using JavaScript's Date class

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:

  1. Internally, for storage and computations, as a Date value.

  2. 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().

  3. 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.

4.2. Calendar dates and times in the user interface

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>

Figure 13.2. The date picker widget rendered by the Google Chrome browser.

The date picker widget rendered by the Google Chrome browser.

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;

4.3. Using Java's Date and Calendar classes

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.

4.4. Using Date and Calendar with JPA

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.

4.5. Rendering Date Attributes with JSF

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"/>