65.9K
CodeProject 正在变化。 阅读更多。
Home

在 VB 中构建 UNIX 时间到日期转换自定义控件

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2008年6月4日

CPOL

5分钟阅读

viewsIcon

30444

downloadIcon

145

本文介绍了一个自定义控件的构建,该控件可以将 UNIX 时间转换为易于理解的日期,以便在 WinForms 应用程序中显示。

引言

本文介绍了一个自定义控件的构建,该控件可以将 UNIX 时间转换为易于理解的日期,以便在 WinForms 应用程序中显示。该控件可以接受标准的日期或 UNIX 时间值,并且可以在任一方向上进行转换(从 UNIX 时间到日期,或从日期到 UNIX 时间)。

图 1:正在运行的测试应用程序。

该控件包含两个属性,可以用来控制显示输出和控件的可用性。“Convert On Click”(点击转换)属性将启用或禁用控件在用户点击控件时在 UNIX 时间和常规日期之间相互转换的能力;如果您希望用户在一个格式下编辑值,而在另一个格式下查看,这会很有用。另一个属性是“Direction”(方向)。Direction 用于确定控件是显示 UNIX 时间值还是标准日期值。

入门

要开始,请解压包含的项目并在 Visual Studio 2008 环境中打开解决方案。在解决方案资源管理器中,您应该会看到这些文件(图 2)。

图 2:解决方案资源管理器

从图 2 可以看出,有两个项目。UnixTime 是自定义控件项目,其中包含一个自定义控件 (UTConverter.vb)。第二个项目 (ControlTest) 是一个用于测试该控件的 WinForms 应用程序。

自定义控件 (UTConverter.vb)

该自定义控件是一个扩展了标准 TextBox 控件的类。

代码非常简单。如果您愿意在 IDE 中打开代码视图,您会看到代码文件以以下库 imports 开始

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

imports 之后,定义了类(注意类继承自 TextBox

Public Class UTConverter
    Inherits TextBox

接下来定义了一个枚举;该枚举名为 Direction。该枚举用于定义扩展 textbox 控件中显示的日期是显示日期还是 UNIX 时间戳值。UNIX 时间戳值可以定义为 1970 年 1 月 1 日之前的秒数或之后的秒数。在枚举声明之后,定义了两个 private 成员变量;一个用于跟踪选定的 Direction 选项,另一个是 Boolean 值,用于确定是否启用了“Convert On Click”。

#Region "Members"

    Public Enum Direction
        ToUnix
        ToDate
    End Enum

    Private mCurrentDirection As Direction
    Private mConvertOnClick As Boolean

#End Region

接下来定义了一个构造函数;在构造函数中,通过将 CurrentDirection 属性设置为 Direction.ToDate,并将 ConvertOnClick 属性设置为 true 来设置控件的默认值。在这种默认情况下,控件通常会以日期形式显示日期,并且在点击时会将日期转换回 UNIX 时间戳值。

#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

构造函数之后,设置了一个区域来包含控件的附加属性。第一个属性是 CurrentDirection;它提供对 mCurrentDirection 成员变量的公共访问,该变量用于确定控件是显示其值作为日期还是 UNIX 时间戳值。另一个属性 ConvertOnClick 用于在运行时启用或显示控件在 UNIX 和常规日期显示之间进行转换的功能。

#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

下一个定义的区域标题是 Methods;本节包含提供此自定义控件的 UNIX-日期转换功能的代码。

#Region "Methods"

ConvertToDateTime 函数将 Unix 时间戳转换为短日期字符串;这可以通过将提供的秒数添加到 UNIX 时间戳的基线数据来轻松完成。

    ''' <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

下一个函数将日期(作为短日期字符串)转换为 UNIX 时间格式

    ''' <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

控件的验证事件处理程序用于根据控件的 CurrentDirection 属性是设置为显示日期还是 UNIX 时间来更新日期或 UNIX 时间值的显示。

    ''' <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

按键事件处理程序被配置为忽略可能输入到控件中的非数字值。该控件接受数字、控制字符和减号键。通过这种方式限制按键,用户可以输入数字,使用退格键,并在处理 UNIX 时间时输入负号以输入早于 1970 年 1 月 1 日的日期。

    ''' <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

接下来的代码只是在用户离开、进入或刷新文本框时重复调用以更新显示的价值。

    ''' <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

以上是控件的内容。下一节将讨论演示项目。

主窗体 (Control Test 项目中的 Form1.vb)

测试窗体包含八个自定义控件实例;每个实例都用于显示不同的内容。四个使用短日期字符串加载,四个使用 UNIX 时间戳加载。在两组中,每个控件都设置为启用和禁用 ConvertOnClick 方法,并将 Direction 选项设置为 ToDateToUnix。向窗体添加了一个工具提示,并在用户将鼠标悬停在控件上时,该工具提示用于描述所选选项的某些内容。

窗体的代码全部显示在下方。窗体加载事件处理程序中的代码已注释,以描述每个部分的作用。

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

摘要

本文旨在描述一个具有非常特定目的的自定义控件,该控件用于在 UNIX 时间戳格式和常规短日期字符串之间转换值。因此,该项目是一个简单的示例,描述了如何创建一个自定义控件来解决一个问题,您可以使用类似的方法来处理其他需要自定义控件的情况,而无需使用现有控件和额外的代码来实现类似的结果。

历史

  • 2008年6月3日:初始版本
© . All rights reserved.