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).
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):
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.