Assessing Dates of Birth using Visual Basic

Introduction

This article describes an approach to assessing the difference between a specified beginning and end date.  The example was written in the context of comparing a birth date to a specific end date but the same approach could be used to calculate the number of years, months, and days between a specified start and end date.

 

 

Test Application Main Form-in-windows8.jpg

Figure 1:  Test Application Main Form

 

Getting Started:

In order to get started, unzip the included project and open the solution in the Visual Studio 2008 environment.   In the solution explorer, you should note these files (Figure 2):

 

 

Solution Explorer-in-windows8.jpg

Figure 2:  Solution Explorer

 

The solution contains a single project called DateAgeCalculation.  This project contains a class entitled AgeEvaluator that is used to perform the date related calculations and a single form class used to test the AgeEvalator class.  The form contains to date picker controls which are used to set the date of birth and the end date (used to simulate today as any day of the year).

 

Code:  AgeEvaluator.vb

The AgeEvaluator class contains a couple of methods used to calculate either the total number of years the subject has been alive, or used to calculate the number of years, months, and days the subject has been alive.  Further, the class determines whether or not the subject’s birthday will occur within 30, 60, or 90 days of the specified end date.

The class begins with the default imports: 

 

Imports System

Imports System.Text

 

 

The next section contains the class declaration.  There is no specified default constructor for the class as both contained methods are static.

 

 

''' <summary>

''' Class used to determine a person's age

''' based upon a date of birth and a specific

''' end date

''' </summary>

''' <remarks></remarks>

Public Class AgeEvaluator

 

 

The first method contained in this class is used to calculate the person’s age in years only.  This method accepts the person’s date of birth as an argument and all calculations are based upon comparing the date of birth to the current date.  The return type is specified as a nullable integer so that, if the method is passed a birthday that is greater than the current date, the method may return a null.  The code in this method is annotated and you can follow what the method does by reading that annotation.

 

    ''' <summary>

    ''' Return a person's age in years based

    ''' upon that person's date of birth

    ''' </summary>

    ''' <param name="birthDay"></param>

    ''' <returns></returns>

    ''' <remarks></remarks>

    Public Shared Function GetAgeInYears(ByVal birthDay As DateTime) As

    Nullable(Of Integer)

 

        ' return null if the date of birth

        ' greater than the current date

        If (birthDay > DateTime.Now) Then

            Return Nothing

        End If

 

        ' get the basic number of years

        Dim years As Integer = DateTime.Now.Year - birthDay.Year

 

        ' adjust the years against this year's

        ' birthday

        If (DateTime.Now.Month < birthDay.Month Or _

           (DateTime.Now.Month = birthDay.Month And _

            DateTime.Now.Day < birthDay.Day)) Then

 

            years -= 1

 

        End If

 

        ' don't return a negative number

        ' for years alive

        If (years >= 0) Then

            Return years

        Else

            Return 0

        End If

 

    End Function

 

 

That next method contained in the class is used to calculate the time a person has been alive in years, months, and days.  The method returns an AgeBag class instance; this class will be described in the next section of this document but in general, it is a property bag used to hold the number of years, months, and days a person has been alive coupled with three Boolean values used to determine whether or not a person’s next birthday will fall within 30, 60, or 90 days of the end date specified in the methods arguments.  This method is annotated and you may read what each section of the code does by following the annotation.

 

    ''' <summary>

    ''' Calculate the time a person has been alive in

    ''' days, months, and years, and return values

    ''' in an instance of the age bag class

    ''' </summary>

    ''' <param name="birthDate"></param>

    ''' <param name="endDate"></param>

    ''' <returns></returns>

    ''' <remarks></remarks>

    Public Shared Function GetTimeAlive(ByVal birthDate As DateTime, _

                                        ByVal endDate As DateTime) As AgeBag

 

        If (endDate < birthDate) Then

            System.Windows.Forms.MessageBox.Show("Invalid end date", "Error")

            Return New AgeBag()

        End If

 

        Dim years As Integer = endDate.Year - birthDate.Year

        Dim months As Integer = endDate.Month - birthDate.Month

        Dim days As Integer = endDate.Day - birthDate.Day

 

        ' use the original days value

        ' to adjust the month where the

        ' day has passed

        If (days < 0) Then

            months -= 1

        End If

 

 

        ' adjust month and years where

        ' month has passed

        While (months < 0)

            months += 12

            years -= 1

        End While

 

 

        ' adjust days for the current year

        Dim timeSpan As TimeSpan = endDate â€"

        birthDate.AddYears(years).AddMonths(months)

 

        ' dispose of fractional portion of total days

        days = Convert.ToInt32(Math.Round(timeSpan.TotalDays))

 

        ' create and populate an instance of

        ' the age bag class to keep the values

        ' calculated for the birth date

        Dim ab = New AgeBag()

        ab.AgeDays = days

        ab.AgeMonths = months

 

        ' get rid of negative number of years

        If (years >= 1) Then

            ab.AgeYears = years

        Else

            ab.AgeYears = 0

        End If

 

        ' get the timespan between the date of birth and end date

        Dim dtThisBirthday = New DateTime(DateTime.Now.Year, _

                     birthDate.Month, birthDate.Day)

 

        Dim ts As TimeSpan = dtThisBirthday - endDate

 

        ' round off the fractional days portion and set

        ' the agebag property used to hold the days remaining

        ' before the next birthday

        ab.DaysToBirthday = Convert.ToInt32(Math.Round(ts.TotalDays))

 

        ' if the days until the next birthday in

        ' a negative number (already passed), recalculate the days

        ' until the next birthday using the future birthday

        If (ab.DaysToBirthday < 0) Then

 

            Dim nextBirthday = New DateTime(endDate.Year + 1,

            birthDate.Month, birthDate.Day)

            Dim tsNext As TimeSpan = nextBirthday - endDate

            ab.DaysToBirthday = Convert.ToInt32(Math.Round(tsNext.TotalDays))

 

 

            ' determine whether or not the subject's next

            ' birthday is between 61 and 90 days away

            If (ab.DaysToBirthday <= 90 And ab.DaysToBirthday > 60) Then

                ab.BirthdayIn90Days = True

            End If

 

        Else

            ab.BirthdayIn90Days = False

 

            ' determine whether or not the subject's next

            ' birthday is between 60 and 31 days

            If (ab.DaysToBirthday <= 60 And ab.DaysToBirthday > 30) Then

                ab.BirthdayIn60Days = True

            Else

                ab.BirthdayIn60Days = False

 

                ' determine whether or not the subject's next

                ' birthday will fall within the next 30 days

                If (ab.DaysToBirthday <= 30 And ab.DaysToBirthday >= 0) Then

                    ab.BirthdayIn30Days = True

                Else

                    ab.BirthdayIn30Days = False

                End If

            End If

        End If

 

        ' return the populated airbag class instance

        ' to the caller

        Return ab

 

    End Function

 

 

