MULTICS TECHNICAL BULLETIN 618 page 1
To: Distribution
From: James A Falksen, Gary Dixon
Date: March 14, 1983
Subject: Date/time system (3) Site tailoring
ABSTRACT
This MTB describes time_table_.cds mentioned in MTB616, with
emphasis on how a site would go about changing the time tables.
Send comments on the MTB by one of the following means:
In forum meeting:
>udd>m>jaf>mtgs>date_time
By Multics mail:
Falksenj.Multics at M
GDixon.Multics at MIT
By Telephone:
HVN 357-6618 or 602-862-6618
________________________________________
Multics Project working documentation. Not to be reproduced or
page 4-2 MTB-618
All date/time related constants reside in time_table_, such as
day names, month names, offset names, zone names and offsets, and
"other" words. All of these are in several languages, one of
which is selected as the site default. time_table_.cds is
designed to allow a site to alter the time tables without having
to get involved too deeply in how the tables are structured.
Below is a sample of lines from a cds procedure. Between the
lines are comments on what the code is doing and/or what it
means.
1 time_table_: proc;
2
3 dcl (the_language_count init (4),
4 the_zone_count init (31),
First, are two constants which define the size of the
site's tables. They must be adjusted to reflect the
site's needs.
5 english init (1),
6 french init (2),
7 german init (3),
8 spanish init (4),
There must be a named constant for each language which
is in the table. These names must be numbered
sequentially beginning at 1. The language numbered 1
is the site default language.
9 Fill_From init (1)
10 ) fixed bin int static options (constant);
Time zone names are defined in a 2-dimensional array,
with zone as one dimension and languages as the second
dimension. Elements of the array are zone names (the
name of a zone in a particular language).
convert_date_to_binary_ requires that the entire array
be filled (ie, a zone name must be specified for each
zone in every language). However, sometimes the name
of a zone in a particular language is not known. This
problem is resolved by placing that zone's name in
another language (usually English) into the empty array
element. The Fill_From constant indicates which lan-
guage should be used to fill such empty array elements.
When chosing the Fill_From language, it is important to
note that a zone name must be explicitly specified for
every zone in the Fill_From language.
11
12 begin;
13
MTB-618 page 4-3
Then, a begin block is entered which contains the
declaration needed to generate the table. It makes use
of the constants just defined.
15 call setup ("STR1", "STR2", "STR3");
This initializes the whole structure to indicate "emp-
ty" in every field. Then it saves STR1 as the system
default date_time format, STR2 as the system default
date format, and STR3 as the system default time
format. These formats are strings which are acceptable
to date_time_$format.
16 call set_language (french, english, "anglais");
For each language present, its name in each other
language should be present. This call to the routine
says:
In french, the word for english is "anglais".
17 call set_month_name (english, Jan, "Jan", "January");
For each language present, the month names must be set.
This call to the routine says:
In english, the abbreviation and name for the
first month are "Jan" and "January".
There are named constants in the procedure for each
month:
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
18 call set_day_name (spanish, Mon, "lun", "lunes");
For each language present, the day names must be set.
This call to the routine says:
In spanish, the abbreviation and name for
Monday are "lun" and "lunes".
There are named constants in the procedure for each
day:
Mon Tue Wed Thu Fri Sat Sun
19 call set_offset (english, Hour, "hr","hours","hour");
For each language present, the offset names must be
set. This call to the routine says:
In english, the abbreviation, plural, and
singular for hour are "hr", "hours", and,
"hour".
There are named constants in the procedure for each
unit:
Year Month Week Day Hour Minute Second Microsecond
page 4-4 MTB-618
For each language present, several additional words
must be defined. This call to the routine says:
In german, the word for before is "vor".
There are named constants in the procedure for these
words:
Before On After Or Noon Midnight
Now Today Yesterday Tomorrow
21 call set_zone (english, "fwt", "fwt", -1,
22 French Winter Time");
23 call set_zone (french, "fwt", "hfh", -1,
24 "Heure Francais d'Hiver");
25 call set_zone (english, "sast", "sast", -9.5,
26 "South Australia Standard Time");
For each other language, time zones may also be
defined. These calls to the routine say:
1) In english, the zone identified as "fwt" is
to have an offset of -1 hours, an abbrevia-
tion of "fwt", and name of "French Winter
Time".
2) In french, the zone named "fwt" is to have
the abbreviation "hfh", and the name "Heure
Francais d'Hiver". All settings of a given
name must have the same offset.
3) The third example illustrates that a zone
abbreviation may have 4 characters in it and
that offsets are not necessarily in integral
hours.
The second argument in this call is an internal id of a
zone. It provides a mechanism to reference a given
entry in each language. The fourth argument is an
offset which represents the interval to be ADDED to GMT
to produce a time in the zone. West longitude needs
negative amounts, East longitude needs positive
amounts. Each zone entry may be referenced once per
language. Each reference to the zone must specify the
same offset or it is in error.
27 call build;
This signals that all data has been filled in.
28 return;
29 /* all internal procedures here */
30 end time_table_;
After all the data has been presented, the build checks several
things. If it finds any that it doesn't like, it will not
generate the table. These are some of the things it will check
MTB-618 page 4-5
1) All tokens(1) must be unique within a language.
2) There may not be any uninitialized fields. If a zone field is
not set in some language, the value from the "fill from"
language will be copied in. After that, if any field has not
been set, it is an error. This includes the error detected
when a zone is not define in the Fill_From language.
3) Two ambiguity checks will be done among all the words defined.
If a string has one meaning in one language and a different
meaning in another, that token will have an ambiguity flag
associated with it. If a string is used for the same purpose
in several languages, the use of it will be flagged to
indicate that it alone cannot determine which language is
being handled. These flags are for use by
convert_date_to_binary_.
A table, "internal" to time_table_, will be built to aid CDTB in
quickly locating a token among all these words. The current
intention is to build a list which can be binary searched. The
details of this internal table are not of importance to a user
and are subject to change as CDTB requires.
________________________________________
(1) Each word presented for inclusion in the time table is
page 4-6 MTB-618
This is a sample of a time_table_.cds to be released:
/* ******************************************************
* *
* *
* Copyright (c) 1972 by Massachusetts Institute of *
* Technology and Honeywell Information Systems, Inc. *
* *
* *
****************************************************** */
/**** format: ind3,ll80,initcol6,indattr,^inddcls,dclind4,idind16 */
/**** format: struclvlind2,^ifthenstmt,^ifthendo,^ifthen,^indnoniterdo */
/**** format: ^inditerdo,^indnoniterend,^indthenelse,case,^indproc,^indend */
/**** format: ^delnl,^insnl,comcol41,^indcom,^indblkcom,linecom,^indcomtxt */
/* * * * * * * * * * * * * * * * * * * */
/* */
/* Name: time_table_ */
/* */
/* Table of values used in converting date/time character strings to or */
/* from Multics standard clock values. Use time_names_.incl.pl1 to */
/* reference data values. */
/* */
/* */
/* Entry: time_table_$version */
/* */
/* Version number of the structures in the time_table_. */
/* */
/* */
/* Entry: time_table_$language_names */
/* */
/* Names of languages in which day names, month names and time zones can be */
/* expressed. Each language is present in each language. */
/* */
/* */
/* Entry: time_table_$zone_names */
/* */
/* Table of time zones in each of the languages. */
/* */
/* */
/* Entry: time_table_$month_names */
/* */
/* Table of month names in each of the languages. */
/* */
/* */
/* Entry: time_table_$day_names */
/* */
/* Table of day names in each of the languages. */
/* */
/* */
/* Entry: time_table_$zones (OBSOLETE) */
MTB-618 page 4-7
/* This table contains the list of acceptable time zone character */
/* strings which may be specified in a date/time string, and the offsets */
/* which must be added to convert a clock value from the zone to Greenwich */
/* Mean Time (GMT). The offsets are in microseconds. */
/* Refer to time_zones_.incl.pl1 for a description of these strings. */
/* */
/* Note */
/* */
/* A Multics standard clock value is a number of microseconds relative */
/* to January 1, 1901 0000.0 GMT. */
/* */
/* Status */
/* */
/* 0) Created: 1976-10-05 Gary C. Dixon- from an ALM data segment. */
/* 1) Recreated: 1983-02-09 James A Falksen- expanded to include */
/* language support, formatted to fit */
/* in MTB */
/* */
/* * * * * * * * * * * * * * * * * * * */
%page;
time_table_: proc;
dcl (the_language_count init (4), /* how many languages in the table */
the_zone_count init (31),/* how many zones in the table */
english init (1), /* site default language */
french init (2),
german init (3),
spanish init (4),
Fill_From init (1) /* which language supplies defaults */
/* for unspecified zones. */
) int static options(constant);
call setup
("^yc/^my/^dm ^Hd^99.9MH ^za ^da", /* date_time format */
"^yc/^my/^dm", /* date format */
"^Hd:^MH"); /* time format */
/* +-+ +-+ +-+ +-+ +-+ +-+ english language values +-+ +-+ +-+ +-+ +-+ +-+ */
call set_language (english, english, "english");
call set_language (english, french, "anglais");
call set_language (english, german, "englisch");
call set_language (english, spanish, "ingles");
call set_month_name (english, Jan, "Jan", "January");
call set_month_name (english, Feb, "Feb", "February");
call set_month_name (english, Mar, "Mar", "March");
call set_month_name (english, Apr, "Apr", "April");
page 4-8 MTB-618
call set_month_name (english, Jun, "Jun", "June");
call set_month_name (english, Jul, "Jul", "July");
call set_month_name (english, Aug, "Aug", "August");
call set_month_name (english, Sep, "Sep", "September");
call set_month_name (english, Oct, "Oct", "October");
call set_month_name (english, Nov, "Nov", "November");
call set_month_name (english, Dec, "Dec", "December");
call set_day_name (english, Mon, "Mon", "Monday");
call set_day_name (english, Tue, "Tue", "Tuesday");
call set_day_name (english, Wed, "Wed", "Wednesday");
call set_day_name (english, Thu, "Thu", "Thursday");
call set_day_name (english, Fri, "Fri", "Friday");
call set_day_name (english, Sat, "Sat", "Saturday");
call set_day_name (english, Sun, "Sun", "Sunday");
call set_offset (english, Year, "yr", "years", "year");
call set_offset (english, Month, "mo", "months", "month");
call set_offset (english, Week, "wk", "weeks", "week");
call set_offset (english, Day, "da", "days", "day");
call set_offset (english, Hour, "hr", "hours", "hour");
call set_offset (english, Minute, "min", "minutes", "minute");
call set_offset (english, Second, "sec", "seconds", "second");
call set_offset (english, Microsecond, "usec","microseconds",
"microsecond");
call set_word (english, Before, "before");
call set_word (english, On, "on");
call set_word (english, After, "after");
call set_word (english, Or, "or");
call set_word (english, Noon, "noon");
call set_word (english, Midnight, "midnight");
call set_word (english, Now, "now");
call set_word (english, Today, "today");
call set_word (english, Yesterday, "yesterday");
call set_word (english, Tomorrow, "tomorrow");
call set_zone (english,"z ","z ", 0 ,"Universal Time");
call set_zone (english,"ut ","ut ", 0 ,"Universal Time");
call set_zone (english,"gmt ","gmt ", 0 ,"Greenwich Mean Time");
call set_zone (english,"wat ","wat ", +1 ,"West Africa Time");
call set_zone (english,"at ","at ", +2 ,"Azores Time");
call set_zone (english,"gst ","gst ", +3 ,"Greenland Standard Time");
call set_zone (english,"nst ","nst ", +3.5,"Newfoundland Standard Time");
call set_zone (english,"ast ","ast ", +4 ,"Atlantic Standard Time");
call set_zone (english,"adt ","adt ", +5 ,"Atlantic Daylight Time");
call set_zone (english,"est ","est ", +5 ,"Eastern Standard Time");
call set_zone (english,"edt ","edt ", +6 ,"Eastern Daylight Time");
call set_zone (english,"cst ","cst ", +6 ,"Central Standard Time");
call set_zone (english,"cdt ","cdt ", +7 ,"Central Daylight Time");
call set_zone (english,"mst ","mst ", +7 ,"Mountain Standard Time");
call set_zone (english,"mdt ","mdt ", +8 ,"Mountain Daylight Time");
MTB-618 page 4-9
call set_zone (english,"pdt ","pdt ", +9 ,"Pacific Daylight Time");
call set_zone (english,"yst ","yst ", +9 ,"Yukon Standard Time");
call set_zone (english,"ahst","ahst", +10 ,"Alaska-Hawaii Standard Time");
/**** l set_zone (english,"bst ","bst ", -11 ,"Bering Standard Time"); */
call set_zone (english,"nt ","nt ", +11 ,"Nome Time");
call set_zone (english,"bst ","bst ", -1 ,"British Summer Time");
call set_zone (english,"swt ","swt ", -1 ,"Swedish Winter Time");
call set_zone (english,"sst ","sst ", -2 ,"Swedish Summer Time");
call set_zone (english,"cet ","cet ", -1 ,"Central European Time");
call set_zone (english,"fwt ","fwt ", -1 ,"French Winter Time");
call set_zone (english,"fst ","fst ", -2 ,"French Summer Time");
call set_zone (english,"met ","met ", -1 ,"Middle Europe Time");
call set_zone (english,"eet ","eet ", -2 ,"Eastern European Time");
call set_zone (english,"bt ","bt ", -3 ,"Baghdad Time");
call set_zone (english,"ist ","ist ", -5.5,"Indian Standard Time");
/**** l set_zone (english,"sst ","sst ", -7 ,"South Sumatra Time"); */
call set_zone (english,"jt ","jt ", -7.5,"Java Time");
call set_zone (english,"cct ","cct ", -8 ,"China Coast Time");
call set_zone (english,"jst ","jst ", -9 ,"Japan Standard Time");
call set_zone (english,"sast","sast", -9.5,"South Australia Standard Time");
call set_zone (english,"nzt ","nzt ", -12 ,"New Zealand Time");
/* +-+ +-+ +-+ +-+ +-+ +-+ french language values +-+ +-+ +-+ +-+ +-+ +-+ */
call set_language (french, english,"french");
call set_language (french, french, "francais");
call set_language (french, german, "franzosisch");
call set_language (french, spanish,"frances");
call set_month_name (french, Jan,"jan","janvier");
call set_month_name (french, Feb,"fev","f{vrier");
call set_month_name (french, Mar,"mar","mars");
call set_month_name (french, Apr,"avr","avril");
call set_month_name (french, May,"mai","mai");
call set_month_name (french, Jun,"jui","juin");
call set_month_name (french, Jul,"jul","julliet");
call set_month_name (french, Aug,"aou","ao|t");
call set_month_name (french, Sep,"sep","septembre");
call set_month_name (french, Oct,"oct","octobre");
call set_month_name (french, Nov,"nov","novembre");
call set_month_name (french, Dec,"dec","d}cembre");
call set_day_name (french, Mon,"lun","lundi");
call set_day_name (french, Tue,"mar","mardi");
call set_day_name (french, Wed,"mer","mercredi");
call set_day_name (french, Thu,"jeu","jeudi");
call set_day_name (french, Fri,"ven","vendredi");
call set_day_name (french, Sat,"sam","samedi");
call set_day_name (french, Sun,"dim","dimanche");
call set_offset (french, Year, "?", "ann{es", "ann{e");
page 4-10 MTB-618
call set_offset (french, Week, "?", "semaines", "semaine");
call set_offset (french, Day, "?", "jours", "jour");
call set_offset (french, Hour, "?", "heures", "heure");
call set_offset (french, Minute, "?", "minutes", "minute");
call set_offset (french, Second, "?", "secondes", "seconde");
call set_offset (french, Microsecond, "?", "microsecondes",
"microseconde");
call set_word (french, Before, "devant");
call set_word (french, On, "sur");
call set_word (french, After, "apr{s");
call set_word (french, Or, "ou");
call set_word (french, Noon, "midi");
call set_word (french, Midnight, "minuit");
call set_word (french, Now, "maintenant");
call set_word (french, Today, "aujourd'hui");
call set_word (french, Yesterday, "heir");
call set_word (french, Tomorrow, "demain");
call set_zone (french,"ut ","tu ", 0 ,"Temps Universal");
call set_zone (french,"fwt ","hfh ", -1 ,"Heure Francais d'Hiver");
call set_zone (french,"fst ","hfc ", -2 ,"Heure Francais d'Et{");
/* +-+ +-+ +-+ +-+ +-+ +-+ german language values +-+ +-+ +-+ +-+ +-+ +-+ */
call set_language (german, english,"german");
call set_language (german, french, "allemand");
call set_language (german, german, "deutsch");
call set_language (german, spanish,"aleman");
call set_month_name (german, Jan,"Jan","Januar");
call set_month_name (german, Feb,"Feb","Februar");
call set_month_name (german, Mar,"Mrz","M{rz");
call set_month_name (german, Apr,"Apr","April");
call set_month_name (german, May,"Mai","Mai");
call set_month_name (german, Jun,"Jun","Juni");
call set_month_name (german, Jul,"Jul","Juli");
call set_month_name (german, Aug,"Aug","August");
call set_month_name (german, Sep,"Sep","September");
call set_month_name (german, Oct,"Okt","Oktober");
call set_month_name (german, Nov,"Nov","November");
call set_month_name (german, Dec,"Dez","Dezember");
call set_day_name (german, Mon,"Mon","Montag");
call set_day_name (german, Tue,"Dns","Dienstag");
call set_day_name (german, Wed,"Mit","Mittwoch");
call set_day_name (german, Thu,"Don","Donnerstag");
call set_day_name (german, Fri,"Fre","Freitag");
call set_day_name (german, Sat,"Sam","Samstag");
MTB-618 page 4-11
call set_offset (german, Year, "?", "Jahren", "Jahre");
call set_offset (german, Month, "?", "Monate", "Monat");
call set_offset (german, Week, "?", "Wochen", "Woche");
call set_offset (german, Day, "?", "Tagen", "Tag");
call set_offset (german, Hour, "?", "Stunden", "Stunde");
call set_offset (german, Minute, "?", "Minuten", "Minute");
call set_offset (german, Second, "?", "Sekunden", "Sekunde");
call set_offset (german, Microsecond, "?", "Mikrosekunden",
"Mikrosekunde");
call set_word (german, Before, "vor");
call set_word (german, On, "an");
call set_word (german, After, "nach");
call set_word (german, Or, "oder");
call set_word (german, Noon, "Mittag");
call set_word (german, Midnight, "Mitternacht");
call set_word (german, Now, "Jetz");
call set_word (german, Today, "Heute");
call set_word (german, Yesterday, "Gestern");
call set_word (german, Tomorrow, "Morgen");
/* +-+ +-+ +-+ +-+ +-+ +-+ spanish language values +-+ +-+ +-+ +-+ +-+ +-+ */
call set_language (spanish, english,"spanish");
call set_language (spanish, french, "espagnol");
call set_language (spanish, german, "spanisch");
call set_language (spanish, spanish,"espa|ol");
call set_month_name (spanish, Jan,"ene","enero");
call set_month_name (spanish, Feb,"feb","febrero");
call set_month_name (spanish, Mar,"mar","marzo");
call set_month_name (spanish, Apr,"abr","abril");
call set_month_name (spanish, May,"may","mayo");
call set_month_name (spanish, Jun,"jun","junio");
call set_month_name (spanish, Jul,"jul","julio");
call set_month_name (spanish, Aug,"ago","agosto");
call set_month_name (spanish, Sep,"sep","septiembre");
call set_month_name (spanish, Oct,"oct","octubre");
call set_month_name (spanish, Nov,"nov","noviembre");
call set_month_name (spanish, Dec,"dic","diciembre");
call set_day_name (spanish, Mon,"lun","Lunes");
call set_day_name (spanish, Tue,"mar","Martes");
call set_day_name (spanish, Wed,"mie","Mi{rcoles");
call set_day_name (spanish, Thu,"jue","Jueves");
call set_day_name (spanish, Fri,"vie","Viernes");
call set_day_name (spanish, Sat,"sab","Sabado");
call set_day_name (spanish, Sun,"dom","Domingo");
call set_offset (spanish, Year, "?", "a}o", "a}o");
page 4-12 MTB-618
call set_offset (spanish, Week, "?", "semana", "semana");
call set_offset (spanish, Day, "?", "dia", "dia");
call set_offset (spanish, Hour, "?", "hora", "hora");
call set_offset (spanish, Minute, "?", "minuto", "minuto");
call set_offset (spanish, Second, "?", "segundo", "segundo");
call set_offset (spanish, Microsecond, "?", "microsegundo",
"microsegundo");
call set_word (spanish, Before, "?");
call set_word (spanish, On, "?");
call set_word (spanish, After, "?");
call set_word (spanish, Or, "?");
call set_word (spanish, Noon, "mediodia");
call set_word (spanish, Midnight, "medionoche");
call set_word (spanish, Now, "?");
call set_word (spanish, Today, "hoy");
call set_word (spanish, Yesterday, "ayer");
call set_word (spanish, Tomorrow, "ma}ana");
call build;
return;
setup_error:
call com_err_ (0, me, """call setup()"" must be done first.");
exit:
return;
/***** Internal Support Procedures ****/
setup: proc (dt_format, d_format, t_format);
dcl (dt_format, /* default format for date_time */
d_format, /* default format for date */
t_format /* default format for time */
) char (*) parm; /* (date_time_$format strings) */
end setup;
set_language: proc (lang, element, value);
dcl lang fixed bin, /* which language to set */
element fixed bin, /* which element to set */
value char (*); /* value to put there */
return;
end set_language;
set_month_name: proc (lang, element, short, long);
dcl lang fixed bin, /* which language to set */
element fixed bin, /* which element to set */
MTB-618 page 4-13
return;
end set_month_name;
set_day_name: proc (lang, element, short, long);
dcl lang fixed bin, /* which language to set */
element fixed bin, /* which element to set */
(short,long) char (*); /* values to put there */
return;
end set_day_name;
set_offset: proc (lang, element, short, plural, singular);
dcl lang fixed bin, /* which language to set */
element fixed bin, /* which element to set */
(short, plural, singular)
char (*); /* values to put there */
return;
end set_offset;
set_word: proc (lang, element, value);
dcl lang fixed bin, /* which language to set */
element fixed bin, /* which element to set */
value char (*); /* value to put there */
end set_word;
set_zone: proc (lang, id, brief, interval, long);
dcl lang fixed bin, /* which language to set */
id char (*), /* which element to set */
(brief, long) char (*), /* values to put there */
interval fixed dec (12,8); /* hour_value+GMT gives this zone */
end set_zone;
build: proc;
end build;
dcl create_data_segment_
entry (ptr, fixed bin(35));
dcl microseconds_per_hour init (3600000000)
fixed bin(71) int static options(constant);
/* format: off */
page 4-14 MTB-618
Feb init (2), Tue init (2),
Mar init (3), Wed init (3),
Apr init (4), Thu init (4),
May init (5), Fri init (5),
Jun init (6), Sat init (6),
Jul init (7), Sun init (7),
Aug init (8),
Sep init (9),
Oct init (10),
Nov init (11),
Dec init (12), Before init (1),
Or init (2),
Year init (1), After init (3),
Month init (2), On init (4),
Week init (3), Noon init (5),
Day init (4), Midnight init (6),
Hour init (5), Now init (7),
Minute init (6), Yesterday init (8),
Second init (7), Today init (9),
Microsecond init (8), Tomorrow init (10)
) fixed bin int static options (constant);
/* format: on */
%include cds_args;
%include time_zones_;
%include time_names_;%page;