1.    /**
2.        DateAndTime Class
3.       
4.        Last Updated: Tue Nov 29 11:48:43 2005
5.       
6.        Tokens:
7.            Y   Full representation of the current year (2005..)
8.            y   Two-digit representation of the current year (05..)
9.            MN Month represented as name (Jan...Dec)
10.           mn Month represented as number in year (1..12)
11.           D   Day represented as name (Sun..Sat)
12.           d   Day represented as number in month (0..31)
13.           H   Hour in 24 hour time
14.           h   Hour in 12 hour time
15.           tod Time of day represented as name (AM/PM)
16.           m   Minutes of current hour
17.           s   Second of current minute
18.      
19.       Note:
20.           using an integer character after the token will cause it to be
21.           padded with n leading zeros.
22.          
23.       Example:
24.           '(D) (H1):(m1):(s1)' will resolve to 'Sun 03:01:32'
25.      
26.       Replacing AM/PM, Day names, Month Names:
27.           These are accessable instance variables. You can just reassign them within the instance:
28.               var d = new DateAndTime('(D) (H1):(m1):(s1)');
29.               d.todnames = ['AM', 'PM'];
30.               d.daynames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
31.               d.monthnames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
32.              
33.           It is also possible to replace the default delimiter tokens '(' and ')':
34.               var d = new DateAndTime();
35.               d.delimiters = ['{', '}'];
36.               d.Compile('{H1}:{m1}:{s1}');
37.      
38.    **/
39.   function DateAndTime (pattern)
40.   {
41.       /* User Customisable Lists */
42.       this.todnames = ['AM', 'PM'];
43.       this.daynames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
44.       this.monthnames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
45.       this.delimiters = ['(', ')'];
46.        
47.       /* Set to true to display when reprocessing occures */
48.       this.debug = false;
49.      
50.       this.date = new Date();
51.       this.pattern = undefined;
52.       this.tokenizedpattern = [];
53.       this.cachedstring = undefined;
54.       this.updatetimestamp = undefined;
55.       if ( pattern != undefined )
56.       {
57.           this.Compile(pattern);
58.       }
59.   }
60.   DateAndTime.prototype.pad = function (what, pad)
61.   {
62.       what = String(what);
63.       for ( var i=0, n=pad-what.length+1; i < n; ++i )
64.       {
65.           what = '0' + what;
66.       }
67.       return what;
68.   };
69.   DateAndTime.prototype.Compile = function (pattern)
70.   {
71.       var offset, j;
72.       this.pattern = pattern;
73.       this.tokenizedpattern = [];
74.       for ( offset=0; offset < this.pattern.length; )
75.       {
76.           if ( this.pattern.charAt(offset) == this.delimiters[0] )
77.           {
78.               j = this.pattern.indexOf(this.delimiters[1], offset);
79.               var token = this.pattern.substr(offset+1, j-offset-1);
80.               var padamount = 0;
81.               if ( token.length > 1 )
82.               {
83.                   var lastchar = token.charCodeAt(token.length-1) - 48;
84.                   if ( lastchar >= 0 && lastchar <= 9 )
85.                   {
86.                       padamount = lastchar;
87.                       token = token.substr(0, token.length-1);
88.                   }
89.               }
90.               switch ( token )
91.               {
92.                   case 's':
93.                       token = new this.TokenSecond(this, padamount);
94.                       break;
95.                   case 'm':
96.                       token = new this.TokenMinute(this, padamount);
97.                       break;
98.                   case 'tod':
99.                       token = new this.TokenTOD(this);
100.                      break;
101.                  case 'h':
102.                      token = new this.TokenHour(this, padamount, true);
103.                      break;
104.                  case 'H':
105.                      token = new this.TokenHour(this, padamount);
106.                      break;
107.                  case 'd':
108.                      token = new this.TokenDay(this, padamount);
109.                      break;
110.                  case 'D':
111.                      token = new this.TokenDayAsName(this);
112.                      break;
113.                  case 'mn':
114.                      token = new this.TokenMonth(this, padamount);
115.                      break;
116.                  case 'MN':
117.                      token = new this.TokenMonthAsName(this);
118.                      break;
119.                  case 'Y':
120.                      token = new this.TokenYearFull(this);
121.                      break;
122.                  case 'y':
123.                      token = new this.TokenYear(this, padamount);
124.                      break;
125.                  default:
126.                      token = new this.TokenDefault(this, token);
127.                      break;
128.              }
129.              /* Add our Tokenized Pattern to our Array */
130.              this.tokenizedpattern.push(token);
131.              offset = j+1;
132.          }
133.          else
134.          {
135.              j = this.pattern.indexOf(this.delimiters[0], offset);
136.              if ( j == -1 )
137.              {
138.                  j = this.pattern.length;
139.              }
140.              this.tokenizedpattern.push(this.pattern.substr(offset, j-offset));
141.              offset = j;
142.          }
143.      }
144.  }
145.  DateAndTime.prototype.toString = function ()
146.  {
147.      var milliseconds = getTimer();
148.      if ( this.updatetimestamp == undefined || this.updatetimestamp < milliseconds )
149.      {
150.          if ( this.debug )
151.          {
152.              trace('reprocessing token list');
153.          }
154.          /* Reprocess our token list */
155.          this.date = new Date();
156.          this.cachedstring = '';
157.          this.updatetimestamp = undefined;
158.          for ( var i=0; i < this.tokenizedpattern.length; ++i )
159.          {
160.              if ( typeof(this.tokenizedpattern[i]) == 'object' )
161.              {
162.                  /* Probable Token
163.                    Adjust our Update Timestamp */
164.                  var nextupdate = this.date.getTime() + (this.tokenizedpattern[i].resolution
165.                                                      - (this.date.getTime() % this.tokenizedpattern[i].resolution));
166.                  if ( this.updatetimestamp == undefined || nextupdate < this.updatetimestamp )
167.                  {
168.                      this.updatetimestamp = nextupdate;
169.                  }
170.              }
171.              this.cachedstring += String(this.tokenizedpattern[i]);
172.          }
173.          /* Convert our delay into to swf-local milliseconds */
174.          this.updatetimestamp = milliseconds + ( this.updatetimestamp - this.date.getTime() );
175.          return this.cachedstring;
176.      }
177.      return this.cachedstring;
178.  }
179.  /* Token: Default */
180.  DateAndTime.prototype.TokenDefault = function (parent, label)
181.  {
182.      this.parent = parent;
183.      this.label = label;
184.      this.resolution = 86400000; // One Day
185.  }
186.  DateAndTime.prototype.TokenDefault.prototype.toString = function ()
187.  {
188.      return this.delimiters[0] + this.label + this.delimiters[1];
189.  };
190.  /* Token: Second */
191.  DateAndTime.prototype.TokenSecond = function (parent, pad)
192.  {
193.      this.parent = parent;
194.      this.resolution = 1000; // One Second
195.      this.pad = ( pad == undefined ) ? 0 : pad;
196.  };
197.  DateAndTime.prototype.TokenSecond.prototype.toString = function ()
198.  {
199.      return this.parent.pad(this.parent.date.getSeconds(), this.pad);
200.  };
201.  /* Token: Minute */
202.  DateAndTime.prototype.TokenMinute = function (parent, pad)
203.  {
204.      this.parent = parent;
205.      this.resolution = 60000; // One Minute
206.      this.pad = ( pad == undefined ) ? 0 : pad;
207.  };
208.  DateAndTime.prototype.TokenMinute.prototype.toString = function ()
209.  {
210.      return this.parent.pad(this.parent.date.getMinutes(), this.pad);
211.  };
212.  /* Token: TOD */
213.  DateAndTime.prototype.TokenTOD = function (parent)
214.  {
215.      this.parent = parent;
216.      this.resolution = 43200000; // Twelve Hours
217.  };
218.  DateAndTime.prototype.TokenTOD.prototype.toString = function ()
219.  {
220.      if ( this.parent.date.getHours() >= 12 )
221.      {
222.          return this.parent.todnames[1];
223.      }
224.      return this.parent.todnames[0];
225.  };
226.  /* Token: Hour */
227.  DateAndTime.prototype.TokenHour = function (parent, pad, twelvehour)
228.  {
229.      this.parent = parent;
230.      this.resolution = 3600000; // One Hour
231.      this.twelvehour = ( twelvehour == undefined ) ? false : true;
232.      this.pad = ( pad == undefined ) ? 0 : pad;
233.  };
234.  DateAndTime.prototype.TokenHour.prototype.toString = function ()
235.  {
236.      var hours = this.parent.date.getHours();
237.      if ( this.twelvehour && hours > 12 )
238.      {
239.          hours -= 12;
240.      }
241.      return this.parent.pad(hours, this.pad);
242.  };
243.  /* Token: Day */
244.  DateAndTime.prototype.TokenDay = function (parent, pad)
245.  {
246.      this.parent = parent;
247.      this.resolution = 86400000; // One Day
248.      this.pad = ( pad == undefined ) ? 0 : pad;
249.  };
250.  DateAndTime.prototype.TokenDay.prototype.toString = function ()
251.  {
252.      return this.parent.pad(this.parent.date.getDate(), this.pad);
253.  };
254.  /* Token: DayAsName */
255.  DateAndTime.prototype.TokenDayAsName = function (parent)
256.  {
257.      this.parent = parent;
258.      this.resolution = 86400000; // One Day
259.  };
260.  DateAndTime.prototype.TokenDayAsName.prototype.toString = function ()
261.  {
262.      return this.parent.daynames[this.parent.date.getDay()];
263.  };
264.  /* Token: Month */
265.  DateAndTime.prototype.TokenMonth = function (parent, pad)
266.  {
267.      this.parent = parent;
268.      this.resolution = 86400000; // One Day
269.      this.pad = ( pad == undefined ) ? 0 : pad;
270.  };
271.  DateAndTime.prototype.TokenMonth.prototype.toString = function ()
272.  {
273.      return this.parent.pad(this.parent.date.getMonth()+1, this.pad);
274.  };
275.  /* Token: MonthAsName */
276.  DateAndTime.prototype.TokenMonthAsName = function (parent)
277.  {
278.      this.parent = parent;
279.      this.resolution = 86400000; // One Day
280.  };
281.  DateAndTime.prototype.TokenMonthAsName.prototype.toString = function ()
282.  {
283.      return this.parent.monthnames[this.parent.date.getMonth()];
284.  };
285.  /* Token: Year */
286.  DateAndTime.prototype.TokenYear = function (parent, pad)
287.  {
288.      this.parent = parent;
289.      this.resolution = 86400000; // One Day
290.      this.pad = ( pad == undefined ) ? 0 : pad;
291.  };
292.  DateAndTime.prototype.TokenYear.prototype.toString = function ()
293.  {
294.      return this.parent.pad(String(this.parent.date.getFullYear()).substr(3,1), this.pad);
295.  };
296.  /* Token: YearFull */
297.  DateAndTime.prototype.TokenYearFull = function (parent)
298.  {
299.      this.parent = parent;
300.      this.resolution = 86400000; // One Day
301.  };
302.  DateAndTime.prototype.TokenYearFull.prototype.toString = function ()
303.  {
304.      return String(this.parent.date.getFullYear());
305.  };