tzrule.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-------------------------> GNU Sather - sourcefile <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute and/or modify it under the terms of the GNU Library General --
-- Public License (LGPL) as published by the Free Software Foundation; --
-- either version 2 of the license, or (at your option) any later version. --
-- This library is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details. --
-- The license text is also available from: Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
--------------> Please email comments to <bug-sather@gnu.org> <--------------
immutable class DATE_FORMS < $ENUMS{DATE_FORMS}
immutable class DATE_FORMS < $ENUMS{DATE_FORMS} is
--This is an enumeration class which describes the different forms of
-- date as specified in ISO/IEC 14652.
-- The mandatory string names are - <blank>, "J", "M"
-- Version 1.0 Feb 98. Copright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 25 Feb 98 kh Original
include ENUM{DATE_FORMS} ;
private const val_count : CARD := 3 ;
-- The next routines provide the enumeration itself for a selection
-- of the official registry encodings.
Zero_Based : SAME is return enum(1) end ;
Julian : SAME is return enum(2) end ;
Gregorian : SAME is return enum(3) end ;
end ; -- DATE_FORMS
immutable class TZ_RULE_ELEM < $STR, $BINARY
immutable class TZ_RULE_ELEM < $STR, $BINARY is
-- This class is the descriptor of a time when the change from summer
-- to standard time (or vice-versa) takes place.
--
-- The model uses a two component 'date' giving either the day in week,
-- week in month and month in year OR if week in month is zero then
-- the day is considered to be the day in month, rather than day in week.
-- Version 1.0 Feb 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 24 Feb 98 kh Original using ISO/IEC 14652 spec.
include BINARY ;
private attr day_number : CARD ;
private attr week_number : CARD ;
private attr month : CARD ;
private attr time : TIMES ;
create(day : CARD,week : CARD,mth : CARD,clock : TIMES) : SAME
pre ((day > 0) and (day <= 7))
and ((week > 0) and (week <= 5))
and ((mth > 0) and (mth <= 12))
post ~void(result)
is
-- This creation routine makes the form of rule given as a particular
-- day in a particular week of the given month.
return day_number(day).week_number(week).month(mth).time(clock)
end ;
create(days : CARD,one_based : CARD,clock : TIMES) : SAME
pre ((days > 0) and (days <= 365) and (one_based = 1))
or ((days > 0) and (days <= 366) and (one_based = 0))
post ~void(result)
is
-- This creation routine makes the form of rule given as a particular
-- day in the year. If one_based is one then the form is based on the Julian
-- year from 1 to 365 and it is not possible to refer to February 29th!
return day_number(days).week_number(one_based).month(0).time(clock)
end ;
build(cursor : BIN_CURSOR) : SAME
pre (cursor.remaining >= ((3 * CARD::zero.binstr.size) + TIMES::null.binstr.size))
post ~void(result) -- and it represents a rule!
is
--This creation routine creates a rule using the given string cursor.
me : SAME ;
me := me.day_number(HEXTET::build(cursor).card) ;
me := me.week_number(cursor.get_item.card) ;
me := me.month(cursor.get_item.card) ;
me := me.time(TIMES::build(cursor)) ;
return me
end ;
binstr : BINSTR
pre ~void(self)
post result.size > 0
is
--This routine creates a storage representation of this rule element.
return BINSTR::create + HEXTET::create(day_number) +
OCTET::create(week_number) +
OCTET::create(month) + time.binstr
end ;
time(year : CARD) : TIME_STAMP
pre ~void(self)
post ~void(result)
is
--This routine returns the full time as a local clock time at which
-- the change corresponding to this rule element would/will take place in
-- the given year.
if month = 0 then -- a Julian rule
if week_number = 1 then -- no leap day!
if DATES::is_leap_year(year) then
loc_day : CARD := day_number ;
if day_number = 60 then
loc_day := loc_day + 1
end ;
return TIME_STAMP::create(DATES::create(loc_day,month,year),time)
end
else
return TIME_STAMP::create(DATES::create(day_number + 1, month,year),time)
end
else -- work out day in month!
loc_date : DATES := DATES::create(1,month,year) ;
loc_day : CARD := loc_date.day_of_week ;
day_in_month : CARD := day_number ;
if day_in_month < loc_day then
day_in_month := day_in_month + DATES::Days_in_Week
end ;
return TIME_STAMP::create(DATES::create((day_in_month - loc_day + 1),
month,year),time)
end
end ;
str(lib : LIBCHARS) : STR
pre ~void(self) and ~void(lib)
post result.size > 0
is
--This routine converts the rule element to a textual representation
-- which would be acceptable to a standard locale parser reading routine
-- using the given repertoire and encoding.
res : STR := STR::create ;
if month = 0 then
if week_number = 0 then
res := res + day_number.str
else
res := res + DATE_FORMS::Julian.str(lib) + day_number.str(lib)
end
else
res := res + DATE_FORMS::Gregorian.str(lib) + month.str(lib) +
lib.Colon.char + week_number.str(lib) +
lib.Colon.char + day_number.str(lib)
end ;
return res + lib.Solidus.char + time.str(lib)
end ;
str : STR
pre ~void(self)
post result.size > 0
is
--This routine converts the rule element to a textual representation
-- which would be acceptable to a standard locale parser reading routine.
return str(LIBCHARS::default)
end ;
end ; -- TZ_RULE_ELEM
class TZONE_RULE < $BINARY
class TZONE_RULE < $BINARY is
-- This class is the descriptor to be used when calculating local time
-- from UTC and vice-versa.
-- Version 1.0 Feb 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 23 Feb 98 kh Original using ISO/IEC 14652 spec.
include BINARY ;
private attr valid_range : RANGE ;
private attr start : TZ_RULE_ELEM ;
private attr stop : TZ_RULE_ELEM ;
build(cursor : BIN_CURSOR) : SAME
pre ~void(cursor) and ~cursor.is_done
post ~void(result) or (cursor.index = initial(cursor.index))
is
--This routine creates a new object from the contents of the binary
-- string indicated.
res : SAME := new ;
start_index : CARD := cursor.index ;
res.valid_range := RANGE::build(cursor) ;
if cursor.is_done then
cursor.set_index(start_index) ;
return void
end ;
res.start := TZ_RULE_ELEM::build(cursor) ;
if cursor.is_done then
cursor.set_index(start_index) ;
return void
end ;
res.stop := TZ_RULE_ELEM::build(cursor) ;
if void(res.stop) then
cursor.set_index(start_index) ;
return void
end ;
return res
end ;
create(from : CARD,to : CARD) : SAME
pre (from < to) -- may not be an empty range!
post void(result.start)
and void(result.stop)
is
-- This creation routine is provided for use by the program reading
-- source text to create this object.
me : SAME := new ;
me.valid_range := RANGE::create(from, to) ;
return me
end ;
create(from : CARD,to : CARD,start_rule : TZ_RULE_ELEM,stop_rule : TZ_RULE_ELEM) : SAME
pre (from < to) and ~void(start_rule) and ~void(stop_rule)
post ~void(result)
is
--This creation routine is provided for use by the program reading
-- source text to create this object.
me : SAME := create(from,to) ;
me.start := start_rule ;
me.stop := stop_rule ;
return me
end ;
binstr : BINSTR
pre ~void(self)
post result.size > 0
is
--This routine produces a binary string form representation of self.
return valid_range.binstr + start.binstr + stop.binstr
end ;
applies(stamp : TIME_STAMP) : BOOL is
--This predicate returns true if and only if the given time stamp is
-- valid - within the range of years for this rule.
return valid_range.contains(stamp.date.year)
end ;
is_summer(stamp : TIME_STAMP) : BOOL is
--This predicate returns true if and only if the given time stamp is
-- in the period of summer time as defined by this rule.
yr : CARD := stamp.date.year ;
res : BOOL ;
if start.time(yr) < stop.time(yr) then -- northern hemisphere
res := (start.time(yr) <= stamp)
and (stop.time(yr) >= stamp)
else -- southern hemisphere
res := (stamp >= start.time(yr))
or (stamp <= stop.time(yr))
end ;
return res
end ;
end ; -- TZONE_RULE