protected bool ParseDateTime(string s, DateTimePart part) { ParseContext context = new ParseContext(s); bool bDatePart = ( part & DateTimePart.Date ) != 0; bool bTimePart = ( part & DateTimePart.Time ) != 0; int year = 0, month = 0, day = 0; int hour = 0, minute = 0; double second = 0; eTZ = ETZ.Missing; offsetTZ = 0; if ( bDatePart ) { // parse date bool bNegative = context.CheckAndAdvance( '-' ); if ( (part & DateTimePart.Year ) != 0 ) { int digits = 0; int temp = 0; while ( context.ReadDigitAndAdvance( ref temp, 1, 9 ) ) { year = year * 10 + temp; digits += 1; temp = 0; if (digits >= 8) // overflow return false; } if ( digits < 4 ) // invalid. return false; if ( digits > 4 && year < 10000 ) return false; if (bNegative) year = -year; } if ( (part & ( DateTimePart.Month | DateTimePart.Day )) != 0 ) { if ( !context.CheckAndAdvance( '-' ) ) return false; if ( ( part & DateTimePart.Month ) != 0 ) { if ( !context.ReadDigitAndAdvance( ref month, 10, 1 ) ) return false; if ( !context.ReadDigitAndAdvance( ref month, 1, month < 10 ? 9 : 2 ) ) return false; if ( month == 0 ) return false; } if ( ( part & DateTimePart.Day ) != 0 ) { if ( !context.CheckAndAdvance( '-') ) return false; int maxFirstDigit = month != 2 ? 3 : 2; // complicate things by making them complicated. if ( !context.ReadDigitAndAdvance( ref day, 10, maxFirstDigit ) ) return false; if ( !context.ReadDigitAndAdvance( ref day, 1, 9 ) ) return false; if ( day == 0 || day > 31 ) return false; if ( ( part & DateTimePart.Month ) != 0 ) { bool b1 = month <= 7; bool b2 = ( month & 1 ) == 0; // month 1, 3, 5, 7, 8, 10, 12 if ( b1 == b2 && day > 30 ) return false; // february. if ( month == 2 && day > 29 ) return false; // leap years. if ( month == 2 && ( part & DateTimePart.Year ) != 0 && ( year % 4 != 0 || year % 100 == 0 ) && year % 400 != 0 && day > 28 ) return false; } } } if ( bTimePart ) { // a 'T' must follow if ( !context.CheckAndAdvance( 'T') ) return false; } } if ( bTimePart ) { // check format here // hour from 0 to 2 if ( !context.ReadDigitAndAdvance( ref hour, 10, 2 ) ) return false; if ( !context.ReadDigitAndAdvance( ref hour, 1, hour < 20 ? 9 : 4 ) ) return false; if ( !context.CheckAndAdvance( ':' ) ) return false; int maxFirstDigit = hour == 24 ? 0 : 5; int maxSecondDigit = hour == 24 ? 0 : 9; if ( !context.ReadDigitAndAdvance( ref minute, 10, maxFirstDigit ) ) return false; if ( !context.ReadDigitAndAdvance( ref minute, 1, maxSecondDigit ) ) return false; if ( !context.CheckAndAdvance( ':' ) ) return false; int secondInt = 0; if ( !context.ReadDigitAndAdvance( ref secondInt, 10, maxFirstDigit ) ) return false; if ( !context.ReadDigitAndAdvance( ref secondInt, 1, maxSecondDigit ) ) return false; second = secondInt; if ( context.CheckAndAdvance( '.' ) ) { // fraction. do whatever seems fit. int val = 0; int digits = 0; while ( context.ReadDigitAndAdvance( ref val, 1, 9) ) { val *= 10; digits += 1; if ( digits >= 8 ) // precision loss - ignore break; } if ( digits == 0 ) return false; second += val * Math.Pow( 10.0, -digits - 1 ); // skip any further digits. while ( context.ReadDigitAndAdvance( ref val, 0, 9) ) ; } } // timezone if ( context.CheckAndAdvance('Z') ) { // timezone specified, it is UTC. eTZ = ETZ.UTC; offsetTZ = 0; } else if ( context.Check('+') || context.Check('-' ) ) { // timezone offset, in hour:minute format bool bNegative = context.Check('-'); context.Advance(); // do not check the hour part, for those who are obscure. int temp = 0; if ( !context.ReadDigitAndAdvance( ref temp, 600, 9 ) ) return false; if ( !context.ReadDigitAndAdvance( ref temp, 60, 9 ) ) return false; if ( !context.CheckAndAdvance( ':' ) ) return false; if ( !context.ReadDigitAndAdvance( ref temp, 10, 5 ) ) return false; if ( !context.ReadDigitAndAdvance( ref temp, 1, 9 ) ) return false; eTZ = ETZ.Offset; offsetTZ = bNegative ? -temp : temp; } if ( context.IsValid() ) return false; // C# specific if (year <= 0) year = 1; if (month == 0) month = 1; bool badjust = false; if (hour == 24) { hour = 0; badjust = true; } if (day == 0) day = 1; try { myValue = new System.DateTime(year, month, day, hour, minute, (int)second, (int)(second * 1000) % 1000); if (badjust) myValue.AddDays(1); } catch { return false; } return true; }
public SchemaCalendarBase(int year, int month, int day, int hour, int minute, int second, double newpartsecond, bool newhasTZ, int newoffsetTZ) { myValue = new System.DateTime(year, month, day, hour, minute, second, (int)(newpartsecond*1000) ); eTZ = newhasTZ ? ( newoffsetTZ == 0 ? ETZ.UTC : ETZ.Offset ) : ETZ.Missing; offsetTZ = newoffsetTZ; isEmpty = false; isNull = false; }
public void Reset() { //myValue = System.DateTime.Now; myValue = new System.DateTime(); eTZ = ETZ.Missing; offsetTZ = 0; }
public SchemaCalendarBase(System.DateTime newvalue) { myValue = newvalue; eTZ = ETZ.Missing; offsetTZ = 0; isEmpty = false; isNull = false; }
public SchemaCalendarBase(SchemaCalendarBase obj) { myValue = obj.myValue; eTZ = obj.eTZ; offsetTZ = obj.offsetTZ; isEmpty = obj.isEmpty; isNull = obj.isNull; }
protected int offsetTZ; // offset in minutes #endregion Fields #region Constructors public SchemaCalendarBase() { Reset(); isEmpty = true; isNull = false; eTZ = ETZ.Missing; }
//throws StringParseException protected void ParseTime(string newvalue) { if ( newvalue == null || newvalue.Length == 0 ) return; if (newvalue.Length < 8) throw new StringParseException("time-part of string is too short"); try { int nStart = 0; int hour = Convert.ToInt32(newvalue.Substring(nStart, 2)); if( !newvalue.Substring(nStart+2, 1).Equals(":")) throw new StringParseException("invalid date format"); int minute = Convert.ToInt32(newvalue.Substring(nStart+3, 2)); if( !newvalue.Substring(nStart+5, 1).Equals(":")) throw new StringParseException("invalid date format"); int second = Convert.ToInt32(newvalue.Substring(nStart+6, 2)); int nTZStartPosition = nStart+8; double partsecond = 0.0; if (newvalue.Length>(nStart+8) ) { nStart = nTZStartPosition; int nEnd = newvalue.Length; int nMSecEnd = newvalue.IndexOf("Z", nStart); if( nMSecEnd > -1 && nMSecEnd < nEnd ) nEnd = nMSecEnd; nMSecEnd = newvalue.IndexOf("+", nStart); if( nMSecEnd > -1 && nMSecEnd < nEnd ) nEnd = nMSecEnd; nMSecEnd = newvalue.IndexOf("-", nStart); if( nMSecEnd > -1 && nMSecEnd < nEnd ) nEnd = nMSecEnd; nTZStartPosition = nEnd; partsecond = Convert.ToDouble( "0" + newvalue.Substring(nStart, nEnd-nStart), CultureInfo.InvariantCulture); } eTZ = ETZ.Missing; offsetTZ = 0; if (newvalue.Length>nTZStartPosition && newvalue.Substring(nTZStartPosition, 1).Equals("Z")) eTZ = ETZ.UTC; else if (newvalue.Length == nTZStartPosition + 6) { eTZ = ETZ.Offset; offsetTZ = Convert.ToInt32(newvalue.Substring(nTZStartPosition+1, 2)) * 60 + Convert.ToInt32(newvalue.Substring(nTZStartPosition+4, 2)); if( newvalue.Substring(nTZStartPosition, 1).Equals("-")) offsetTZ = -offsetTZ; } myValue = new System.DateTime( myValue.Year, myValue.Month, myValue.Day, hour, minute, second, (int)(partsecond * 1000.0)); } catch (FormatException) { throw new StringParseException("invalid number format"); } isEmpty = false; }
public void Reset() { myValue = DateTime.Now; eTZ = ETZ.Missing; offsetTZ = 0; }