Subscribe to The Madman Scribblings        RSS Feed
-----

Validation Of Date.(No Math)

Icon 4 Comments
Validation Of Dates.(No Math)

I've developed a method of validating the digit characters in a date. Using only simple parsing techniques.
  • No maths is involved
  • No creation of a DateTime object.
  • No converting of the character into integers.

This technique assumes that character are a least digits.



Extension Methods
public static class exts
{ 
  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static bool IsDigit (this char ch)
  {
    return ('0' <= ch) && ( ch <= '9');
  }
  
  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static bool IsEven (this char ch )
  {
    //Debug.Assert( ch.IsDigit() );
    return ch.IsAnyOf('0','2','4','6','8');
  } 

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static bool IsAnyOf(this char ch, char cx0, char cx1)
  {
    return (ch == cx0) || (ch == cx1);
  }
  
  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static bool IsAnyOf(this char ch , char cx0, char cx1, char cx2)
  {
    return (ch == cx0) || (ch == cx1) || (ch==cx2);
  }
  
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static bool IsAnyOf(this char ch , char cx0, char cx1, char cx2, char cx3, char cx4)
  {
    return (ch == cx0) || (ch == cx1) || (ch == cx2) || (ch == cx3) || (ch == cx4);
  }

}



Is Leap Year?
This aspect is typically the hard part, as it effects how the day aspect of the date is validated. Is Feb 28 or 29 days long?
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
 static bool IsMod4 (char t, char u)
  {
    return t.IsEven() ? u.IsAnyOf('0','4','8') : u.IsAnyOf('2','6');
  }
  
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
 static bool IsCentury (char t, char u)
  {
    return ( t=='0') && (u=='0');
  }
  
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
   bool IsLeapYear (string yy)
  {
 //   Debug.Assert( yy != null );
 //   Debug.Assert( yy.Length == 4);
    return IsLeapYear( yy[0], yy[1], yy[2], yy[3]);
  }

     [MethodImpl(MethodImplOptions.AggressiveInlining)]
  bool IsLeapYear (char th, char hu, char te, char un)
  {
  return un.IsEven() && IsMod4( te , un ) && ( !IsCentury( te , un ) || IsMod4( th , hu ) );
  }


Note: My timings says that this more 50% than doing DateTime.IsLeapYear

Is Date Valid?
Now it is relatively simple to validate date.

  bool DDMMYYYY(char d0, char d1, char m0, char m1, char y0, char y1, char y2, char y3)
    {
    return !((d0=='0'&&d1=='0')||((m0=='0')&&((m1=='2'&&d0=='2'&&d1>(IsLeapYear(y0,y1,y2,y3)?'9':'8'))
        ||(m1.IsAnyOf('1','3','5','7','8')&&(d0>'3'||(d0=='3' && d1>'1')))
         ||(m1.IsAnyOf('4','6','9')&&(d0>'3')||(d0=='3'&&d1>='1')))
         ||(m0=='1'&&(d0>'3'||(d0=='3'&& d1>(m1=='1'?'0':'1'))))));
}

4 Comments On This Entry

Page 1 of 1

Skydiver Icon

23 August 2015 - 09:37 PM
This incorrectly computes leap years prior to 1582 when the Julian calendar rather than the Gregorian calendar was in use.
0

AdamSpeight2008 Icon

25 August 2015 - 01:06 PM
Neither does DataTime.IsLeapYear. This one is specific to the Gregorian calendar.
0

Skydiver Icon

26 August 2015 - 05:52 AM
True that.
0

Skydiver Icon

26 August 2015 - 05:54 AM
I just remember getting dinged on a programming assignment involving calendars once where I didn't account for Julian vs. Gregorian calendar when dealing with dates.
1
Page 1 of 1

Search My Blog

Recent Entries

Recent Comments