BYU Home pageBRIGHAM YOUNG UNIVERSITY
  Humanities Technology and Research Support Center
Back     CHum Revolution Gateway

CHum 310
Time and Timing in Revolution

Time and Date

As you no doubt recall, the Revolution functions the date and the time return the current date and time information as provided by the host operating system. You may also remember that you can get the date and time information in various formats, determined by the use of keywords like long and short. Let's revisit these functions and get a more in-depth look at them.

Here are the major variants of the date function. If you call these functions you'll get the results shown. Try them out in your own stack or in the message box.

The date function
This form Produces this format
the date 3/13/07
the long date Tuesday, March 13, 2007
the abbreviated date
(or abbrev or abbr)
Tue, Mar 13, 2007
the short date 3/13/07 (same as the date)
the internet date Tue, 13 Mar 2007 13:36:47 -0700
the english date (forces the date to be displayed in U.S. format—the default)
the system date (forces the date to be displayed in format specified by the host OS—country specific)

The time function

This form Produces this format
the time 1:49 PM
the long time 1:49:31 PM
the abbreviated time 1:49 PM (same as the time)
the short time 1:49 PM (same as the time)
the english date (forces the time to be displayed in U.S. format—the default)
the system date (forces the time to be displayed in format specified by the host OS—country specific)

There are two functions—the monthNames and the weekdayNames—that return information useful when working with dates .

The monthNames function
This form Produces This form Produces This form Produces
the monthNames January
February
March
April
May
June
July
August
September
October
November
December
the short monthNames

1
2
3
4
5
6
7
8
9
10
11
12

the abbreviated monthNames Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec

The weekdayNames function

This form Produces This form Produces This form Produces
the weekdayNames Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
the short weekdayNames

1
2
3
4
5
6
7

the abbreviated weekdayNames Sun
Mon
Tue
Wed
Thu
Fri
Sat

Checking for a valid date

If you need to verify whether a particular string is in a valid date format, you can use the is [not] a boolean operator. For example, if you are asking your users to enter a date, you may want to first check for a valid format:

if myDate is not a date then
  answer "Please type your date in this format: mm/dd/yyyy."
end if

Note that both a valid date string and a valid time string will cause is a date to evaluate to true, so if you want to make sure the string is a date, rather than a time, you will have to perform other checks besides this basic format check.

Date and Time Calculations

While getting date and time information from the OS is useful and important, it is even more useful to be able to do calculations based on dates and times. For example, what if you want to know which day of the week the 15th of April falls on? Or how many shopping days are left until Christmas? With a few useful tools you can easily do date and time arithmetic.

The first set of tools we have is the time units keywords. Revolution understands these time units:

seconds
ticks (one-sixtieth of a second)
milliseconds (one-thousandth of a second)

For each of these time units there is a corresponding function:

the seconds function: the total number of seconds since GMT*, January 1, 1970
the long seconds: seconds and fractions of seconds since GMT*, January 1, 1970
the ticks function: the total number of ticks since GMT*, January 1, 1970
the milliseconds: the total number of milliseconds since GMT*, January 1, 1970

* GMT = Greenwich Mean Time

To calculate minutes, days, weeks, etc., remember the simple formulas:

one minute = 60 seconds
one hour = 60*60 seconds
one day = 60*60*24 seconds
one week = 60*60*24*7 seconds
one year = 60*60*24*365 seconds

The convert command

The convert command is a powerful tool that lets you easily change any valid time or date format to any other valid format. You can specify a from format if desired, but if you don't Revolution just analyzes the input to determine the format it's in.

Basic Syntax:

convert <date and/or time> to format [and format]
where <date and/or time> is a string in any valid date and/or time format
    e.g., the long date; the date && the time; a variable with a valid date or time in it
(The second format is optional. It simply means that instead of converting to a date only format or a time only format, you can convert to a date and a time.)

If you pass it a literal string, like this:

convert "March 14, 2007" to seconds

the converted time will go into the it variable.

If you pass it a date or time in a variable, the converted time/date will go into the variable you passed:

put the long date && the long time into tCurrentTime
-- makes the value of tCurrentTime: Tuesday, March 13, 2007 6:36:47 PM
convert tCurrentTime to abbr time and abbr date

-- tCurrentTime now holds something like this: 6:37 PM Tue, Mar 13, 2007

The convert command will convert to and from any of the date and time formats listed above, plus two other formats:

seconds
dateItems

The dateItems format is a list of numbers, separated by commas (hence, dateitems.) There are seven items in the dateitems format:

year,month num,day of month,hour in 24-hour time,minute,second,numeric day of week.