End Class

 

       

The bit of code in the project is a class entitled “AgeBag”.  This class is nothing more than a property bag used to contain the years, months, and days a person has been alive coupled with the Booleans indicating whether or not a person’s next birthday will occur within the following 30, 60, or 90 days.

 

''' <summary>

''' A class containing age related properties

''' describing the time alive, the days

''' remaining before the next birthday, and

''' indications as to whether or not the

''' next birthday will fall within 90,

''' 60, or 30 days

''' </summary>

''' <remarks></remarks>

Public Class AgeBag

 

    Public Sub New()

        ' do nothing

    End Sub

 

 

    ' member variables

    Private mYears As Integer

    Private mMonths As Integer

    Private mDays As Integer

    Private mDaysToBirthday As Integer

 

    Private mBirthdayIn90Days As Boolean

    Private mBirthdayIn60Days As Boolean

    Private mBirthdayIn30Days As Boolean

 

 

    ' public properties

    Public Property AgeYears() As Integer

        Get

            Return mYears

        End Get

        Set(ByVal value As Integer)

            mYears = value

        End Set

    End Property

 

 

    Public Property AgeMonths() As Integer

        Get

            Return mMonths

        End Get

        Set(ByVal value As Integer)

            mMonths = value

        End Set

    End Property

 

 

    Public Property AgeDays() As Integer

        Get

            Return mDays

        End Get

        Set(ByVal value As Integer)

            mDays = value

        End Set

    End Property

 

 

    Public Property BirthdayIn90Days() As Boolean

        Get

            Return mBirthdayIn90Days

        End Get

        Set(ByVal value As Boolean)

            mBirthdayIn90Days = value

        End Set

    End Property

 

 

    Public Property BirthdayIn60Days() As Boolean

        Get

            Return mBirthdayIn60Days

        End Get

        Set(ByVal value As Boolean)

            mBirthdayIn60Days = value

        End Set

    End Property

 

 

    Public Property BirthdayIn30Days() As Boolean

        Get

            Return mBirthdayIn30Days

        End Get

        Set(ByVal value As Boolean)

            mBirthdayIn30Days = value

        End Set

    End Property

 

 

    Public Property DaysToBirthday() As Integer

        Get

            Return mDaysToBirthday

        End Get

        Set(ByVal value As Integer)

            mDaysToBirthday = value

        End Set

    End Property

 

End Class

 

Code:  frmTestEmailer.vb

This form class is the only class contained in the test application; it provides a simple interface for testing the AgeEvaluator class using a specified birth date coupled with an arbitrary end date (simulating the current date as any date).

The class begins with the default imports. 

Imports System.Text

Imports System.Environment

 

 

The next section contains the class declaration and default constructor. 

 

 

''' <summary>

