Home : Course Map : Chapter 10 : Java :
Calendar, Dates & Time
JavaTech
Course Map
Chapter 10

Introduction
Vector/Enumeration
Hashtable,HashMap
   Properties
Collections

Iterator/ArrayList
Generics
Preferences API
  Demo 1
Concurrency Utils
Enumerated Type
Arrays Class
String Tools
  String
  StringBuffer
  StringBuilder
  StringTokenizer
  String.split()

Calendar,Date,Time
  Demo 2
  Demo 3

Other Utilities
Exercises

    Supplements
Performance
Benchmarks
     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

The core language offers several classes for dealing with dates and times:

  • java.util.GregorianCalendar (a subclass of the abstract Calendar class.)
  • java.util.Date
  • java.text.DateFormat and its subclass java.text.SimpleDateFormat

The GregorianCalendar can be used to represent a specific date according to the Gregorian calendar (and the Julian calendar before that). Methods are provided to compare calendar objects such as whether one date came before or after another. The java.util.Calendar cbase class, which is abstract, holds static methods that give information such as the current date and time. For example,

Calendar this_moment = Calendar.getInstance ();

The hierarchy implies that there could be other calendar subclasses, e.g. Chinese, but none has appeared in the core language as of version 5.0.

If you look at the API Specifications for the Date class you will see that most of its methods have been deprecated. As of version 1.1 java.text.DateFormat took over most of duties of the Date class, which now essentially just holds a date/time value.

The class DateFormat can generate several date and time strings. Many variations of date representations are available. There are also a number of methods for dealing with Time Zone settings and internationalization of the strings.

The class DateFormatPanel, shown below in demo ClockTimer1, displays the time. Each time the panel is repainted, it displays the current time. See Chapter 8 :Tech : Timers for a discussion of the timer classes. In Chapter 8: Java: Demo : Clock we used a thread instead of a timer to periodically redraw DataFormatPanel. (See also ClockTimer2, which uses the Swing timer class.)

ClockTimer1
+ DataFormatPanel

import javax.swing.*;
import java.awt.*;
import java.text.*;
import java.util.*;

/**
  * This JPanel subclass uses the DateFormat class
  * to display the current time.
 **/
class DateFormatPanel extends JPanel {
  DateFormat fDateFormat = null;
  boolean fFirstPass = true;
  int fMsgX = 0, fMsgY = 0;
  Font fFont = new Font ("Serif", Font.BOLD, 24);

  /** Get the DateFormat object with the default time style. **/
  DateFormatPanel () {
    fDateFormat =
      DateFormat.getTimeInstance (DateFormat.DEFAULT);
  } // ctor

  /** Draw the time string on the panel center. **/
  public void paintComponent (Graphics g) {
    super.paintComponent (g);

    // Get current date object
    Date now = new Date ();

    // Format the time string.
    String date_out = fDateFormat.format (now);

    // Use our choice for the font.
    g.setFont (fFont);

    // Do the size and placement calculations only for the
    // first paint  (assumes the applet window is never resized.)
    if (fFirstPass) {

       // Get measures needed to center the message
      FontMetrics fm = g.getFontMetrics ();

      // How many pixels wide is the string
      int msg_width = fm.stringWidth (date_out);

      // Use the string width to find the starting point
      fMsgX = getSize ().width/2 - msg_width/2;

      // How far above the baseline can the font go?
      int ascent = fm.getMaxAscent ();

      // How far below the baseline?
      int descent= fm.getMaxDescent ();

      // Use the vertical height of this font to find
      // the vertical starting coordinate
      fMsgY = getSize ().height/2 - descent/2 + ascent/2;
    }
    g.drawString (date_out,fMsgX,fMsgY);
    fFirstPass = false;
  } // paintComponent

}// class DateFormatPanel

import javax.swing.*;
import java.awt.*;
import java.util.*;

/**
  * This applet uses java.util.Timer with an instance of a
  * java.util.TimerTask subclass to run a digital clock.
 **/
public class ClockTimer1 extends JApplet {
  java.util.Timer fTimer = null;
  // Need panel reference in run ().
  DateFormatPanel fClockPanel = null;

  public void init () {
    Container content_pane = getContentPane ();

    // Create an instance of DrawingPanel
    fClockPanel = new DateFormatPanel ();

    // Add the DrawingPanel to the contentPane.
    content_pane.add (fClockPanel);
  }