So, for example, Wednesday, March 14, 2007 2:23:30 PM converted to dateitems would be:

2007,3,14,14,23,30,4

Why is this useful? There are a lot of reasons, but one major one is you can do "date arithmetic" with date items by adding or subtracting to or from the item, e.g.:

-- I want to find out what day of the week today's date falls on in 20 years
convert the long date to dateItems --> 2007,3,14,0,0,0,3
add 20 to item 1 of it --> 2027,3,14,0,0,0,3
convert it to dateItems --> 2027,3,14,0,0,0,1
put line (item 7 of it) of the weekdayNames --> Sunday

It even works if your arithmetic puts one or more of the items out of range, because the convert command will automatically adjust the date items to the appropriate values:

-- I want to find out the date 23 days from today:
convert the date to dateItems --> 2007,3,14,0,0,0,3
add 23 to item 3 of it --> 2007,3,37,0,0,0,3
convert it to date --> 4/6/07

You can also use the seconds (or ticks or milliseconds) for time arithmetic.

-- How many days until Christmas?
convert "December 25," && the last word of the long date to seconds -->e.g., 1197705600
put it - the seconds into totalSeconds
put totalSeconds / (60*60*24) into totalDays
put "Only" && totalDays
&& "shopping days until Christmas!"

Executing Time-delayed or Repeating Events

Often you may want to something to happen after a certain amount of time has elapsed, or you may want something to happen every few minutes or seconds. To do that you use a command that should already be familiar to you: the send command. This command has an optional in time clause that will cause the message you send to be executed when that time period has elapsed.

Syntax: send <message> to <object> in <time>
Where <message> is the name of any handler, and
<object> is a valid object reference (only needed if the object you are sending the message to is not in the current message hierarchy, or if you want to bypass intervening objects in the hierarchy,) and
<time> is any valid time period in seconds, ticks or milliseconds.

Examples:

Play a system alert to signal the end of a timed test:

send "beep" to this card in 30 seconds

To automatically advance to the next card after a specified time period:

send "go to next card" in 180 ticks

As useful as it is to execute a single action at some future time, the real power of send in time comes when you want to continuously check or update some aspect of your stack.

Examples:

Create a simple digital clock or timer on your card:

In button "startTimer":

on mouseUp
  updateTime
end mouseUp


In the card script:

on updateTime
  put the long time into field "timer"
  send updateTime to me in 500 milliseconds
end updateTime

With calls like this problems can arise. Let's say you wanted to move on to another card where the timer was no longer required. When you go to the next card, there would most likely still be a message in the queue waiting to be sent, but since you are now on a card that doesn't have field "timer" on it, the updateTime handler would cause an error. So you need to cancel the pending message before you leave the card. For this there is the cancel command:

Syntax: cancel <queued message ID>
The < queued message ID> is a number that is automatically generated when you use the send in <time> command. You can capture it by using the result function, storing the ID in a global variable or custom property, then canceling it when you leave the card:

In the card script:

global messageID
on updateTime
  put the long time into field "timer"
  send updateTime to me in 500 milliseconds
  put the result into messageID
end updateTim

on closeCard
  cancel messageID
end closeCard

What if you have several messages in the queue and you want to cancel some or all of them when you leave the card. One way is to save each message ID in its own global variable, but that can rapidly become unwieldy. Another approach would be to save all queued message IDs in a single variable, on separate lines, then loop through the variable when you leave the card:

In the card script:

global messageIDs
on updateTime
  put the long time into field "timer"
  send updateTime to me in 500 milliseconds
  if messageIDs is empty then
    put the result into messageIDs
  else
    put cr & the result after messageIDs
  end if
end updateTime

on startCounting
  put the seconds - startSeconds into fld "counter"
  send startCounting to me in 30 ticks
  if messageIDs is empty then
    put the result into messageIDs
  else
    put cr & the result after messageID
  end if
end startCounting

on closeCard
  repeat for each line thisMsgID in messageIDs
    cancel thisMsgID
  end repeat
end closeCard

There is also a function, the pendingMessages, that will return a list of all queued messages. Each line contains four items of information, the first item being the message ID. So if you wanted to kill all queued messages you could do this:

on closeCard -- brute-force method
  repeat until the pendingMessages is empty
    cancel item 1 of line 1 of the pendingMessages
  end repeat
end closeCard

Your Turn:

Put your new knowledge to work by doing the Timing Assignment. When you are finished copy it to the Homework Drop folder.


Back     CHum Revolution Gateway
Maintained by Devin Asay.
Copyright © 2005 Brigham Young University