Oberon || Library || Module Index || Search Engine || Definition || Module

Ulm's Oberon Library:


Dates - date and time conversions


CONST january = 1;   april = 4;     july = 7;      october = 10;
CONST february = 2;  may = 5;       august = 8;    november = 11;
CONST march = 3;     june = 6;      september = 9; december = 12;

CONST sunday = 0; tuesday = 2; thursday = 4; saturday = 6; CONST monday = 1; wednesday = 3; friday = 5;

CONST absolute = Scales.absolute; relative = Scales.relative;

TYPE Date = POINTER TO DateRec; TYPE DateRec = RECORD (Times.TimeRec) END;

TYPE Value = POINTER TO ValueRec; TYPE ValueRec = RECORD (Objects.ObjectRec) days: Scales.Value; hours: SHORTINT; (* 0..23 *) minutes: SHORTINT; (* 0..59 *) seconds: SHORTINT; (* 0..59 *) msecs: INTEGER; (* 0..999 *) END;

TYPE Info = POINTER TO InfoRec; TYPE InfoRec = RECORD (Objects.ObjectRec) year: Scales.Value; month: SHORTINT; (* january..december *) day: SHORTINT; (* 1..31 *) weekday: SHORTINT; (* sunday..saturday *) hour: SHORTINT; (* 0..23 *) minute: SHORTINT; (* 0..59 *) second: SHORTINT; (* 0..59 *) msec: INTEGER; (* 0..999 *) END;

TYPE LongInfo = POINTER TO LongInfoRec; TYPE LongInfoRec = RECORD (InfoRec) yearday: INTEGER; (* 1..366 *) week: SHORTINT; (* 1..53, week begins on Sunday *) mweek: SHORTINT; (* 1..53, week begins on Monday *) leapyear: BOOLEAN; daysInMonth: SHORTINT; (* usu. 28..31, length of month *) daysInYear: INTEGER; (* usu. 365..366, length of year *) tzInfo: Timezones.GlimpseRec; END;

VAR scale: Scales.Scale;

CONST invalidTime = 0; CONST invalidDate = 1; CONST bogusValue = 2; CONST timeOutOfRange = 3; CONST errorcodes = 4; TYPE ErrorCode = SHORTINT; TYPE ErrorEvent = POINTER TO ErrorEventRec; TYPE ErrorEventRec = RECORD (Events.EventRec) errorcode: ErrorCode; END; VAR errormsg: ARRAY errorcodes OF Events.Message; VAR error: Events.EventType;

PROCEDURE Create(VAR time: Times.Time; type: SHORTINT);

PROCEDURE CreateYMD(VAR time: Times.Time; year, month, day: Scales.Value);

PROCEDURE SetValue(time: Times.Time; value: ValueRec); PROCEDURE GetValue(time: Times.Time; VAR value: ValueRec);

PROCEDURE Set(time: Times.Time; info: InfoRec); PROCEDURE SetT(time: Times.Time; tz: Timezones.Timezone; info: InfoRec); PROCEDURE SetO(time: Times.Time; off: Timezones.Offset; info: InfoRec);

PROCEDURE Get(time: Times.Time; VAR info: InfoRec); PROCEDURE GetT(time: Times.Time; tz: Timezones.Timezone; VAR info: InfoRec); PROCEDURE GetO(time: Times.Time; off: Timezones.Offset; VAR info: InfoRec);

PROCEDURE GetLong(time: Times.Time; VAR info: LongInfoRec); PROCEDURE GetLongT(time: Times.Time; tz: Timezones.Timezone; VAR info: LongInfoRec);

PROCEDURE Valid(year, month, day: Scales.Value) : BOOLEAN;

PROCEDURE Weekday(year, month, day: Scales.Value) : SHORTINT;


Dates implements a time scale scale that belongs to the Times.family family and allows particular efficiency for the date and time conversions it also offers. The module can handle all kinds of time measures compatible to Times.Time. Therefore, type Date is made visible only so that it can be used in type tests.

The time scale this module is based upon consists of only two units: days (``days'') and milliseconds (``msecs''). For convenience, milliseconds are unfolded into hours, minutes, seconds and remaining msecs. Legal values cover at least one million years in either direction. Absolute values are considered to be relative to Jan 1, 1970, 0:00:00 GMT (universal time). Thus, values are always independent of locations, daylight corrections etc. The conversions from a time to a calendar date and time of day, and vice versa, however, do take care of all these things.

The implemented calendar is the Gregorian calendar, which replaced Julius Caesar's calendar in October 1582. Dates before the Gregorian calendar reformation, no matter how far in the past, are considered Julian dates (for the sake of astronomers). The fact that some countries switched to Gregorian calendar much later than in 1582 is not reflected (for the sake of simplicity).

Create creates a new instance of time, where type is either absolute or relative, and initializes it to zero. Of course, the data type of time will be Date.

CreateYMD creates an absolute time representing year, month, day, 12:00:00 GMT.

SetValue sets time to value. Values with negative components (besides value.days) are normalized first. GetValue obtains a time value.

Set, SetT and SetO set time to the date and time of day given in info, ignoring info.weekday. While Set determines the time zone and daylight saving time correction according to Timezones.local, SetT does this according to the given time zone tz, whereas SetO uses an explicit offset off in respect to universal time instead.

Get, GetT and GetO translate time to info using Timezones.local, tz or off respectively. GetLong and GetLongT do essentially the same, but fill in the additional fields of LongInfoRec, too. In particular, info.week and info.mweek are week numbers within the year, starting with the first week containing at least four days of January; where weeks are considered to begin on Sunday resp. Monday.

Valid returns TRUE if year, month and day form a correct date of the implemented calendar, otherwise FALSE.

Weekday returns the weekday of the given date.


All conversion procedures raise an error event which is passed to Events if they encounter illegal values. Returned, resp. modified, values are always guaranteed to be valid anyway.

Error events carry in errorcode an error code which can be one of the following:

An info parameter represented no valid date and time.
A year/month/day parameter triple represented no valid date.
An inconsistent date value was detected. This can also happen as a consequence of PersistentObjects.Read.
A time was outside the range that can be represented as a Date value.


reference scale for time measurement systems
formatted input and output of times and dates
abstraction for time zones
implementation of time zones known to the system
abstraction for persistent objects
event handling for error events


Martin Hasch, University of Ulm
credits to Markus Schauler, University of Ulm, for some work on the subject
Edited by: martin, last change: 1995/08/02, revision: 1.5, converted to HTML: 1997/04/28

Oberon || Library || Module Index || Search Engine || Definition || Module