  /** Applet start() method called by browser. **/
  public void start () {
    // Create a timer.
    fTimer = new java.util.Timer ();

    // Start the timer immediately and then repeat calls
    // to run in UpdateTask object every second.
    fTimer.schedule (new UpdateTask (), 0, 1000);
  }

  /** Stop clock when web page unloaded. **/
  public void stop () {
    // Stop the clock updates.
    fTimer.cancel ();
  }

  /** Use the inner class technique to define the
    * TimerTask subclass to update the clock.
   **/
  class UpdateTask extends java.util.TimerTask {
    public void run () {
      fClockPanel.repaint ();
    }
  }
}// class ClockTimer1

 

The DateFormatPanel class uses an instance of DateFormat obtained with the factory method getTimeInstance (int style). The style of the date and time output is obtained with the DateFormat constants.

The Java 2 API Specifications for this class list the style constants. Here we chose for the time format the DateFormat.DEFAULT style. What this actually means varies somewhat with the locale setting (see the Sun tutorial on internationalization of Java programs). In the USA the default style results in a time string such as "5:30:33 PM".

The DateFormat subclass SimpleDateFormat offers somewhat more explicit formatting options. Data and time formats are chosen with a string pattern. The API Specification for the SimpleDateFormat provides a table of symbols for use in the format patterns. For example, in the example below, the pattern

   "EEE, d MMM yyyy HH:mm:ss Z"

produces a time format like

    Wed, 26 Mar 2003 15:34:35 -0500

where the latter number, -0500, indicates a time zone 5 hours earlier than GMT.

The demo ClockTimer3 shown below, uses the JPanel subclass SimpleDateFormatPanel to display the date and time with the SimpleDateFormat class. The ClockTimer3 class is identitical to ClockTimer1 except for loading the different panel class.

ClockTimer3
+ SimpleDataFormatPanel

import javax.swing.*;
import java.awt.*;
import java.text.*;
import java.util.*;

/**
  * This JPanel subclass uses the SimpleDateFormat class
  * to display the current date and time.
 **/
public class SimpleDateFormatPanel extends JPanel
{
  SimpleDateFormat fSDateFormat = null;
  boolean fFirstPass =true;
  int fMsgX = 0, fMsgY = 0;
  Font fFont = new Font ("Serif", Font.BOLD, 24);

  /** Use SimpleDateFormat with the given date & time style. **/
  SimpleDateFormatPanel () {
    fSDateFormat =
      new SimpleDateFormat ("EEE, d MMM yyyy HH:mm:ss Z");
  } // ctor

  /** Paint the date and time at center of panel. **/
  public void paintComponent (Graphics g) {
    super.paintComponent (g);

    // Get current date object
    Date now = new Date ();
    // And create a date/time string in the desired format.
    String date_out = fSDateFormat.format (now);

    // Use our choice for the font.
    g.setFont (fFont);

    // Do the size and placement calculations only for the
    // first paint  (assumes applet's window never resized.)
    if (fFirstPass) {

       // Get measures needed to center the message
      FontMetrics fm = g.getFontMetrics ();

      // How many pixels wide is the string
      int msg_width = fm.stringWidth (date_out);

      // Use the string width to find the starting point
      fMsgX = getSize ().width/2 - msg_width/2;

      // How far above the baseline can the font go?
      int ascent = fm.getMaxAscent ();

      // How far below the baseline?
      int descent= fm.getMaxDescent ();

      // Use the vertical height of this font to find
      // the vertical starting coordinate
      fMsgY = getSize ().height/2 - descent/2 + ascent/2;
    }
    g.drawString (date_out, fMsgX, fMsgY);
    fFirstPass = false;
  } // paintComponent

} // class SimpleDateFormatPanel

 

Note: To get the current time use System.currentTimeMillis(). However, the catch is that the time is provided in milliseconds. The value corresponds to the difference between the current time and midnight, January 1, 1970 UTC. This method is useful for program timing studies.

References & Web Resources

Latest update: Nov. 18, 2004

              Tech
ArbitaryPrecision
   BigInteger
  
BigDecimal
Bit Handling
Exercises

           Physics
Data Gen&Analysis

  Demo 1
  Demo 2
Exercises

  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.