wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #define DEBUG
2 /*
3 * ClockCmd.java --
4 *
5 * Implements the built-in "clock" Tcl command.
6 *
7 * Copyright (c) 1998-2000 Christian Krone.
8 * Copyright (c) 1997 Cornell University.
9 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
10 * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
11 *
12 * See the file "license.terms" for information on usage and
13 * redistribution of this file, and for a DISCLAIMER OF ALL
14 * WARRANTIES.
15 *
16 * Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart
17 *
18 * RCS @(#) $Id: ClockCmd.java,v 1.6 2003/02/03 04:48:46 mdejong Exp $
19 *
20 */
21 using System;
22 using System.Globalization;
23 using System.Text;
24 using System.Collections;
25  
26  
27 namespace tcl.lang
28 {
29  
30 /// <summary> This class implements the built-in "clock" command in Tcl.</summary>
31  
32 class ClockCmd : Command
33 {
34  
35 private static readonly string[] validCmds = new string[] { "clicks", "format", "scan", "seconds" };
36  
37 private const int CMD_CLICKS = 0;
38 private const int CMD_FORMAT = 1;
39 private const int CMD_SCAN = 2;
40 private const int CMD_SECONDS = 3;
41  
42 private static readonly string[] clicksOpts = new string[] { "-milliseconds" };
43  
44 private const int OPT_CLICKS_MILLISECONDS = 0;
45  
46 private static readonly string[] formatOpts = new string[] { "-format", "-gmt" };
47  
48 private const int OPT_FORMAT_FORMAT = 0;
49 private const int OPT_FORMAT_GMT = 1;
50  
51 private static readonly string[] scanOpts = new string[] { "-base", "-gmt" };
52  
53 private const int OPT_SCAN_BASE = 0;
54 private const int OPT_SCAN_GMT = 1;
55  
56 internal const int EPOCH_YEAR = 1970;
57 internal const int MILLIS_PER_HOUR = 60 * 60 * 1000;
58 public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
59 {
60 int clockVal; // Time value as seconds of epoch.
61 string dateString; // Time value as string.
62 int argIx; // Counter over arguments.
63 string format = null; // User specified format string.
64 bool useGmt = false; // User specified flag to use gmt.
65 TclObject baseObj = null; // User specified raw value of baseClock.
66 System.DateTime baseClock; // User specified time value.
67 System.DateTime date; // Parsed date value.
68  
69 if ( objv.Length < 2 )
70 {
71 throw new TclNumArgsException( interp, 1, objv, "option ?arg ...?" );
72 }
73 int cmd = TclIndex.get( interp, objv[1], validCmds, "option", 0 );
74  
75 switch ( cmd )
76 {
77  
78 case CMD_CLICKS:
79 {
80 if ( objv.Length > 3 )
81 {
82 throw new TclNumArgsException( interp, 2, objv, "?-milliseconds?" );
83 }
84 if ( objv.Length == 3 )
85 {
86 // We can safely ignore the -milliseconds options, since
87 // we measure the clicks in milliseconds anyway...
88 int clicksOpt = TclIndex.get( interp, objv[2], clicksOpts, "switch", 0 );
89 }
90 long millis = ( System.DateTime.Now.Ticks - 621355968000000000 ) / 10000;
91 int clicks = (int)( millis % System.Int32.MaxValue );
92 interp.setResult( clicks );
93 break;
94 }
95  
96  
97 case CMD_FORMAT:
98 {
99 if ( ( objv.Length < 3 ) || ( objv.Length > 7 ) )
100 {
101 throw new TclNumArgsException( interp, 2, objv, "clockval ?-format string? ?-gmt boolean?" );
102 }
103 clockVal = TclInteger.get( interp, objv[2] );
104  
105 for ( argIx = 3; argIx + 1 < objv.Length; argIx += 2 )
106 {
107 int formatOpt = TclIndex.get( interp, objv[argIx], formatOpts, "switch", 0 );
108 switch ( formatOpt )
109 {
110  
111 case OPT_FORMAT_FORMAT:
112 {
113  
114 format = objv[argIx + 1].ToString();
115 break;
116 }
117  
118 case OPT_FORMAT_GMT:
119 {
120 useGmt = TclBoolean.get( interp, objv[argIx + 1] );
121 break;
122 }
123 }
124 }
125 if ( argIx < objv.Length )
126 {
127 throw new TclNumArgsException( interp, 2, objv, "clockval ?-format string? ?-gmt boolean?" );
128 }
129 FormatClock( interp, clockVal, useGmt, format );
130 break;
131 }
132  
133  
134 case CMD_SCAN:
135 {
136 if ( ( objv.Length < 3 ) || ( objv.Length > 7 ) )
137 {
138 throw new TclNumArgsException( interp, 2, objv, "dateString ?-base clockValue? ?-gmt boolean?" );
139 }
140  
141 dateString = objv[2].ToString();
142  
143 for ( argIx = 3; argIx + 1 < objv.Length; argIx += 2 )
144 {
145 int scanOpt = TclIndex.get( interp, objv[argIx], scanOpts, "switch", 0 );
146 switch ( scanOpt )
147 {
148  
149 case OPT_SCAN_BASE:
150 {
151 baseObj = objv[argIx + 1];
152 break;
153 }
154  
155 case OPT_SCAN_GMT:
156 {
157 useGmt = TclBoolean.get( interp, objv[argIx + 1] );
158 break;
159 }
160 }
161 }
162 if ( argIx < objv.Length )
163 {
164 throw new TclNumArgsException( interp, 2, objv, "clockval ?-format string? ?-gmt boolean?" );
165 }
166 if ( baseObj != null )
167 {
168 long seconds = TclInteger.get( interp, baseObj );
169 baseClock = new System.DateTime( (long)seconds * 10000 * 1000 + 621355968000000000 );
170 }
171 else
172 {
173 baseClock = System.DateTime.Now;
174 }
175 try
176 {
177 date = GetDate( dateString, baseClock, useGmt );
178 }
179 catch ( FormatException )
180 {
181 throw new TclException( interp, "unable to convert date-time string \"" + dateString + "\"" );
182 }
183 long millis = ( date.Ticks - 621355968000000000 ) / 10000;
184 int seconds2 = (int)( millis / 1000 );
185 interp.setResult( seconds2 );
186 break;
187 }
188  
189  
190 case CMD_SECONDS:
191 {
192 if ( objv.Length != 2 )
193 {
194 throw new TclNumArgsException( interp, 2, objv, null );
195 }
196 long millis = ( System.DateTime.Now.Ticks - 621355968000000000 ) / 10000;
197 int seconds = (int)( millis / 1000 );
198 interp.setResult( seconds );
199 break;
200 }
201 }
202 return TCL.CompletionCode.RETURN;
203 }
204 private void FormatClock( Interp interp, int clockVal, bool useGMT, string format )
205 {
206 DateTime date = new DateTime( (long)clockVal * 10000 * 1000 + 621355968000000000 );
207  
208 DateTimeFormatInfo formatInfo = new DateTimeFormatInfo();
209 string fmt, locFmt;
210  
211 GregorianCalendar calendar = new GregorianCalendar();
212  
213 System.Int32[] temp_int_array;
214 temp_int_array = new System.Int32[3];
215 temp_int_array[0] = 0;
216 temp_int_array[1] = 0;
217 temp_int_array[2] = 0;
218 System.Int32[] fp = temp_int_array;
219 StringBuilder result = new StringBuilder();
220  
221 if ( (System.Object)format == null )
222 {
223 format = new StringBuilder( "%a %b %d %H:%M:%S %Z %Y" ).ToString();
224 }
225  
226 if ( useGMT )
227 {
228 date = date.ToUniversalTime();
229 }
230 if ( format.Equals( "%Q" ) )
231 {
232 // Enterprise Stardate. (seems to be Star Track fan coding)
233 // ATK not tested
234 int trekYear = date.Year + 377 - 2323;
235 int trekDay = ( date.DayOfYear * 1000 ) / ( calendar.IsLeapYear( date.Year ) ? 366 : 365 );
236 int trekHour = ( 24 * 60 + date.Minute ) / 144;
237  
238 interp.setResult( "Stardate " + ( trekYear < 10 ? "0" : "" ) + ( trekYear * 1000 + trekDay ) + '.' + trekHour );
239 return;
240 }
241  
242 for ( int ix = 0; ix < format.Length; ix++ )
243 {
244 if ( format[ix] == '%' && ix + 1 < format.Length )
245 {
246 switch ( format[++ix] )
247 {
248  
249 case '%':
250 result.Append( '%' );
251 break;
252  
253 case 'a':
254 result.Append( date.ToString( "ddd", formatInfo ) );
255 break;
256  
257 case 'A':
258 result.Append( date.ToString( "dddd", formatInfo ) );
259 break;
260 case 'b':
261 case 'h':
262 result.Append( date.ToString( "MMM", formatInfo ) );
263 break;
264 case 'B':
265 result.Append( date.ToString( "MMMM", formatInfo ) );
266 break;
267 case 'c':
268 result.Append( date.ToString() );
269 break;
270 case 'C':
271 int century = date.Year / 100;
272 result.Append( ( century < 10 ? "0" : "" ) + century );
273 break;
274 case 'd':
275 result.Append( date.ToString( "dd", formatInfo ) );
276 break;
277 case 'D':
278 result.Append( date.ToString( "MM/dd/yy", formatInfo ) );
279 break;
280 case 'e':
281 result.Append( date.ToString( "%d", formatInfo ) );
282 break;
283 case 'H':
284 result.Append( date.ToString( "HH", formatInfo ) );
285 break;
286 case 'I':
287 result.Append( date.ToString( "hh", formatInfo ) );
288 break;
289 case 'j':
290 result.Append( date.Year.ToString( "0###" ) );
291 break;
292 case 'k':
293 result.Append( date.ToString( "H", formatInfo ) );
294 break;
295 case 'l':
296 result.Append( date.ToString( "%h", formatInfo ) );
297 break;
298 case 'm':
299 // Month number (01 - 12).
300 result.Append( date.ToString( "MM", formatInfo ) );
301 break;
302 case 'M':
303 // Minute (00 - 59).
304 result.Append( date.ToString( "mm", formatInfo ) );
305 break;
306 case 'n':
307 // Insert a newline.
308 result.Append( '\n' );
309 break;
310 case 'p':
311 // AM/PM indicator.
312 result.Append( date.ToString( "tt", formatInfo ) );
313 break;
314 case 'r':
315 // %r
316 //Time in a locale-specific "meridian" format. The "meridian" format in the default "C" locale is "%I:%M:%S %p".
317 result.Append( date.ToString( "hh:mm:ss tt", formatInfo ) );
318 break;
319 case 'R':
320 //%R
321 //Time as %H:%M.
322 result.Append( date.ToString( "HH:MM", formatInfo ) );
323 break;
324 case 's':
325 //%s
326 //Count of seconds since the epoch, expressed as a decimal integer.
327 result.Append( ( date.Ticks / 1000 ).ToString() );
328 break;
329  
330 case 'S':
331 //%S
332 //Seconds (00 - 59).
333 result.Append( date.ToString( "ss", formatInfo ) );
334 break;
335 case 't':
336 //%t
337 //Insert a tab.
338 result.Append( '\t' );
339 break;
340  
341 case 'T':
342 //%T
343 //Time as %H:%M:%S.
344 result.Append( date.ToString( "HH:mm:ss", formatInfo ) );
345 break;
346  
347 case 'u':
348 //%u
349 //Weekday number (Monday = 1, Sunday = 7).
350 if ( date.DayOfWeek == DayOfWeek.Sunday )
351 {
352 result.Append( "7" );
353 }
354 else
355 {
356 result.Append( ( (int)date.DayOfWeek ).ToString() );
357 }
358 break;
359 case 'U':
360 //%U
361 //Week of year (00 - 52), Sunday is the first day of the week.
362 int weekS = GetWeek( date, System.DayOfWeek.Sunday, false );
363 result.Append( ( weekS < 10 ? "0" : "" ) + weekS );
364 break;
365  
366 case 'V':
367 //%V
368 //Week of year according to ISO-8601 rules. Week 1 of a given year is the week containing 4 January.
369 int isoWeek = GetWeek( date, System.DayOfWeek.Monday, true );
370 result.Append( ( isoWeek < 10 ? "0" : "" ) + isoWeek );
371 break;
372  
373 case 'w':
374 //%w
375 //Weekday number (Sunday = 0, Saturday = 6).
376 result.Append( ( (int)date.DayOfWeek ).ToString() );
377 break;
378  
379 case 'W':
380 //%W
381 //Week of year (00 - 52), Monday is the first day of the week.
382 int weekM = GetWeek( date, System.DayOfWeek.Monday, false );
383 result.Append( ( weekM < 10 ? "0" : "" ) + weekM );
384 break;
385 case 'x':
386 //%x
387 //Locale specific date format. The format for a date in the default "C" locale for Unix/Mac is "%m/%d/%y". On Windows, this value is the locale specific short date format, as specified in the Regional Options control panel settings.
388 result.Append( date.ToShortDateString() );
389 break;
390  
391 case 'X':
392 //%X
393 //Locale specific 24-hour time format. The format for a 24-hour time in the default "C" locale for Unix/Mac is "%H:%M:%S". On Windows, this value is the locale specific time format, as specified in the Regional Options control panel settings.
394 result.Append( date.ToShortTimeString() );
395 break;
396 case 'y':
397 //%y
398 //Year without century (00 - 99).
399 result.Append( date.ToString( "yy", formatInfo ) );
400 break;
401  
402 case 'Y':
403 //%Y
404 //Year with century (e.g. 1990)
405 result.Append( date.ToString( "yyyy", formatInfo ) );
406 break;
407 case 'Z':
408 //%Z
409 //Time zone name.
410 result.Append( date.ToString( "zzz", formatInfo ) );
411 break;
412 default:
413 result.Append( format[ix] );
414 break;
415 }
416 }
417 else
418 {
419 result.Append( format[ix] );
420 }
421 }
422 interp.setResult( result.ToString() );
423 }
424 private int GetWeek( DateTime date, System.DayOfWeek firstDayOfWeek, bool iso )
425 {
426 GregorianCalendar cal = new GregorianCalendar();
427 CalendarWeekRule weekRule = CalendarWeekRule.FirstFullWeek;
428 if ( iso )
429 {
430 firstDayOfWeek = System.DayOfWeek.Monday;
431 weekRule = CalendarWeekRule.FirstFourDayWeek;
432 }
433 return cal.GetWeekOfYear( date, weekRule, firstDayOfWeek );
434 }
435 private void SetWeekday( TclDateTime calendar, ClockRelTimespan diff )
436 // time difference to evaluate
437 {
438 int weekday = diff.getWeekday();
439 int dayOrdinal = diff.DayOrdinal;
440  
441 // ATK
442 // while (SupportClass.CalendarManager.manager.Get(calendar, SupportClass.CalendarManager.DAY_OF_WEEK) != weekday)
443 // {
444 //
445 // calendar.add(SupportClass.CalendarManager.DATE, 1);
446 // }
447 // if (dayOrdinal > 1)
448 // {
449 //
450 // calendar.add(SupportClass.CalendarManager.DATE, 7 * (dayOrdinal - 1));
451 // }
452 }
453 private void SetOrdMonth( TclDateTime calendar, ClockRelTimespan diff )
454 // time difference to evaluate
455 {
456 int month = diff.Months;
457 int ordMonth = diff.OrdMonth;
458  
459 // calendar.add(SupportClass.CalendarManager.MONTH, 1); /* we want to get the next month... */
460 // while (SupportClass.CalendarManager.manager.Get(calendar, SupportClass.CalendarManager.MONTH) != month)
461 // {
462 // calendar.add(SupportClass.CalendarManager.MONTH, 1);
463 // }
464 // if (ordMonth > 1)
465 // {
466 // calendar.add(SupportClass.CalendarManager.YEAR, ordMonth - 1);
467 // }
468 calendar.day = 1;
469 calendar.hour = 0;
470 calendar.minute = 0;
471 calendar.second = 0;
472 }
473 private System.DateTime GetDate( string dateString, System.DateTime baseDate, bool useGMT )
474 {
475 if ( useGMT )
476 {
477 baseDate = baseDate.ToUniversalTime();
478 }
479 TclDateTime calendar = new TclDateTime();
480 calendar.dateTime = baseDate;
481 calendar.hour = 0;
482 calendar.minute = 0;
483 calendar.second = 0;
484 calendar.millisecond = 0;
485  
486 ClockToken[] dt = GetTokens( dateString, false );
487  
488 System.Int32 parsePos = 0;
489 ClockRelTimespan diff = new ClockRelTimespan();
490 int hasTime = 0;
491 int hasZone = 0;
492 int hasDate = 0;
493 int hasDay = 0;
494 int hasOrdMonth = 0;
495 int hasRel = 0;
496  
497 while ( parsePos < dt.Length )
498 {
499 if ( ParseTime( dt, ref parsePos, calendar ) )
500 {
501 hasTime++;
502 }
503 else if ( ParseZone( dt, ref parsePos, calendar ) )
504 {
505 hasZone++;
506 }
507 else if ( ParseIso( dt, ref parsePos, calendar ) )
508 {
509 hasDate++;
510 }
511 else if ( ParseDate( dt, ref parsePos, calendar ) )
512 {
513 hasDate++;
514 }
515 else if ( ParseDay( dt, ref parsePos, diff ) )
516 {
517 hasDay++;
518 }
519 else if ( ParseOrdMonth( dt, ref parsePos, diff ) )
520 {
521 hasOrdMonth++;
522 }
523 else if ( ParseRelSpec( dt, ref parsePos, diff ) )
524 {
525 hasRel++;
526 }
527 else if ( ParseNumber( dt, ref parsePos, calendar, hasDate > 0 && hasTime > 0 && hasRel == 0 ) )
528 {
529 if ( hasDate == 0 || hasTime == 0 || hasRel > 0 )
530 {
531 hasTime++;
532 }
533 }
534 else if ( ParseTrek( dt, ref parsePos, calendar ) )
535 {
536 hasDate++;
537 hasTime++;
538 }
539 else
540 {
541 goto failed;
542 }
543 }
544  
545 if ( hasTime > 1 || hasZone > 1 || hasDate > 1 || hasDay > 1 || hasOrdMonth > 1 )
546 {
547 goto failed;
548 }
549  
550 // The following line handles years that are specified using
551 // only two digits. The line of code below implements a policy
552 // defined by the X/Open workgroup on the millinium rollover.
553 // Note: some of those dates may not actually be valid on some
554 // platforms. The POSIX standard startes that the dates 70-99
555 // shall refer to 1970-1999 and 00-38 shall refer to 2000-2038.
556 // This later definition should work on all platforms.
557  
558 int thisYear = calendar.year;
559 if ( thisYear < 100 )
560 {
561 if ( thisYear >= 69 )
562 {
563 calendar.year = thisYear + 1900;
564 }
565 else
566 {
567 calendar.year = thisYear + 2000;
568 }
569 }
570  
571 if ( hasRel > 0 )
572 {
573 if ( hasTime == 0 && hasDate == 0 && hasDay == 0 )
574 {
575 calendar.dateTime = baseDate;
576 }
577 // Certain JDK implementations are buggy WRT DST.
578 // Work around this issue by adding a day instead
579 // of a days worth of seconds.
580 int seconds_in_day = ( 60 * 60 * 24 );
581 int seconds = diff.Seconds;
582 bool negative_seconds = ( seconds < 0 );
583 int days = 0;
584 if ( negative_seconds )
585 seconds *= ( -1 );
586 while ( seconds >= seconds_in_day )
587 {
588 seconds -= seconds_in_day;
589 days++;
590 }
591 if ( negative_seconds )
592 {
593 seconds *= ( -1 );
594 days *= ( -1 );
595 }
596 if ( days != 0 )
597 {
598  
599 // calendar.add(SupportClass.CalendarManager.DATE, days);
600 }
601 if ( seconds != 0 )
602 {
603  
604 // calendar.add(SupportClass.CalendarManager.SECOND, seconds);
605 }
606  
607 // calendar.add(SupportClass.CalendarManager.MONTH, diff.Months);
608 }
609  
610 if ( hasDay > 0 && hasDate == 0 )
611 {
612 SetWeekday( calendar, diff );
613 }
614  
615 if ( hasOrdMonth > 0 )
616 {
617 SetOrdMonth( calendar, diff );
618 }
619 try
620 {
621 return calendar.dateTime;
622 }
623 catch ( Exception )
624 {
625 throw new FormatException();
626 }
627 failed:
628 throw new FormatException();
629 }
630 private bool ParseTime( ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar )
631 // calendar object to set
632 {
633 int pos = parsePos;
634  
635 if ( pos + 6 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ':' ) && dt[pos + 2].UNumber && dt[pos + 3].is_Renamed( ':' ) && dt[pos + 4].UNumber && dt[pos + 5].is_Renamed( '-' ) && dt[pos + 6].UNumber )
636 {
637 ClockToken zone = GetTimeZoneFromRawOffset( ( -dt[pos + 6].Int ) / 100 );
638 if ( zone != null )
639 {
640 calendar.hour = dt[pos].Int;
641 calendar.minute = dt[pos + 2].Int;
642 calendar.second = dt[pos + 4].Int;
643 // TODO
644 // calendar.setTimeZone(zone.Zone);
645 parsePos = pos + 7;
646 return true;
647 }
648 }
649 if ( pos + 4 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ':' ) && dt[pos + 2].UNumber && dt[pos + 3].is_Renamed( ':' ) && dt[pos + 4].UNumber )
650 {
651 parsePos = pos + 5;
652 ParseMeridianAndSetHour( dt, ref parsePos, calendar, dt[pos].Int );
653 calendar.minute = dt[pos + 2].Int;
654 calendar.second = dt[pos + 4].Int;
655 return true;
656 }
657 if ( pos + 4 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ':' ) && dt[pos + 2].UNumber && dt[pos + 3].is_Renamed( '-' ) && dt[pos + 4].UNumber )
658 {
659 ClockToken zone = GetTimeZoneFromRawOffset( ( -dt[pos + 4].Int ) / 100 );
660 if ( zone != null )
661 {
662 calendar.hour = dt[pos].Int;
663 calendar.minute = dt[pos + 2].Int;
664  
665 // calendar.setTimeZone(zone.Zone);
666 parsePos = pos + 5;
667 return true;
668 }
669 }
670 if ( pos + 2 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ':' ) && dt[pos + 2].UNumber )
671 {
672 parsePos = pos + 3;
673 ParseMeridianAndSetHour( dt, ref parsePos, calendar, dt[pos].Int );
674 calendar.minute = dt[pos + 2].Int;
675 return true;
676 }
677 if ( pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ClockToken.MERIDIAN ) )
678 {
679 parsePos = pos + 1;
680 ParseMeridianAndSetHour( dt, ref parsePos, calendar, dt[pos].Int );
681 return true;
682 }
683 return false;
684 }
685 private bool ParseZone( ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar )
686 // calendar object to set
687 {
688 int pos = parsePos;
689  
690 if ( pos + 1 < dt.Length && dt[pos].is_Renamed( ClockToken.ZONE ) && dt[pos + 1].is_Renamed( ClockToken.DST ) )
691 {
692  
693 // calendar.setTimeZone(dt[pos].Zone);
694 parsePos = pos + 2;
695 return true;
696 }
697 if ( pos < dt.Length && dt[pos].is_Renamed( ClockToken.ZONE ) )
698 {
699  
700 // calendar.setTimeZone(dt[pos].Zone);
701 parsePos = pos + 1;
702 return true;
703 }
704 if ( pos < dt.Length && dt[pos].is_Renamed( ClockToken.DAYZONE ) )
705 {
706  
707 // calendar.setTimeZone(dt[pos].Zone);
708 parsePos = pos + 1;
709 return true;
710 }
711 return false;
712 }
713 private bool ParseDay( ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff )
714 // time difference to evaluate
715 {
716 int pos = parsePos;
717  
718 if ( pos + 2 < dt.Length && dt[pos].is_Renamed( '+' ) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed( ClockToken.DAY ) )
719 {
720 diff.setWeekday( dt[pos + 2].Int, dt[pos + 1].Int );
721 parsePos = pos + 3;
722 return true;
723 }
724 if ( pos + 2 < dt.Length && dt[pos].is_Renamed( '-' ) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed( ClockToken.DAY ) )
725 {
726 diff.setWeekday( dt[pos + 2].Int, -dt[pos + 1].Int );
727 parsePos = pos + 3;
728 return true;
729 }
730 if ( pos + 1 < dt.Length && dt[pos].is_Renamed( ClockToken.NEXT ) && dt[pos + 1].is_Renamed( ClockToken.DAY ) )
731 {
732 diff.setWeekday( dt[pos + 1].Int, 2 );
733 parsePos = pos + 2;
734 return true;
735 }
736 if ( pos + 1 < dt.Length && dt[pos].is_Renamed( ClockToken.DAY ) && dt[pos + 1].is_Renamed( ',' ) )
737 {
738 diff.setWeekday( dt[pos].Int );
739 parsePos = pos + 2;
740 return true;
741 }
742 if ( pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ClockToken.DAY ) )
743 {
744 diff.setWeekday( dt[pos + 1].Int, dt[pos].Int );
745 parsePos = pos + 2;
746 return true;
747 }
748 if ( pos < dt.Length && dt[pos].is_Renamed( ClockToken.DAY ) )
749 {
750 diff.setWeekday( dt[pos].Int );
751 parsePos = pos + 1;
752 return true;
753 }
754 return false;
755 }
756 private bool ParseDate( ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar )
757 // calendar object to set
758 {
759 int pos = parsePos;
760  
761 if ( pos + 4 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( '/' ) && dt[pos + 2].UNumber && dt[pos + 3].is_Renamed( '/' ) && dt[pos + 4].UNumber )
762 {
763 calendar.day = dt[pos + 2].Int;
764 calendar.month = dt[pos].Int;
765 calendar.year = dt[pos + 4].Int;
766 parsePos = pos + 5;
767 return true;
768 }
769 if ( pos + 4 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( '-' ) && dt[pos + 2].is_Renamed( ClockToken.MONTH ) && dt[pos + 3].is_Renamed( '-' ) && dt[pos + 4].UNumber )
770 {
771 calendar.year = dt[pos + 4].Int;
772 calendar.month = dt[pos + 2].Int;
773 calendar.day = dt[pos].Int;
774 parsePos = pos + 5;
775 return true;
776 }
777 if ( pos + 4 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( '-' ) && dt[pos + 2].UNumber && dt[pos + 3].is_Renamed( '-' ) && dt[pos + 4].UNumber )
778 {
779 calendar.year = dt[pos].Int;
780 calendar.month = dt[pos + 2].Int;
781 calendar.day = dt[pos + 4].Int;
782 parsePos = pos + 5;
783 return true;
784 }
785 if ( pos + 3 < dt.Length && dt[pos].is_Renamed( ClockToken.MONTH ) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed( ',' ) && dt[pos + 3].UNumber )
786 {
787 calendar.day = dt[pos + 1].Int;
788 calendar.month = dt[pos].Int;
789 calendar.year = dt[pos + 3].Int;
790 parsePos = pos + 4;
791 return true;
792 }
793 if ( pos + 2 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( '/' ) && dt[pos + 2].UNumber )
794 {
795 calendar.day = dt[pos + 2].Int;
796 calendar.month = dt[pos].Int;
797 parsePos = pos + 3;
798 return true;
799 }
800 if ( pos + 2 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ClockToken.MONTH ) && dt[pos + 2].UNumber )
801 {
802 calendar.day = dt[pos].Int;
803 calendar.month = dt[pos + 1].Int;
804 calendar.year = dt[pos + 2].Int;
805 parsePos = pos + 3;
806 return true;
807 }
808 if ( pos + 1 < dt.Length && dt[pos].is_Renamed( ClockToken.MONTH ) && dt[pos + 1].UNumber )
809 {
810 calendar.day = dt[pos + 1].Int;
811 calendar.month = dt[pos].Int;
812 parsePos = pos + 2;
813 return true;
814 }
815 if ( pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed( ClockToken.MONTH ) )
816 {
817 calendar.day = dt[pos].Int;
818 calendar.month = dt[pos + 1].Int;
819 parsePos = pos + 2;
820 return true;
821 }
822 if ( pos < dt.Length && dt[pos].IsoBase )
823 {
824 calendar.day = dt[pos].Int % 100;
825 calendar.month = ( dt[pos].Int % 10000 ) / 100;
826 calendar.year = dt[pos].Int / 10000;
827 parsePos = pos + 1;
828 return true;
829 }
830 if ( pos < dt.Length && dt[pos].is_Renamed( ClockToken.EPOCH ) )
831 {
832 calendar.day = 1;
833 calendar.month = 0;
834 calendar.year = EPOCH_YEAR;
835 parsePos = pos + 1;
836 return true;
837 }
838 return false;
839 }
840 private bool ParseNumber( ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar, bool mayBeYear )
841 // number is considered to be year?
842 {
843 int pos = parsePos;
844  
845 if ( pos < dt.Length && dt[pos].UNumber )
846 {
847 parsePos = pos + 1;
848 if ( mayBeYear )
849 {
850 calendar.year = dt[pos].Int;
851 }
852 else
853 {
854 calendar.hour = dt[pos].Int / 100;
855 calendar.minute = dt[pos].Int % 100;
856 calendar.second = 0;
857 }
858 return true;
859 }
860 return false;
861 }
862 private bool ParseRelSpec( ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff )
863 // time difference to evaluate
864 {
865 if ( !ParseRelUnits( dt, ref parsePos, diff ) )
866 {
867 return false;
868 }
869  
870 int pos = parsePos;
871 if ( pos < dt.Length && dt[pos].is_Renamed( ClockToken.AGO ) )
872 {
873 diff.negate();
874 parsePos = pos + 1;
875 }
876 return true;
877 }
878 private bool ParseRelUnits( ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff )
879 // time difference to evaluate
880 {
881 int pos = parsePos;
882  
883 if ( pos + 2 < dt.Length && dt[pos].is_Renamed( '+' ) && dt[pos + 1].UNumber && dt[pos + 2].Unit )
884 {
885 diff.addUnit( dt[pos + 2], dt[pos + 1].Int );
886 parsePos = pos + 3;
887 return true;
888 }
889 if ( pos + 2 < dt.Length && dt[pos].is_Renamed( '-' ) && dt[pos + 1].UNumber && dt[pos + 2].Unit )
890 {
891 diff.addUnit( dt[pos + 2], -dt[pos + 1].Int );
892 parsePos = pos + 3;
893 return true;
894 }
895 if ( pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].Unit )
896 {
897 diff.addUnit( dt[pos + 1], dt[pos].Int );
898 parsePos = pos + 2;
899 return true;
900 }
901 else if ( pos + 2 < dt.Length && dt[pos].is_Renamed( ClockToken.NEXT ) && dt[pos + 1].UNumber && dt[pos + 2].Unit )
902 {
903 diff.addUnit( dt[pos + 2], dt[pos + 1].Int );
904 parsePos = pos + 3;
905 return true;
906 }
907 if ( pos + 1 < dt.Length && dt[pos].is_Renamed( ClockToken.NEXT ) && dt[pos + 1].Unit )
908 {
909 diff.addUnit( dt[pos + 1] );
910 parsePos = pos + 2;
911 return true;
912 }
913 if ( pos < dt.Length && dt[pos].Unit )
914 {
915 diff.addUnit( dt[pos] );
916 parsePos = pos + 1;
917 return true;
918 }
919 return false;
920 }
921 private bool ParseOrdMonth( ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff )
922 // time difference to evaluate
923 {
924 int pos = parsePos;
925  
926 if ( pos + 2 < dt.Length && dt[pos].is_Renamed( ClockToken.NEXT ) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed( ClockToken.MONTH ) )
927 {
928 diff.addOrdMonth( dt[pos + 2].Int, dt[pos + 1].Int );
929 parsePos = pos + 3;
930 return true;
931 }
932 if ( pos + 1 < dt.Length && dt[pos].is_Renamed( ClockToken.NEXT ) && dt[pos + 1].is_Renamed( ClockToken.MONTH ) )
933 {
934 diff.addOrdMonth( dt[pos + 1].Int, 1 );
935 parsePos = pos + 2;
936 return true;
937 }
938 return false;
939 }
940 private bool ParseIso( ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar )
941 // calendar object to set
942 {
943 int pos = parsePos;
944  
945 if ( pos + 6 < dt.Length && dt[pos].IsoBase && dt[pos + 1].is_Renamed( ClockToken.ZONE ) && dt[pos + 2].UNumber && dt[pos + 3].is_Renamed( ':' ) && dt[pos + 4].UNumber && dt[pos + 5].is_Renamed( ':' ) && dt[pos + 6].UNumber )
946 {
947 calendar.day = dt[pos].Int % 100;
948 calendar.month = ( dt[pos].Int % 10000 ) / 100;
949 calendar.year = dt[pos].Int / 10000;
950 calendar.hour = dt[pos + 2].Int;
951 calendar.minute = dt[pos + 4].Int;
952 calendar.second = dt[pos + 6].Int;
953 parsePos = pos + 7;
954 return true;
955 }
956 if ( pos + 2 < dt.Length && dt[pos].IsoBase && dt[pos + 1].is_Renamed( ClockToken.ZONE ) && dt[pos + 1].Zone.GetUtcOffset( calendar.dateTime ).Hours == ( -7 ) * MILLIS_PER_HOUR && dt[pos + 2].IsoBase )
957 {
958 calendar.day = dt[pos].Int % 100;
959 calendar.month = ( dt[pos].Int % 10000 ) / 100;
960 calendar.year = dt[pos].Int / 10000;
961 calendar.hour = dt[pos + 2].Int / 10000;
962 calendar.minute = ( dt[pos + 2].Int % 10000 ) / 100;
963 calendar.second = dt[pos + 2].Int % 100;
964 parsePos = pos + 3;
965 return true;
966 }
967 if ( pos + 1 < dt.Length && dt[pos].IsoBase && dt[pos + 1].IsoBase )
968 {
969 calendar.day = dt[pos].Int % 100;
970 calendar.month = ( dt[pos].Int % 10000 ) / 100;
971 calendar.year = dt[pos].Int / 10000;
972 calendar.hour = dt[pos + 1].Int / 10000;
973 calendar.minute = ( dt[pos + 1].Int % 10000 ) / 100;
974 calendar.second = dt[pos + 1].Int % 100;
975 parsePos = pos + 2;
976 return true;
977 }
978 return false;
979 }
980 private bool ParseTrek( ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar )
981 // calendar object to set
982 {
983 int pos = parsePos;
984  
985 if ( pos + 3 < dt.Length && dt[pos].is_Renamed( ClockToken.STARDATE ) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed( '.' ) && dt[pos + 3].UNumber )
986 {
987 GregorianCalendar gcal = new GregorianCalendar();
988 int trekYear = dt[pos + 1].Int / 1000 + 2323 - 377;
989 int trekDay = 1 + ( ( dt[pos + 1].Int % 1000 ) * ( gcal.IsLeapYear( trekYear ) ? 366 : 365 ) ) / 1000;
990 int trekSeconds = dt[pos + 3].Int * 144 * 60;
991 calendar.year = trekYear;
992 calendar.dateTime = gcal.AddDays( calendar.dateTime, trekDay );
993 calendar.second = trekSeconds;
994 parsePos = pos + 4;
995 return true;
996 }
997 return false;
998 }
999 private void ParseMeridianAndSetHour( ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar, int hour )
1000 // hour value (1-12 or 0-23) to set.
1001 {
1002 int pos = parsePos;
1003 int hourField;
1004  
1005 if ( pos < dt.Length && dt[pos].is_Renamed( ClockToken.MERIDIAN ) )
1006 {
1007 // SupportClass.CalendarManager.manager.Set(calendar, SupportClass.CalendarManager.AM_PM, dt[pos].Int);
1008 parsePos = pos + 1;
1009 hourField = SupportClass.CalendarManager.HOUR;
1010 }
1011 else
1012 {
1013 hourField = SupportClass.CalendarManager.HOUR_OF_DAY;
1014 }
1015  
1016 if ( hourField == SupportClass.CalendarManager.HOUR && hour == 12 )
1017 {
1018 hour = 0;
1019 }
1020 calendar.hour = hour;
1021 }
1022 private ClockToken[] GetTokens( string in_Renamed, bool debug )
1023 // Send the generated token list to stderr?
1024 {
1025 System.Int32 parsePos = 0;
1026 ClockToken dt;
1027 ArrayList tokenVector = new ArrayList( in_Renamed.Length );
1028  
1029 while ( ( dt = GetNextToken( in_Renamed, ref parsePos ) ) != null )
1030 {
1031 tokenVector.Add( dt );
1032 }
1033  
1034 ClockToken[] tokenArray = new ClockToken[tokenVector.Count];
1035 tokenVector.CopyTo( tokenArray );
1036  
1037 #if DEBUG
1038 for ( int ix = 0; ix < tokenArray.Length; ix++ )
1039 {
1040 if ( ix != 0 )
1041 {
1042 System.Console.Error.Write( "," );
1043 }
1044  
1045 System.Console.Error.Write( tokenArray[ix].ToString() );
1046 }
1047 System.Console.Error.WriteLine( "" );
1048 #endif
1049  
1050 return tokenArray;
1051 }
1052 private ClockToken GetNextToken( string in_Renamed, ref System.Int32 parsePos )
1053 // Current position in input
1054 {
1055 int pos = parsePos;
1056 int sign;
1057  
1058 while ( true )
1059 {
1060 while ( pos < in_Renamed.Length && ( System.Char.GetUnicodeCategory( in_Renamed[pos] ) == System.Globalization.UnicodeCategory.SpaceSeparator ) )
1061 {
1062 pos++;
1063 }
1064 if ( pos >= in_Renamed.Length )
1065 {
1066 break;
1067 }
1068  
1069 char c = in_Renamed[pos];
1070 if ( System.Char.IsDigit( c ) )
1071 {
1072 int number = 0;
1073 int count = 0;
1074 while ( pos < in_Renamed.Length && System.Char.IsDigit( c = in_Renamed[pos] ) )
1075 {
1076 number = 10 * number + c - '0';
1077 pos++;
1078 count++;
1079 }
1080 parsePos = pos;
1081 return new ClockToken( number, count >= 6 );
1082 }
1083 if ( System.Char.IsLetter( c ) )
1084 {
1085 int beginPos = pos;
1086 while ( ++pos < in_Renamed.Length )
1087 {
1088 c = in_Renamed[pos];
1089 if ( !System.Char.IsLetter( c ) && c != '.' )
1090 {
1091 break;
1092 }
1093 }
1094 parsePos = pos;
1095 return LookupWord( in_Renamed.Substring( beginPos, ( pos ) - ( beginPos ) ) );
1096 }
1097 parsePos = pos + 1;
1098 return new ClockToken( in_Renamed[pos] );
1099 }
1100 parsePos = pos + 1;
1101 return null;
1102 }
1103 private ClockToken LookupWord( string word )
1104 // word to lookup
1105 {
1106 int ix;
1107 string[] names;
1108 string[][] zones;
1109  
1110 if ( word.ToUpper().Equals( "am".ToUpper() ) || word.ToUpper().Equals( "a.m.".ToUpper() ) )
1111 {
1112 return new ClockToken( ClockToken.MERIDIAN, SupportClass.CalendarManager.AM );
1113 }
1114 if ( word.ToUpper().Equals( "pm".ToUpper() ) || word.ToUpper().Equals( "p.m.".ToUpper() ) )
1115 {
1116 return new ClockToken( ClockToken.MERIDIAN, SupportClass.CalendarManager.PM );
1117 }
1118  
1119 // See if we have an abbreviation for a day or month.
1120  
1121 bool abbrev;
1122 if ( word.Length == 3 )
1123 {
1124 abbrev = true;
1125 }
1126 else if ( word.Length == 4 && word[3] == '.' )
1127 {
1128 abbrev = true;
1129 word = word.Substring( 0, ( 3 ) - ( 0 ) );
1130 }
1131 else
1132 {
1133 abbrev = false;
1134 }
1135  
1136  
1137 DateTimeFormatInfo symbols = new CultureInfo( "en-US" ).DateTimeFormat;
1138 if ( abbrev )
1139 {
1140 names = symbols.AbbreviatedMonthNames;
1141 }
1142 else
1143 {
1144 names = (string[])symbols.MonthNames;
1145 }
1146 for ( ix = 0; ix < names.Length; ix++ )
1147 {
1148 if ( word.ToUpper().Equals( names[ix].ToUpper() ) )
1149 {
1150 return new ClockToken( ClockToken.MONTH, ix + 1 );
1151 }
1152 }
1153 if ( abbrev )
1154 {
1155 names = symbols.AbbreviatedDayNames;
1156 }
1157 else
1158 {
1159 names = symbols.DayNames;
1160 }
1161 for ( ix = 0; ix < names.Length; ix++ )
1162 {
1163 if ( word.ToUpper().Equals( names[ix].ToUpper() ) )
1164 {
1165 return new ClockToken( ClockToken.DAY, ix );
1166 }
1167 }
1168  
1169 // Drop out any periods and try the timezone table.
1170  
1171 StringBuilder withoutDotsBuf = new StringBuilder( word.Length );
1172 for ( ix = 0; ix < word.Length; ix++ )
1173 {
1174 if ( word[ix] != '.' )
1175 {
1176 withoutDotsBuf.Append( word[ix] );
1177 }
1178 }
1179  
1180 string withoutDots = new string( withoutDotsBuf.ToString().ToCharArray() );
1181  
1182 // zones = symbols.getZoneStrings();
1183  
1184 // for (ix = 0; ix < zones.Length; ix++)
1185 // {
1186 // if (withoutDots.ToUpper().Equals(zones[ix][2].ToUpper()) || withoutDots.ToUpper().Equals(zones[ix][4].ToUpper()))
1187 // {
1188 //
1189 // System.TimeZone zone = TimeZone.getTimeZone(zones[ix][0]);
1190 // return new ClockToken(ClockToken.ZONE, zone);
1191 // }
1192 // }
1193 if ( withoutDots.ToUpper().Equals( "dst".ToUpper() ) )
1194 {
1195 return new ClockToken( ClockToken.DST, null );
1196 }
1197  
1198 // Strip off any plural and try the units.
1199  
1200 string singular;
1201 if ( word.EndsWith( "s" ) )
1202 {
1203 singular = word.Substring( 0, ( word.Length - 1 ) - ( 0 ) );
1204 }
1205 else
1206 {
1207 singular = word;
1208 }
1209 if ( singular.ToUpper().Equals( "year".ToUpper() ) )
1210 {
1211 return new ClockToken( ClockToken.MONTH_UNIT, 12 );
1212 }
1213 else if ( singular.ToUpper().Equals( "month".ToUpper() ) )
1214 {
1215 return new ClockToken( ClockToken.MONTH_UNIT, 1 );
1216 }
1217 else if ( singular.ToUpper().Equals( "fortnight".ToUpper() ) )
1218 {
1219 return new ClockToken( ClockToken.MINUTE_UNIT, 14 * 24 * 60 );
1220 }
1221 else if ( singular.ToUpper().Equals( "week".ToUpper() ) )
1222 {
1223 return new ClockToken( ClockToken.MINUTE_UNIT, 7 * 24 * 60 );
1224 }
1225 else if ( singular.ToUpper().Equals( "day".ToUpper() ) )
1226 {
1227 return new ClockToken( ClockToken.MINUTE_UNIT, 24 * 60 );
1228 }
1229 else if ( singular.ToUpper().Equals( "hour".ToUpper() ) )
1230 {
1231 return new ClockToken( ClockToken.MINUTE_UNIT, 60 );
1232 }
1233 else if ( singular.ToUpper().Equals( "minute".ToUpper() ) )
1234 {
1235 return new ClockToken( ClockToken.MINUTE_UNIT, 1 );
1236 }
1237 else if ( singular.ToUpper().Equals( "min".ToUpper() ) )
1238 {
1239 return new ClockToken( ClockToken.MINUTE_UNIT, 1 );
1240 }
1241 else if ( singular.ToUpper().Equals( "second".ToUpper() ) )
1242 {
1243 return new ClockToken( ClockToken.SEC_UNIT, 1 );
1244 }
1245 else if ( singular.ToUpper().Equals( "sec".ToUpper() ) )
1246 {
1247 return new ClockToken( ClockToken.SEC_UNIT, 1 );
1248 }
1249  
1250 if ( singular.ToUpper().Equals( "tomorrow".ToUpper() ) )
1251 {
1252 return new ClockToken( ClockToken.MINUTE_UNIT, 1 * 24 * 60 );
1253 }
1254 else if ( singular.ToUpper().Equals( "yesterday".ToUpper() ) )
1255 {
1256 return new ClockToken( ClockToken.MINUTE_UNIT, ( -1 ) * 24 * 60 );
1257 }
1258 else if ( singular.ToUpper().Equals( "today".ToUpper() ) )
1259 {
1260 return new ClockToken( ClockToken.MINUTE_UNIT, 0 );
1261 }
1262 else if ( singular.ToUpper().Equals( "now".ToUpper() ) )
1263 {
1264 return new ClockToken( ClockToken.MINUTE_UNIT, 0 );
1265 }
1266 else if ( singular.ToUpper().Equals( "last".ToUpper() ) )
1267 {
1268 return new ClockToken( -1, false );
1269 }
1270 else if ( singular.ToUpper().Equals( "this".ToUpper() ) )
1271 {
1272 return new ClockToken( ClockToken.MINUTE_UNIT, 0 );
1273 }
1274 else if ( singular.ToUpper().Equals( "next".ToUpper() ) )
1275 {
1276 return new ClockToken( ClockToken.NEXT, 1 );
1277 }
1278 else if ( singular.ToUpper().Equals( "ago".ToUpper() ) )
1279 {
1280 return new ClockToken( ClockToken.AGO, 1 );
1281 }
1282 else if ( singular.ToUpper().Equals( "epoch".ToUpper() ) )
1283 {
1284 return new ClockToken( ClockToken.EPOCH, 0 );
1285 }
1286 else if ( singular.ToUpper().Equals( "stardate".ToUpper() ) )
1287 {
1288 return new ClockToken( ClockToken.STARDATE, 0 );
1289 }
1290  
1291 // Since a military timezone (T) is used in the clock test of 8.3,
1292 // we can't ignore these timezones any longer...
1293  
1294 if ( withoutDots.Length == 1 )
1295 {
1296 int rawOffset = 0;
1297 bool found = true;
1298 char milTz = System.Char.ToLower( withoutDots[0] );
1299  
1300 if ( milTz >= 'a' && milTz <= 'm' )
1301 {
1302 rawOffset = milTz - 'a' + 1;
1303 }
1304 else if ( milTz >= 'n' && milTz < 'z' )
1305 {
1306 rawOffset = 'n' - milTz - 1;
1307 }
1308 else if ( milTz != 'z' )
1309 {
1310 found = false;
1311 }
1312 if ( found )
1313 {
1314 ClockToken zone = GetTimeZoneFromRawOffset( rawOffset );
1315 if ( zone != null )
1316 {
1317 return zone;
1318 }
1319 }
1320 }
1321  
1322 return new ClockToken( word );
1323 }
1324 private ClockToken GetTimeZoneFromRawOffset( int rawOffset )
1325 {
1326  
1327 // string[] tzNames = TimeZone.getAvailableIDs(rawOffset * MILLIS_PER_HOUR);
1328  
1329 // if (tzNames.Length > 0)
1330 // {
1331 //
1332 // System.TimeZone zone = TimeZone.getTimeZone(tzNames[0]);
1333 // return new ClockToken(ClockToken.ZONE, zone);
1334 // }
1335 return null;
1336 }
1337 } // end ClockCmd
1338 class ClockToken
1339 {
1340 public bool UNumber
1341 {
1342 get
1343 {
1344 return kind == UNUMBER;
1345 }
1346  
1347 }
1348 public bool IsoBase
1349 {
1350 get
1351 {
1352 return kind == ISOBASE;
1353 }
1354  
1355 }
1356 public bool Unit
1357 {
1358 get
1359 {
1360 return kind == MINUTE_UNIT || kind == MONTH_UNIT || kind == SEC_UNIT;
1361 }
1362  
1363 }
1364 internal int Int
1365 {
1366 get
1367 {
1368 return number;
1369 }
1370  
1371 }
1372 internal System.TimeZone Zone
1373 {
1374 get
1375 {
1376 return zone;
1377 }
1378  
1379 }
1380 internal const int ISOBASE = 1;
1381 internal const int UNUMBER = 2;
1382 internal const int WORD = 3;
1383 internal const int CHAR = 4;
1384 internal const int MONTH = 5;
1385 internal const int DAY = 6;
1386 internal const int MONTH_UNIT = 7;
1387 internal const int MINUTE_UNIT = 8;
1388 internal const int SEC_UNIT = 9;
1389 internal const int AGO = 10;
1390 internal const int EPOCH = 11;
1391 internal const int ZONE = 12;
1392 internal const int DAYZONE = 13;
1393 internal const int DST = 14;
1394 internal const int MERIDIAN = 15;
1395 internal const int NEXT = 16;
1396 internal const int STARDATE = 17;
1397  
1398 internal ClockToken( int number, bool isIsoBase )
1399 {
1400 this.kind = isIsoBase ? ISOBASE : UNUMBER;
1401 this.number = number;
1402 }
1403 internal ClockToken( int kind, int number )
1404 {
1405 this.kind = kind;
1406 this.number = number;
1407 }
1408 internal ClockToken( int kind, System.TimeZone zone )
1409 {
1410 this.kind = kind;
1411 this.zone = zone;
1412 }
1413 internal ClockToken( string word )
1414 {
1415 this.kind = WORD;
1416 this.word = word;
1417 }
1418 internal ClockToken( char c )
1419 {
1420 this.kind = CHAR;
1421 this.c = c;
1422 }
1423 public bool is_Renamed( char c )
1424 {
1425 return this.kind == CHAR && this.c == c;
1426 }
1427 public bool is_Renamed( int kind )
1428 {
1429 return this.kind == kind;
1430 }
1431  
1432 public override string ToString()
1433 {
1434 if ( UNumber )
1435 {
1436 return "U" + System.Convert.ToString( Int );
1437 }
1438 else if ( IsoBase )
1439 {
1440 return "I" + System.Convert.ToString( Int );
1441 }
1442 else if ( kind == WORD )
1443 {
1444 return word;
1445 }
1446 else if ( kind == CHAR )
1447 {
1448 return c.ToString();
1449 }
1450 else if ( kind == ZONE || kind == DAYZONE )
1451 {
1452 return zone.StandardName;
1453 }
1454 else
1455 {
1456 return "(" + kind + "," + Int + ")";
1457 }
1458 }
1459  
1460 private int kind;
1461 private int number;
1462 private string word;
1463 private char c;
1464 private System.TimeZone zone;
1465 } // end ClockToken
1466 class ClockRelTimespan
1467 {
1468 internal int Seconds
1469 {
1470 get
1471 {
1472 return seconds;
1473 }
1474  
1475 }
1476 internal int Months
1477 {
1478 get
1479 {
1480 return months;
1481 }
1482  
1483 }
1484 internal int OrdMonth
1485 {
1486 get
1487 {
1488 return ordMonth;
1489 }
1490  
1491 }
1492 internal int DayOrdinal
1493 {
1494 get
1495 {
1496 return dayOrdinal;
1497 }
1498  
1499 }
1500 internal ClockRelTimespan()
1501 {
1502 seconds = 0;
1503 months = 0;
1504 ordMonth = 0;
1505 weekday = 0;
1506 dayOrdinal = 0;
1507 }
1508 internal void addSeconds( int s )
1509 {
1510 seconds += s;
1511 }
1512 internal void addMonths( int m )
1513 {
1514 months += m;
1515 }
1516 internal void addOrdMonth( int m, int c )
1517 {
1518 months = m;
1519 ordMonth += c;
1520 }
1521 internal void addUnit( ClockToken unit, int amount )
1522 {
1523 if ( unit.is_Renamed( ClockToken.SEC_UNIT ) )
1524 {
1525 addSeconds( unit.Int * amount );
1526 }
1527 else if ( unit.is_Renamed( ClockToken.MINUTE_UNIT ) )
1528 {
1529 addSeconds( unit.Int * 60 * amount );
1530 }
1531 else if ( unit.is_Renamed( ClockToken.MONTH_UNIT ) )
1532 {
1533 addMonths( unit.Int * amount );
1534 }
1535 }
1536 internal void addUnit( ClockToken unit )
1537 {
1538 addUnit( unit, 1 );
1539 }
1540 internal void setWeekday( int w, int ord )
1541 {
1542 weekday = w;
1543 dayOrdinal = ord;
1544 }
1545 internal void setWeekday( int w )
1546 {
1547 setWeekday( w, 1 );
1548 }
1549 internal void negate()
1550 {
1551 seconds = -seconds;
1552 months = -months;
1553 }
1554 internal int getWeekday()
1555 {
1556 return weekday;
1557 }
1558 private int seconds;
1559 private int months;
1560 private int ordMonth;
1561 private int weekday;
1562 private int dayOrdinal;
1563 }
1564 class TclDateTime
1565 {
1566 public int year, month, day, hour, minute, second, millisecond;
1567 public DateTime dateTime
1568 {
1569 get
1570 {
1571 return new DateTime( year, month, day, hour, minute, second, millisecond );
1572 }
1573 set
1574 {
1575 DateTime dt = value;
1576 year = dt.Year;
1577 month = dt.Month;
1578 day = dt.Day;
1579 hour = dt.Hour;
1580 minute = dt.Minute;
1581 second = dt.Second;
1582 millisecond = dt.Millisecond;
1583 }
1584 }
1585 }
1586 }