''' Application used to test the

''' AgeEvaluator Class

''' </summary>

''' <remarks></remarks>

Public Class Form1

 

 

    ''' <summary>

    ''' Default Constructor

    ''' </summary>

    ''' <remarks></remarks>

    Public Sub New()

 

        ' This call is required by the Windows Form Designer.

        InitializeComponent()

 

        ' Add any initialization after the InitializeComponent() call.

 

    End Sub

 

The next bit of code in the application is a method entitled “ShowYourAge”; this method creates and populates an AgeBag class instance based upon the results returned from the AgeEvaluator class GetTimeAlive method.  The method displays a message box containing the results returned in the age bag.  The method is annotated and you can follow what is going on within the method by reading he annotation.

 

    ''' <summary>

    ''' Method uses ManageAgeCalcs Class to

    ''' determine the age of the subject along with

    ''' additional information about the subject's

    ''' next birthday

    ''' </summary>

    Private Sub ShowYourAge()

 

        Try

            ' create a new AgeBag to collect the birth and age related

            ' information

            Dim ab As New AgeBag()

 

            ' get the subject's time alive based upon the

            ' date of birth and the end value date

            ab = AgeEvaluator.GetTimeAlive(dtpBirthDate.Value, _

                                           dtpEndDate.Value)

 

            ' display information about the subject's age and date

            ' of birth

            Dim sb As New StringBuilder()

            sb.Append("Time Alive (Days/Months/Years): " + NewLine)

            sb.Append("Years Alive: " + ab.AgeYears.ToString() + NewLine)

            sb.Append("Months Alive: " + ab.AgeMonths.ToString() + NewLine)

            sb.Append("Days Alive: " + ab.AgeDays.ToString() + NewLine +

            NewLine)

            sb.Append("Pending Birthday: " + NewLine)

            sb.Append("Birthday Is Within The Next 90 Days: " + _

                      ab.BirthdayIn90Days.ToString() + NewLine)

            sb.Append("Birthday Is Within The Next 60 Days: " + _

                      ab.BirthdayIn60Days.ToString() + NewLine)

            sb.Append("Birthday Is Within The Next 30 Days: " + _

                      ab.BirthdayIn30Days.ToString() + NewLine + NewLine)

            sb.Append("Days Until Next Birthday: " + _

                      ab.DaysToBirthday.ToString() + NewLine)

 

            ' display the age and birth day information

            MessageBox.Show("Birth Information" + NewLine + _

                            NewLine + sb.ToString(), "Birthday Test")

 

 

        Catch ex As Exception

 

            MessageBox.Show(ex.Message, "Error")

 

        End Try

 

    End Sub

 

The last bit of code in the form class is the button click event handler used to handle the test button’s click event.  The handler merely calls the ShowYourAge method defined in the previous section of this document.

 

 

    ''' <summary>

    ''' Test button click event handler;

    ''' calls the ShowYourAge method

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub btnTestDates_Click(ByVal sender As System.Object, _

                                   ByVal e As System.EventArgs) _

                                   Handles btnTestDates.Click

 

        ShowYourAge()

 

    End Sub

 

Summary

The article provide a simple class that may be used to determine the exact age of a person, or to determine the exact amount of time in years, months, and days that has passed between a specific start and end date.  Further, the class will indicate whether or not the person’s next birthday will occur within the following 30, 60, or 90 days.