Building a UNIX Time to Date Conversion Custom Control in VB.NET

Introduction:

This article addresses the construction of a custom control that will convert UNIX time into useful and readable dates for display in a Win Forms application. The control will accept either a standard date or UNIX time value and can convert the value in either direction (From UNIX Time to Date or from Date to UNIX Time).

test application running-in-windows8.gif

Figure 1: The test application running

The control contains two properties that may be set to control the displayed output and the usability of the control. The "Convert On Click" property will enable or disable the control's ability to convert the value back and forth between UNIX time and normal date when a user clicks on the control; this may be useful if you wish to permit the user to edit the value in one format and view it in another. The other property is "Direction". Direction is used to determine whether or not the control will display the value as UNIX time or as a standard date.

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.gif

Figure 2: Solution Explorer

As you can see from Figure 2; there are two projects. UnixTime is the custom control project and it contains a single custom control (UTConverter.vb). the second project (ControlTest) is a win forms application used to test the control.

The Custom Control (UTConverter.vb).

The custom control is a class that extends the standard TextBox control.

The code is pretty simple, if you'd care to open the code view up in the IDE you will see that the code file begins with the following library imports:

Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms

Following the imports, the class is defined (note the class inherits TextBox):

Public
Class UTConverter
Inherits TextBox

Next an enumeration is defined; this enumeration is entitled "Direction". The enumeration is used to define whether or not the date displayed in the extended textbox control will display dates or UNIX time stamp values. UNIX time stamp values can be defined as the number of seconds before or after the date 1/1/1970. Following the declaration of the enumeration, two private member variables are defined; one to keep track of the selected Direction option, and one Boolean value used to determine whether or not "Convert On Click" is enabled.

#Region "Members"

    Public Enum Direction

        ToUnix
        ToDate

    End Enum
 

    Private mCurrentDirection As Direction

    Private mConvertOnClick As Boolean

 

#End Region

Next, a constructor is defined; within the constructor, the default values for the control are set by setting the CurrentDirection property to Direction.ToDate, and setting the ConvertOnClick property to true. In this default condition, the control will normally display the date as a date and will, on click, convert the date back to the UNIX time stamp value.
 

#Region "Constructor"

 

    Public Sub New()

 

        ' This call is required by the Windows Form Designer.

        InitializeComponent()

 

        ' Add any initialization after the InitializeComponent() call.

        CurrentDirection = Direction.ToDate

        ConvertOnClick = True

 

    End Sub

 

#End Region

After the constructor, a region is setup to contain the control's added properties. The first property is CurrentDirection; it provides public access to the mCurrentDirection member variable used to determine whether or not the control will display its value as a date or as a UNIX time stamp value. The other property, ConvertOnClick, is used to enable or display the functionality that will convert between UNIX and normal date displays within the control at runtime.

 

#Region "Properties"

 

    <CategoryAttribute("UNIX Time"), _Browsable(True), _BindableAttribute(False), _DescriptionAttribute("Convert to or from UNIX time.")>

    Public Property CurrentDirection() As Direction

        Get

            Return mCurrentDirection

        End Get

 

        Set(ByVal value As Direction)

            mCurrentDirection = value

        End Set

    End Property
 

    <CategoryAttribute("UNIX Time"), _Browsable(True), _BindableAttribute(False), _DescriptionAttribute("Enable or disable On Click UNIX Time format conversion.")>

    Public Property ConvertOnClick() As Boolean

        Get

            Return mConvertOnClick

        End Get
 

        Set(ByVal value As Boolean)

 

            mConvertOnClick = value
 

        End Set

    End Property

 

#End Region

The next region defined is entitled "Methods"; this section carries the code used to provide the UNIX-Date conversion functionality to this custom control.

#Region "Methods"

The ConvertToDateTime function converts the unix time stamp to a short date string; this is easily accomplished by adding the number of seconds provided to the baseline data used for the UNIX time stamp.

 

    ''' <summary>

    ''' Convert unix time to date

    ''' </summary>

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

    ''' <remarks></remarks>

    Private Sub ConvertToDateTime(ByVal unixTime As Double)

 

        Dim convertedDateTime As DateTime = _New DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(unixTime)

 

        Me.Text = convertedDateTime.ToShortDateString()

 

    End Sub

The next function converts a date (as a short date string) to UNIX time format:

 

    ''' <summary>

    ''' Convert date to unix time

    ''' </summary>

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

    ''' <remarks></remarks>

    Private Sub ConvertToUnixTime(ByVal dt As Date)

 

        Me.Text = (dt - New DateTime(1970, 1, 1, 0, 0, _0)).TotalSeconds.ToString()

 

        ' Note:  This operation will truncate the value to its

        ' minimum for the date time shown; for example, if "500000000" is  

        ' entered into the textbox, this operation will alter the value to

        ' "499996800"

        ' which is the minimum value for the date 11/5/1985.  If you need to

        ' maintain the exact unix time value, create a separate variable to

        ' store it in and set it to the unix time stamp prior to converting

        ' from unix time to a date.

 

    End Sub

