The Telescript language provides two classes whose instances can express a time: Time
and CalendarTime
. This chapter shows you how to use both.
Time
and CalendarTime
:Object
* CalendarTime
* Time (Ordered, Protected)
Time
. When you instantiate Time
, the object you create captures the time of initialization and stores the time as a time value. (The time of initialization is provided by the platform on which the Telescript engine is running.) The time value is a number of days and seconds elapsed since a fixed reference time.
Because Time
inherits from the mix-in superclass Protected
, a time object's time value can't be modified. This means that the time supplied at initialization is fixed for the life of a time object. Because Time
also inherits from the mix-in superclass Ordered
, you can use ordered operations to compare two time objects and see if one time is before, after, or simultaneous with another time.
Time
's own operations allow you to determine the interval in seconds between the time values of two time objects; they also let you adjust the time value of a time object by incrementing or decrementing it to create a new time object.
CalendarTime
.
CalendarTime
defines an object with a set of read/write attributes that each contain a different facet of a date and time: one attribute contains the year, another contains the month of the year, another the day of the month, another the hour of the day, another the minute of the hour, another the second of the minute, and so on. Because CalendarTime
is not protected, you may modify any of these attributes, adding hours to a time, for example, or subtracting months from the date. This allows you to use a calendar time for record keeping or time calculations--adding or subtracting different units of time as you see fit.
It's possible to exceed meaningful values by modifying calendar time attributes. If, for example, you add 25 days to a calendar time whose date is June 23rd, the calendar time will have a date of June 48th. You can, at any time, normalize a calendar time object. Normalization converts out-of-range attribute values into meaningful time and date values. In the previous example, June 48th would be normalized to July 18th because June 48th goes 18 days past the 30 days allotted to June. CalendarTime
's normalize
operation takes into account months with different numbers of days, leap years, and other quirks of standard timekeeping.
If you want to compare two calendar times, you can convert them both to time objects. You can then check to see if one is before, after, or simultaneous to the other, or you can find out the difference in time between the two objects.
Time
class defines an object that has no attributes. It has a single property--its time value which, as you'll recall, is a number of days and seconds elapsed since a fixed time. That fixed time is not defined by the Telescript language, so its value depends on the Telescript implementation used where a Time object is instantiated. (The most common implementation uses a fixed time of midnight, November 17, 1858 A.D.) Because the fixed time is arbitrary, you can't count on it being the same from one implementation of the Telescript language to another, and shouldn't look on a time value as a concrete time.The time value has two parts: days, which is the number of Julian days that have elapsed since the fixed time; and seconds, which is the number of seconds that have passed since midnight of the current day.
A time object's time value is created at the moment of initialization. The value is determined using the Coordinated Universal Time (UTC) at that moment. You might know UTC better as Greenwich Mean Time, the current time in Greenwich, England, with no modifications made for daylight savings time. When the time object is instantiated, its time value is the number of Julian days from Telescript's fixed time to the current UTC date, and the number of seconds from midnight of the current date to the UTC time at initialization.
The accuracy of a time value is completely dependent on the platform. If the date and time kept by the platform isn't set properly, or if the platform runs slow or fast as it keeps time, the platform may supply an inaccurate time when a time object is instantiated. This means that three simultaneously instantiated time objects from three different platforms may have three different time values. This is an important consideration to keep in mind when time objects travel from one Telescript engine to another. Comparing time objects from two different engines can't be guaranteed to give you completely accurate results.
(A timely aside: If you're interested in reckoning time and date in a computer environment, and in how a Julian day value is reckoned, you'll find technical details in "Calendrical Calculations" by Nachum Dershowitz and Edward M. Reingold in Software--Practice and Experience, Volume 20, Number 9, September 1990, pp. 899-928. You'll find that the standard Julian days reference time is noon, January 1, 4713 B.C., a date that leads to extremely large day values in a time value. Midnight, November 17, 1858 A.D., the fixed time commonly used in today's Telescript implementations, turns out to be a convenient fixed time for reckoning contemporary time values. That's because it's exactly 2,400,000.5 days later than the standard fixed time, so it allows day values to be expressed in integers of reasonable size.)
creates a time object whose time value is set at the moment of initialization.
Time objects are also created as the result of two operations that you'll read about later in this chapter. If you call adjust
on an existing time object, you create a new time object based on the first time object. If you call asTime
on a calendar time object, you convert it to a new time object. In both cases, the newly initialized time objects have times that are based on the responder, not on the moment of initialization.
adjust
operation, which accepts a single argument: a positive or negative integer that gives the number of seconds you want to use to adjust the original time value. This statement
creates a new time object twoMinutesLater
whose time value is 120 seconds later than the time value of rightNow
.
You can, if you want, use the same variable name to discard the original time object and use the adjusted time object in its place:
interval
operation. interval
accepts a single argument: a time object. It calculates the interval of time between the argument time object and the responder time object by subtracting the argument's time value from the responder's time value. It returns an integer that is the number of seconds difference between the two time values. The following statement, for example, determines the interval of time between rightNow
and twoMinutesLater
:
The interval
operation here subtracts the time value of rightNow
from the time value of twoMinutesLater
. If both those time objects were defined as they were in previous examples, the operation would return a value of 120 (the number of seconds difference between the two) so timeElapsed
would be equal to 120.
maximum
, minimum
, and order
--all inherited from the mix-in superclass Ordered
--allow you to make time comparisons. Ordered
has been specialized in Time
to compare the time values of time objects.
Because time objects are comparable, you can use them with relationship operators such as <
, >
, and ==
. If one time is after a second time, it is greater than the second time; if it's before a second time, it's less than the second time; if it's simultaneous with the second time, it's equal to the second time.
Time
offers two conversion operations: asCalendarTime
and localize
. asCalendarTime
accepts no arguments and returns a calendar time object that expresses the same second of time that the time object expresses. The calendar time object's attributes are all normalized (no out-of-range values are present), and its expressed time doesn't show any permanent or seasonal offsets. In other words, it shows UTC: Greenwich Mean Time without any Daylight Savings Time.
localize
also converts a time object to a calendar time. It accepts no arguments and returns a calendar time object that expresses the same second of time that the time object expresses. Its attributes are all normalized. The main difference between localize
and asCalendarTime
is that localize
expresses any permanent or seasonal offsets in effect on the Telescript engine's platform. It reflects the time zone where the platform is located and the daylight savings time (DST) offset if DST is in effect.
CalendarTime
class defines an object that expresses time through its read/write attributes: time in years, months, days, hours, minutes, and seconds. These attributes also provide information about the time zone where the time is expressed, and any daylight savings time adjustments made to the time.You may change the time expressed by a calendar time. (Compare this to a time object, whose time value is unchangeable once the object is created.) To change a calendar time, you write a new value to one of its attributes. You can read any aspect of a calendar time--the month, the hour, or time zone, for example--by simply reading the appropriate attribute.
creates a calendar time named whatTime
whose attributes are all nil.
If you create a calendar time by converting a time object (using the operations localize
or asCalendarTime
on the time object), the calendar time created has all of its attributes set to express a single moment in time--the time expressed by the converted time object. If you want to create a calendar time that expresses the time of its creation, you can initialize a time object, convert it, and discard the original time object as shown in this statement:
The statement creates a time object, calls localize
on it to return a calendar time, then assigns the calendar time to the variable nowCalendarTime
. The original time object is discarded; the end result is a calendar time named nowCalendarTime
whose expressed time is the moment of its creation.
CalendarTime
has five attributes that express aspects of the date. Each attribute can be nil or a negative or positive integer value. Each attribute has a range of values that are considered normal--that is, a value that has meaning for the aspect of date expressed by the attribute. The attribute can have a value outside of the normal range; if so, the value will be adjusted appropriately if the calendar time object is normalized.
You can change the date expressed by a calendar time by writing new values to year
, month
, or day
, or by modifying existing values (adding or subtracting years, months, or days, for example). Writing new values to dayOfWeek
or dayOfYear
has no effect on the values of the other date attributes; these two attributes are used only to show different aspects of the date, and are best treated as read-only attributes.
CalendarTime
also has three attributes that express aspects of time--that is, increments of time smaller than a day. These attributes, like the date attributes, can be nil, or a negative or positive integer value. Each attribute has a normal range of values.
You can change the time expressed by a calendar time by writing new values to hour
, minute
, or second
, or by modifying their existing values.
CalendarTime
has two attributes that express time offsets. Each can be nil or a negative or positive integer value, and each has a normal range of values.
It's important to note that zone
and dst
are not linked to the time and date attributes during normalization. If you change the zone
value, for example, by adding 60 (the effect of moving another time zone to the west), the hour
and minute
attributes are unchanged--that is, they don't reflect the change in time zone, and won't even if the calendar time is normalized. The offset attributes are strictly present for reference so you can read them to see what offsets are in effect for the date and time expressed in the other attributes. If you change offset attributes to express a calendar time with a new time zone or DST offset, it's your responsibility to change the hour
and minute
attributes to match the change to new offsets.
CalendarTime
offers the normalize
operation.
normalize
accepts no arguments. When it executes, it checks each attribute for out-of-range or nil values. If an attribute has an out-of-range value, normalize
brings the value into the normal range. If an attribute has a nil value, normalize
turns it into a 1 or a 0 depending on the attribute (as shown later). normalize
returns a boolean: true if it made changes to any of the calendar time's attributes, false if it made no changes.
normalize
brings an out-of-range value into the normal range, it increments or decrements the next-greater attribute to maintain the overall expressed time. For example, if it normalizes an hour
value of 78, it realizes that 78 hours is equal to 3 days (72 hours) and 6 hours, so it adds 3 to the day
attribute and sets hour
equal to 6.
normalize
starts its work with the smallest time attribute and works to the greatest date attribute: it begins with second
, moves to minute
, then hour
, day
, month
, and finally year
. It independently normalizes the offset attributes (zone
and dst
) without regard to the date and time attributes. And it calculates dayOfWeek
and dayOfYear
from the values of the normalized day
, month
, and year
attributes.
normalize
follows the rules of Gregorian calendar time when it normalizes out-of-range values. As an example of the way it works, consider a calendar time whose attributes are as follows:
year: 1996 month: 2 day: 27 hour: 21 minute: 34 second: 50 zone: 480 dst: 0 dayOfWeek: 3In other words, it expresses the time 9:34:50 p.m. on Tuesday, February 27, 1996, the 58th day of the year. The time is expressed in Pacific Standard Time--the local time for time zone 8. There is no daylight savings time in effect.
Now let's say that the calendar time is incremented at different times: once to add two days to the day
attribute, another time to add 58 hours to the hour
attribute, and again to add 397 to the second
attribute. The result is the following set of unnormalized attributes:
year: 1996 month: 2 day: 29 hour: 79 minute: 34 second: 447 zone: 480 dst: 0 dayOfWeek: 3Two attributes now have out-of-range values:
hour
and second
. day
does not have an out-of-range attribute because 1996 is a leap year, so February has 29 days.
When normalize
is called on the calendar time, the attributes are as follows:
year: 1996 month: 3 day: 3 hour: 7 minute: 41 second: 27 zone: 480 dst: 0 dayOfWeek: 1It expresses the time 7:41:27 a.m. on Sunday, March 3, 1996--the 63rd day of the year as expressed in Pacific Standard time.
Let's look at the process of normalization:
normalize
first checked the second
value which, at 447, is past the upper limit of 60. It divided 447 by 60 to get 7 with a remainder of 27--in other words, 447 seconds equals 7 minutes and 27 seconds. It wrote 27 to second
, then added 7 to minute
to create a new minute
value of 41.
Because minute
is within normal range, normalize
moved to hour
which, at 79, is past the upper limit of 23. It turned the 79 hours into 3 days and 7 hours (3*24+7), wrote 7 to hour
and added 3 to day
to create a new day value of 32.
32 is three days past the upper limit of 29, so normalize
turned it into 1 month and 3 days. It wrote 3 to day
and added 1 to month
to create a new month value of 3. Because month
and year
are within normal limits, normalize
didn't change them.
The month
and day
values were changed, so the calendar time calculated new values for dayOfWeek
and dayOfYear
: 1 and 63 respectively. zone
and dst
were never out of normal range, so their values weren't changed.
If zone
or dst
have out-of-range values (not in the range of -720 to 720), normalize
wraps the value around to the opposite side of the range as many times as necessary. A value of -780, for example, would change to 660; a value of 1560 would change to -600. zone
and dst
don't affect each other, so normalizing one offset value won't affect the value of the other.
normalize
encounters nil values in calendar time attributes, it takes different actions depending on the attribute:
year: nil month: nil day: nil hour: nil minute: nil second: nil zone: nil dst: nil dayOfWeek: nilAfter normalization, it has these values:
year: 1 month: 1 day: 1 hour: 0 minute: 0 second: 0 zone: 0 dst: 0 dayOfWeek: 2
Calling the operation asTime
on a calendar time normalizes the calendar time and then converts it to a time object. The operation accepts no arguments and returns the converted time object.
1 do{ 2 /* declare variables */ 3 firstTime, secondTime, thirdTime: Time; 4 humanTime: CalendarTime; 5 /* create a time variable, adjust it by 3 million seconds, compare 6 adjusted time to original time */ 7 firstTime = Time(); 8 secondTime = firstTime.adjust(-3000000); 9 "Here are firstTime and secondTime".dump(); 10 firstTime.dump(); 11 secondTime.dump(); 12 if firstTime > secondTime 13 {"firstTime comes after secondTime.".dump();} 14 else if firstTime < secondTime 15 {"firstTime comes before secondTime.".dump();} 16 else {"firstTime is simultaneous with secondTime".dump();}; 17 /* convert original time to a localized calendar time */ 18 humanTime = firstTime.localize(); 19 "This is humanTime after conversion from firstTime".dump(); 20 humanTime.dump(); 21 /* subtract 3 million seconds from calendar time */ 22 humanTime.second = humanTime.second - 3000000; 23 "This is humanTime after decrementing 3000000 seconds".dump(); 24 humanTime.dump(); 25 /* normalize calendar time */ 26 humanTime.normalize(); 27 "This is humanTime after normalization".dump(); 28 humanTime.dump(); 29 /* convert calendar time to time object, compare with original time */ 30 thirdTime = humanTime.asTime(); 31 "Here are firstTime and thirdTime".dump(); 32 firstTime.dump(); 33 thirdTime.dump(); 34 String("There is a difference of ", 35 firstTime.interval(thirdTime).asString(), 36 " seconds from thirdTime to firstTime.").dump();When it runs, you see these results:
String: <Here are firstTime and secondTime> Time: <Modified Julian Day 50126, Helgeseconds 340320000> Time: <Modified Julian Day 50091, Helgeseconds 1300320000> String: <firstTime comes after secondTime.> String: <This is humanTime after conversion from firstTime> CalendarTime: year = 1996 month = 2 day = 12 hour = 18 minute = 21 second = 48 DST = 0 timezone = -480 dayOfWeek = 2 dayOfYear = 43 String: <This is humanTime after decrementing 3000000 seconds> CalendarTime: year = 1996 month = 2 day = 12 hour = 18 minute = 21 second = -2999952 DST = 0 timezone = -480 dayOfWeek = 2 dayOfYear = 43 String: <This is humanTime after normalization> CalendarTime: year = 1996 month = 1 day = 9 hour = 1 minute = 1 second = 48 DST = 0 timezone = -480 dayOfWeek = 3 dayOfYear = 9 String: <Here are firstTime and thirdTime> Time: <Modified Julian Day 50126, Helgeseconds 340320000> Time: <Modified Julian Day 50091, Helgeseconds 1300320000>This program creates a time object in line 7, then adjusts it in line 8 to create a second time object that is three million seconds (a little more than a month) less than the first time object. Lines 10 and 11 dump the time objects so you can see their values, then the code in lines 12-16 checks the relationship between the two times and reports on what it finds.
Line 18 converts the first time object into a localized calendar time (Pacific Standard time, in this case), then line 20 dumps the object so you can see its attributes.
In line 22, the program decrements three million seconds by subtracting 3000000 from the second
attribute of the calendar time; line 24 dumps the calendar time so you can see its unnormalized second value.
Lines 26-28 normalize the calendar time and then dumps it. Notice that the subtraction of three million seconds, when normalized, creates an expression of time more than a month earlier than the calendar time when it was first converted.
Line 30 converts the altered calendar time back to a third time object. Because the calendar time was altered by subtracting three million seconds, it should be three million seconds before the first time object. Lines 32 and 33 dump the two time objects so you can see them. Line 35 subtracts the third time from the first time to get an interval of time in seconds between the two time objects, then converts the integer value to a string so that it may be dumped with the larger string concatenated in lines 34-36.
Generated with Harlequin WebMaker