New Squeak Date Classes

Abstract

This document proposes a new data and time class library for the Squeak Smalltalk environment.

Overview and Scope

The package replaces the existing Date and Time classes with ANSI standard DateAndTime and Duration implementations. The existing Date and Time classes are then reused along with Week, Month and Year classes to provide an intuitive classes library which complements the collection class library.

Motivation and Benefits

Almost all commercial development tools provide woefully poor support for manipulating dates and times. Indeed the J++ implementation of Java forces the application programmer to familiarise himself with up to six different classes. These classes are not compatible with each other and lack basic functionality to compare and manipulate instances. Even expensive tools like VisualAge Generator which targets large commercial projects does not provide library code to add or subtract and arbitrary number of days from a date.

Most implementations are closed and cannot be easily extended necessitating awkward conversion methods. The support for iterating over a time span between two dates is usually very poor. The result is verbose code, cluttered with arcane conversion methods, which it preoccupied with the details of the date instances. Enumeration constructs are extremely susceptible to errors at or near the iteration boundaries.

This situation should not be tolerated by developers. The Gregorian calendar with years, months, weeks and dates is almost universal and is most certainly the dominant calendar used in commercial software. The developer should reasonably expect to see classes which endorse these concepts.

Most significantly, such temporal classes should provide robust, stable and elegant mechanism to iterate over these temporal classes in a manner consistent with the iteration protocol for that language.

Opportunity

Regrettably Smalltalk is not exempt from a date time class library which is not optimised to the real needs of commercial software. Fortunately Smalltalk is better positioned than most environments to correct this as the class library can be modified and extended at will and the language supports closures which provide the developer with an extremely functional mechanism to iterate over a collection of objects.

The timing is also superb.

The ANSI specification has been completed which dictates a very usable protocol for representing dates, times and durations. Implementing the DateAndTime and Duration protocols will provide a standard foundation based on UTC.

This implementation can be augmented by additional temporal classes providing the commercial developer with the craven functionality.

Architecture and Concepts

The new temporal class library implements the DateAndTime and Duration protocols.

The Duration class is interpreted to represent some duration of time possibly negative. DateAndTime instances are interpreted to represent a point in Universal Co-ordinated Time space. By definition they have zero duration.

Moore's Law is accepted to hold, so the implementation will have nanosecond precision. This is fully UTC compliant and provides the high precision needed for database timestamps and GUI events. This decision should help minimize the need for a further class library to be developed.

To support the new temporal library, we introduce the concept of a Timespan which spans UTC time for a specified duration starting from some arbitrary DateAndTime. This information is sufficient to determine the end time of the duration. The timespan is designed to be similar to the Interval class although its elements are interpreted to be a continuous collection of DateAndTime instances.

This concept is further promoted by introducing classes for familiar the timespans of Years, Months, Weeks and individual dates.

We note that the introduction of the DateAndTime class as the preferred representation of time, frees up the Date class for redeployment. The notion of a date 'Date' is familiar to all people and represents a full day, midnight to midnight, 24 hours, a full 86400 seconds. We leverage this and reuse Date and a new subclass of Timespan. The existing Time class is inserted as a subclass of DateAndTime for compatibility. Its role in the new library is still not fully known.

Class Hierarchy

Object
    Duration
    DateAndTime
        Time
Object
    Timespan
        Year
        Month
        Week
        Date

Protocol

Instance protocol

The temporal class are designed to be extremely interoperable to minimize the clutter and preoccupation with irrelevant details. The de facto Smalltalk naming convention of verb\noun is used for methods thoughout and conversion methods are provided in abundance.

The timespan classes re-implement much of the ANSI DateAndTime protocol to reduce unnecessary conversion.

Iteration protocol

The iteration protocol provides the application programmer with the power to express enumeration constructs in the functional manner. This is designed to be similar to the #do:, #select: #collect: methods offered by the Collection classes.

Usage

The example code is be displayed in a workspace. It is by no means exhaustive but provides an indication of the functionality.

Duration

Duration zero.
Duration seconds: 90060.
123 asDuration.

DateAndTime

DateAndTime now.
DateAndTime year: 2000 month: 8 day: 17 hour: 16 minute: 34 second: 40.

Dates

DateAndTime now asDate.
Date today.
d := Date year: 2000 month: 5 day: 28.
d start.
d end.
d duration.
d end - d start.
d dayOfWeekName.

Week

Week startDay.
Week current.
DateAndTime now asWeek.
Date today asWeek.
Week current dates.
Week current datesDo: [ :d | Transcript cr; show: d ].
Week current workDatesDo: [ :d | Transcript cr; show: d dayOfWeekName ].

Month

Month current.
DateAndTime now asMonth.
Month current weeks.
Month current dates.

Year

Year current.
Year year: 2000.
Date today asYear.
Month current asYear.
Year months.

Financial Years

Much of the worlds  financial software deals with financial years which do not neccessarily start on the first day of the year. Consider the financial year April 2001 ending March 2002.
financialYear := Year starting: (Date year: 2001 month: 4 day: 1). "e.g.. 1 April 2001"
financialYear start.
financialYear end.
"Produce a report..."
Transcript clear.
aStream := Transcript.
aStream cr; nextPutAll: 'Report. Financial Year Ending: '.
financialYear end asDate printOn: aStream.
aStream cr; nextPutAll: (String new: 60 withAll: $-).
financialYear monthsDo:
[ :aMonth |
    | workDays |
    aStream cr. aMonth printOn: aStream.
    aStream crtab; nextPutAll: aMonth weeks size printString; nextPutAll: ' weeks'.
    workDays := 0.
    aMonth workDatesDo: [ :d | workDays := workDays + 1 ].
    aStream crtab; nextPutAll: workDays printString; nextPutAll: ' work days'.
].
aStream flush.

Arbitrary Timespans

Some applications like law  enforcement may require timespans spanning many years.
jail  := Timespan starting: (Year year: 2000) start ending: (2010 asYear).
jail years.
jail yearsDo: [:y | Transcript cr; show: y asDate]
Other applications need to iterate over a timespan in unusual intervals. Consider the code necessary to inspect a timespan of one second every millisecond:
oneSecond := Timespan starting: DateAndTime now duration: (Duration seconds: 1).
millisecond := Duration nanoSeconds: 1000000.
x := 0.
oneSecond every: millisecond do: [ :t | x := x + 1 ].
x printString.

Morphic

The implementation changeset includes changes to the MonthMorph and WeekMorph classes which are part of the base image. The reader should compare the changes with the existing code.

Implementation

The implementation of the DateAndTime class uses julian day numbers.

Testing

When complete the temporal library will ship with a full SUnit test suite. This has not been completed yet.

Status

This code is reasonably stable - I hope all bugs will be relatively simple to track down.

Test pilots would be most appreciated. The development effort has focussed on making the programming interface elegant and intuitive. Performance does not appears to be a problem and may be improved if needs be.  The DateAndTime protocol is almost complete.

Installation

The initial release has been developed using the 3.1 alpha with most recent change set 3910.
 
  • Get a clean 3.1 image
  • File in the NewDateHierarchy.cs change set.
  • File in the DateTimeChanges.cs change set.
  • You can now begin to explore the examples. The first time you instanciate a DateAndTime you will be prompted for your offset in hours from UTC.
  • Thanks

    Other than the usual suspects on the Squeak mailing list, my thanks go to whoever LC is. That person first introduced the Month and Week classes into the Squeak distribution which triggered the idea to reify timespans.

    Licences

    This library is distributed under the Squeak Licence as I know very little about law.

    Contact

    Brent Pinkney
    pinkfoot@bigfoot.com