The controls validated event handler is used to update the display of the date or UNIX time value based upon whether or not the control's Current Direction property has been set to display dates or UNIX time.

 

    ''' <summary>

    ''' Upon validation, update the control to

    ''' display the converted unix time

    ''' </summary>

    ''' <remarks></remarks>

    Private Sub UTConverter_Validated(ByVal sender As Object, _ByVal e As EventArgs) Handles MyBase.Validated

 

        Try

 

            If mCurrentDirection = Direction.ToDate Then

                ConvertToDateTime(Convert.ToDouble(Me.Text))

            Else

                ConvertToUnixTime(Convert.ToDateTime(Me.Text))

            End If

 

        Catch

            ' do nothing

        End Try

    End Sub

The key press event handler is configured to disregard non-numeric values that may be typed into the control. The control accepts digits, control characters, and the minus key. Limiting the key press in this way will allow the user to enter numbers and to use the backspace key, and to enter a minus sign to enter dates less than 1/1/1970 when working with UNIX times.

 

    ''' <summary>

    ''' Disregard non-numeric values; allow

    ''' numbers, controls, and the negative

    ''' sign.

    ''' </summary>

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

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

    ''' <remarks></remarks>

    Private Sub UTConverter_KeyPress(ByVal sender _As Object, ByVal e _As KeyPressEventArgs) _Handles MyBase.KeyPress

 

        If (Not Char.IsDigit(e.KeyChar) And _Not Char.IsControl(e.KeyChar) And _ e.KeyChar <> "-") Then

 

            e.Handled = True

 

        End If

 

    End Sub

The next bit of code just repeats the call to update the displayed value whenever the user exits, enters, or refreshes the textbox.

    ''' <summary>

    ''' Update the displayed value to show a date

    ''' in lieu of a unix time value whenever the

    ''' leave event is fired.

    ''' </summary>

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

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

    ''' <remarks></remarks>

    Private Sub UTConverter_Leave(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Leave

 

        Try

            If mCurrentDirection = Direction.ToDate Then

                ConvertToDateTime(Convert.ToDouble(Me.Text))

            Else

 

                ConvertToUnixTime(Convert.ToDateTime(Me.Text))

            End If

        Catch

            ' do nothing

        End Try

 

    End Sub
 

    ''' <summary>

    ''' Update the displayed value to show a unix

    ''' time in lieu of a date whenever the enter

    ''' event is fired.

    '''

    ''' Disable this event handler if you do

    ''' not want the time to convert back to

    ''' unix time

    '''

    ''' </summary>

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

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

    ''' <remarks></remarks>

    Private Sub UTConverter_Enter(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Enter

 

        If ConvertOnClick = True Then

            Try

                If mCurrentDirection = Direction.ToDate Then

                    ConvertToUnixTime(Convert.ToDateTime(Me.Text))

                Else

                    ConvertToDateTime(Convert.ToDouble(Me.Text))

                End If

            Catch

                ' do nothing

            End Try

        End If

 

    End Sub
 

    ''' <summary>

    ''' Override the base refresh method

    ''' to update the display of each value

    ''' </summary>

    ''' <remarks></remarks>

    Public Overrides Sub Refresh()

 

        MyBase.Refresh()

 

        ' convert to date whenever control

        ' is refreshed

        Try

            If mCurrentDirection = Direction.ToDate Then

                ConvertToDateTime(Convert.ToDouble(Me.Text))

            Else

 

                ConvertToUnixTime(Convert.ToDateTime(Me.Text))

            End If

        Catch

            ' do nothing

        End Try

 

    End Sub

#End Region

End Class

That wraps the content of the control. The next section will discuss the demonstration project.

The Main Form (Form1.vb from the Control Test Project).

The test form contains eight instances of the custom control; each one is used to display something different. Four are loaded using a short date string and four are loaded using a UNIX time stamp. In both groups, each of the controls is set up with the ConvertOnClick method enabled and disabled, and with the Direction option set to either ToDate or ToUnix. A tooltip was added to the form and it is set to describe something about each of the options selected when the user hovers over the control.
The code for the form is presented in its entirety below. The code in the form load event handler is annotated to describe what each section accomplishes.

 

Public Class Form1

 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

 

        ' use negative numbers to express dates

        ' prior to 1/1/1970

 

        ' load with unix time

        UtConverter1.Text = "-885772800"  ' a date prior to 1/1/1970

        UtConverter2.Text = "849312000"

        UtConverter3.Text = "999648000"

        UtConverter4.Text = "4000000000"

 

        ' load with normal dates

        UtConverter5.Text = "7/19/1960"

        UtConverter6.Text = "5/16/1933"

        UtConverter7.Text = "7/4/2008"

        UtConverter8.Text = "6/18/3100"

 

        ' refresh all of the controls

        ' to update the display

        UtConverter1.Refresh()

        UtConverter2.Refresh()

        UtConverter3.Refresh()

        UtConverter4.Refresh()

        UtConverter5.Refresh()

        UtConverter6.Refresh()

        UtConverter7.Refresh()

        UtConverter8.Refresh()

 

        ' move selection off custom controls

        button1.Select()

 

    End Sub
 

    Private Sub button1_Click(ByVal sender As System.Object, ByVal e As

    System.EventArgs) Handles button1.Click

        Application.Exit()

    End Sub

 

End Class

Summary.

This article is intended to describe a custom control with the very specific purpose of converting values between UNIX time stamp format and a normal short date string. In that, the project is an easy example describing how one might go about creating custom control to solve a problem and one may use a similar approach to other situations where a custom control might be a handy alternative to using an existing control along with additional code to attain similar results.