private void ParseMeridianAndSetHour(ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar, int hour) // hour value (1-12 or 0-23) to set. { int pos = parsePos; int hourField; if (pos < dt.Length && dt[pos].is_Renamed(ClockToken.MERIDIAN)) { // SupportClass.CalendarManager.manager.Set(calendar, SupportClass.CalendarManager.AM_PM, dt[pos].Int); parsePos = pos + 1; hourField = SupportClass.CalendarManager.HOUR; } else { hourField = SupportClass.CalendarManager.HOUR_OF_DAY; } if (hourField == SupportClass.CalendarManager.HOUR && hour == 12) { hour = 0; } calendar.hour = hour; }
private bool ParseIso(ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar) // calendar object to set { int pos = parsePos; 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) { calendar.day = dt[pos].Int % 100; calendar.month = (dt[pos].Int % 10000) / 100; calendar.year = dt[pos].Int / 10000; calendar.hour = dt[pos + 2].Int; calendar.minute = dt[pos + 4].Int; calendar.second = dt[pos + 6].Int; parsePos = pos + 7; return true; } 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) { calendar.day = dt[pos].Int % 100; calendar.month = (dt[pos].Int % 10000) / 100; calendar.year = dt[pos].Int / 10000; calendar.hour = dt[pos + 2].Int / 10000; calendar.minute = (dt[pos + 2].Int % 10000) / 100; calendar.second = dt[pos + 2].Int % 100; parsePos = pos + 3; return true; } if (pos + 1 < dt.Length && dt[pos].IsoBase && dt[pos + 1].IsoBase) { calendar.day = dt[pos].Int % 100; calendar.month = (dt[pos].Int % 10000) / 100; calendar.year = dt[pos].Int / 10000; calendar.hour = dt[pos + 1].Int / 10000; calendar.minute = (dt[pos + 1].Int % 10000) / 100; calendar.second = dt[pos + 1].Int % 100; parsePos = pos + 2; return true; } return false; }
private bool ParseTrek(ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar) // calendar object to set { int pos = parsePos; if (pos + 3 < dt.Length && dt[pos].is_Renamed(ClockToken.STARDATE) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed('.') && dt[pos + 3].UNumber) { GregorianCalendar gcal = new GregorianCalendar(); int trekYear = dt[pos + 1].Int / 1000 + 2323 - 377; int trekDay = 1 + ((dt[pos + 1].Int % 1000) * (gcal.IsLeapYear(trekYear) ? 366 : 365)) / 1000; int trekSeconds = dt[pos + 3].Int * 144 * 60; calendar.year = trekYear; calendar.dateTime = gcal.AddDays(calendar.dateTime, trekDay); calendar.second = trekSeconds; parsePos = pos + 4; return true; } return false; }
private bool ParseDate(ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar) // calendar object to set { int pos = parsePos; 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) { calendar.day = dt[pos + 2].Int; calendar.month = dt[pos].Int; calendar.year = dt[pos + 4].Int; parsePos = pos + 5; return true; } 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) { calendar.year = dt[pos + 4].Int; calendar.month = dt[pos + 2].Int; calendar.day = dt[pos].Int; parsePos = pos + 5; return true; } 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) { calendar.year = dt[pos].Int; calendar.month = dt[pos + 2].Int; calendar.day = dt[pos + 4].Int; parsePos = pos + 5; return true; } if (pos + 3 < dt.Length && dt[pos].is_Renamed(ClockToken.MONTH) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed(',') && dt[pos + 3].UNumber) { calendar.day = dt[pos + 1].Int; calendar.month = dt[pos].Int; calendar.year = dt[pos + 3].Int; parsePos = pos + 4; return true; } if (pos + 2 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed('/') && dt[pos + 2].UNumber) { calendar.day = dt[pos + 2].Int; calendar.month = dt[pos].Int; parsePos = pos + 3; return true; } if (pos + 2 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed(ClockToken.MONTH) && dt[pos + 2].UNumber) { calendar.day = dt[pos].Int; calendar.month = dt[pos + 1].Int; calendar.year = dt[pos + 2].Int; parsePos = pos + 3; return true; } if (pos + 1 < dt.Length && dt[pos].is_Renamed(ClockToken.MONTH) && dt[pos + 1].UNumber) { calendar.day = dt[pos + 1].Int; calendar.month = dt[pos].Int; parsePos = pos + 2; return true; } if (pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed(ClockToken.MONTH)) { calendar.day = dt[pos].Int; calendar.month = dt[pos + 1].Int; parsePos = pos + 2; return true; } if (pos < dt.Length && dt[pos].IsoBase) { calendar.day = dt[pos].Int % 100; calendar.month = (dt[pos].Int % 10000) / 100; calendar.year = dt[pos].Int / 10000; parsePos = pos + 1; return true; } if (pos < dt.Length && dt[pos].is_Renamed(ClockToken.EPOCH)) { calendar.day = 1; calendar.month = 0; calendar.year = EPOCH_YEAR; parsePos = pos + 1; return true; } return false; }
private bool ParseNumber(ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar, bool mayBeYear) // number is considered to be year? { int pos = parsePos; if (pos < dt.Length && dt[pos].UNumber) { parsePos = pos + 1; if (mayBeYear) { calendar.year = dt[pos].Int; } else { calendar.hour = dt[pos].Int / 100; calendar.minute = dt[pos].Int % 100; calendar.second = 0; } return true; } return false; }
private bool ParseZone(ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar) // calendar object to set { int pos = parsePos; if (pos + 1 < dt.Length && dt[pos].is_Renamed(ClockToken.ZONE) && dt[pos + 1].is_Renamed(ClockToken.DST)) { // calendar.setTimeZone(dt[pos].Zone); parsePos = pos + 2; return true; } if (pos < dt.Length && dt[pos].is_Renamed(ClockToken.ZONE)) { // calendar.setTimeZone(dt[pos].Zone); parsePos = pos + 1; return true; } if (pos < dt.Length && dt[pos].is_Renamed(ClockToken.DAYZONE)) { // calendar.setTimeZone(dt[pos].Zone); parsePos = pos + 1; return true; } return false; }
private bool ParseTime(ClockToken[] dt, ref System.Int32 parsePos, TclDateTime calendar) // calendar object to set { int pos = parsePos; 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) { ClockToken zone = GetTimeZoneFromRawOffset((-dt[pos + 6].Int) / 100); if (zone != null) { calendar.hour = dt[pos].Int; calendar.minute = dt[pos + 2].Int; calendar.second = dt[pos + 4].Int; // TODO // calendar.setTimeZone(zone.Zone); parsePos = pos + 7; return true; } } 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) { parsePos = pos + 5; ParseMeridianAndSetHour(dt, ref parsePos, calendar, dt[pos].Int); calendar.minute = dt[pos + 2].Int; calendar.second = dt[pos + 4].Int; return true; } 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) { ClockToken zone = GetTimeZoneFromRawOffset((-dt[pos + 4].Int) / 100); if (zone != null) { calendar.hour = dt[pos].Int; calendar.minute = dt[pos + 2].Int; // calendar.setTimeZone(zone.Zone); parsePos = pos + 5; return true; } } if (pos + 2 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed(':') && dt[pos + 2].UNumber) { parsePos = pos + 3; ParseMeridianAndSetHour(dt, ref parsePos, calendar, dt[pos].Int); calendar.minute = dt[pos + 2].Int; return true; } if (pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed(ClockToken.MERIDIAN)) { parsePos = pos + 1; ParseMeridianAndSetHour(dt, ref parsePos, calendar, dt[pos].Int); return true; } return false; }
private System.DateTime GetDate(string dateString, System.DateTime baseDate, bool useGMT) { if (useGMT) { baseDate = baseDate.ToUniversalTime(); } TclDateTime calendar = new TclDateTime(); calendar.dateTime = baseDate; calendar.hour = 0; calendar.minute = 0; calendar.second = 0; calendar.millisecond = 0; ClockToken[] dt = GetTokens(dateString, false); System.Int32 parsePos = 0; ClockRelTimespan diff = new ClockRelTimespan(); int hasTime = 0; int hasZone = 0; int hasDate = 0; int hasDay = 0; int hasOrdMonth = 0; int hasRel = 0; while (parsePos < dt.Length) { if (ParseTime(dt, ref parsePos, calendar)) { hasTime++; } else if (ParseZone(dt, ref parsePos, calendar)) { hasZone++; } else if (ParseIso(dt, ref parsePos, calendar)) { hasDate++; } else if (ParseDate(dt, ref parsePos, calendar)) { hasDate++; } else if (ParseDay(dt, ref parsePos, diff)) { hasDay++; } else if (ParseOrdMonth(dt, ref parsePos, diff)) { hasOrdMonth++; } else if (ParseRelSpec(dt, ref parsePos, diff)) { hasRel++; } else if (ParseNumber(dt, ref parsePos, calendar, hasDate > 0 && hasTime > 0 && hasRel == 0)) { if (hasDate == 0 || hasTime == 0 || hasRel > 0) { hasTime++; } } else if (ParseTrek(dt, ref parsePos, calendar)) { hasDate++; hasTime++; } else { goto failed; } } if (hasTime > 1 || hasZone > 1 || hasDate > 1 || hasDay > 1 || hasOrdMonth > 1) { goto failed; } // The following line handles years that are specified using // only two digits. The line of code below implements a policy // defined by the X/Open workgroup on the millinium rollover. // Note: some of those dates may not actually be valid on some // platforms. The POSIX standard startes that the dates 70-99 // shall refer to 1970-1999 and 00-38 shall refer to 2000-2038. // This later definition should work on all platforms. int thisYear = calendar.year; if (thisYear < 100) { if (thisYear >= 69) { calendar.year = thisYear + 1900; } else { calendar.year = thisYear + 2000; } } if (hasRel > 0) { if (hasTime == 0 && hasDate == 0 && hasDay == 0) { calendar.dateTime = baseDate; } // Certain JDK implementations are buggy WRT DST. // Work around this issue by adding a day instead // of a days worth of seconds. int seconds_in_day = (60 * 60 * 24); int seconds = diff.Seconds; bool negative_seconds = (seconds < 0); int days = 0; if (negative_seconds) seconds *= (-1); while (seconds >= seconds_in_day) { seconds -= seconds_in_day; days++; } if (negative_seconds) { seconds *= (-1); days *= (-1); } if (days != 0) { // calendar.add(SupportClass.CalendarManager.DATE, days); } if (seconds != 0) { // calendar.add(SupportClass.CalendarManager.SECOND, seconds); } // calendar.add(SupportClass.CalendarManager.MONTH, diff.Months); } if (hasDay > 0 && hasDate == 0) { SetWeekday(calendar, diff); } if (hasOrdMonth > 0) { SetOrdMonth(calendar, diff); } try { return calendar.dateTime; } catch (Exception) { throw new FormatException(); } failed: throw new FormatException(); }
private void SetOrdMonth(TclDateTime calendar, ClockRelTimespan diff) // time difference to evaluate { int month = diff.Months; int ordMonth = diff.OrdMonth; // calendar.add(SupportClass.CalendarManager.MONTH, 1); /* we want to get the next month... */ // while (SupportClass.CalendarManager.manager.Get(calendar, SupportClass.CalendarManager.MONTH) != month) // { // calendar.add(SupportClass.CalendarManager.MONTH, 1); // } // if (ordMonth > 1) // { // calendar.add(SupportClass.CalendarManager.YEAR, ordMonth - 1); // } calendar.day = 1; calendar.hour = 0; calendar.minute = 0; calendar.second = 0; }
private void SetWeekday(TclDateTime calendar, ClockRelTimespan diff) // time difference to evaluate { int weekday = diff.getWeekday(); int dayOrdinal = diff.DayOrdinal; // ATK // while (SupportClass.CalendarManager.manager.Get(calendar, SupportClass.CalendarManager.DAY_OF_WEEK) != weekday) // { // // calendar.add(SupportClass.CalendarManager.DATE, 1); // } // if (dayOrdinal > 1) // { // // calendar.add(SupportClass.CalendarManager.DATE, 7 * (dayOrdinal - 1)); // } }