如何以编程方式计算下一个生日

时间:2019-10-02 09:23:32

标签: vb.net

我有一个带有出生日期列的数据表。

我想分开日期,并用今天的year.year更改年份部分。

下面是我的代码:

Dim birthda As New SqlDataAdapter(birthcmd)
Dim birthdt As New DataTable
birthda.Fill(birthdt)

For Each rw As DataRow In birthdt.Rows
    Dim dob As String = rw.Item(3)

    Dim mdat As Date = FormatDateTime(dob, DateFormat.ShortDate)

    Dim bday As Date = (Date.Today.Year & mdat.Month & mdat.Day)

    Dim yers As Integer = DateDiff(DateInterval.Year, mdat.Date, Today.Date)
    Dim moths As Integer = DateDiff(DateInterval.Month, mdat.Date, Today.Date)
    Dim dys As Integer = DateDiff(DateInterval.Day, mdat.Date, Today.Date)

但我收到此错误:

  

从字符串“ 2019715”到类型“日期”的转换无效。   说明:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。

     

异常详细信息:System.InvalidCastException:从字符串“ 2019715”到类型“日期”的转换无效。

     

源错误:
  149行:
  第150行:Dim bday As Date =(日期,今天,年份和mdat.Month和mdat.Day)

4 个答案:

答案 0 :(得分:0)

关于字符串到日期的转换,VB.net非常独特。

我建议像这样从各个组件转换日期:

Dim bday as Date = New Date(Date.Today.Year, mdat.Month, mdat.Day)

或者如评论中所述,尝试使用VB.Net DateTime

Dim bday as New DateTime(Date.Today.Year, mdat.Month, mdat.Day, 0, 0, 0)

答案 1 :(得分:0)

谢谢你,我想我已经弄清楚了这就是我所做的。我针对当前年份计算了年龄,并将结果添加到了出生日期的年份部分。
这是代码

对于每个行作为datadow在birthd.Rows中

        Dim dob As DateTime = rw.Item(2)


        Dim mdat As Date = FormatDateTime(dob, DateFormat.ShortDate)

     Dim yers As Integer = DateDiff(DateInterval.Year, mdat.Date, Today.Date)
        Dim moths As Integer = DateDiff(DateInterval.Month, mdat.Date, Today.Date)

        Dim dys As Integer = DateDiff(DateInterval.Day, mdat.Date, Today.Date)

        Dim ndob As Date = (DateAdd(DateInterval.Year, yers, mdat))

        Dim yers2 As Integer = DateDiff(DateInterval.Year, ndob.Date, Today.Date)
        Dim moths2 As Integer = DateDiff(DateInterval.Month, ndob.Date, Today.Date)
        Dim dys2 As Integer = DateDiff(DateInterval.Day, ndob.Date, Today.Date)     

答案 2 :(得分:0)

这是基于您在comment中写的内容:

  

想查看那些在特定一周即将过生日的人。

处理下一年的dates年和日期很麻烦,但我想这里已经涵盖了所有情况。

我在SQL Server中用“名称”和“ DOB”列创建了一个“宠物”表,并将一些数据放入其中。

我创建了一个新的Windows Forms项目,并在Form1中添加了多行文本框,并使用了以下代码:

Imports System.Data.SqlClient
Imports System.Text

Public Class Form1

    Sub ShowUpcomingBirthdays()
        Dim csb As New SqlConnectionStringBuilder With {.DataSource = ".\SQLEXPRESS", .InitialCatalog = "Testing", .IntegratedSecurity = True}

        Dim birthdt As New DataTable()

        Dim sql = "SELECT [Name], [DOB] FROM [Pets]"

        Using conn As New SqlConnection(csb.ConnectionString)
            Using sqlCmd As New SqlCommand(sql, conn)
                Dim da As New SqlDataAdapter With {.SelectCommand = sqlCmd}
                da.Fill(birthdt)
            End Using
        End Using

        Dim matchEarliest = DateTime.Today
        Dim matchLatest = matchEarliest.AddDays(8)

        Dim sb As New StringBuilder ' somewhere to save the matching data

        For Each r As DataRow In birthdt.Rows
            Dim dob = Convert.ToDateTime(r.Item("DOB"))

            ' Allow for leap years by transferring the birthday to 1st March - some countries would use 28th February.
            If DateTime.IsLeapYear(dob.Year) AndAlso Not DateTime.IsLeapYear(matchEarliest.Year) AndAlso dob.Month = 2 AndAlso dob.Day = 29 Then
                dob = dob.AddDays(1)
            End If

            Dim nextBirthday = New DateTime(matchEarliest.Year, dob.Month, dob.Day)

            If dob.Month <= matchEarliest.Month AndAlso dob.Day < matchEarliest.Day Then
                ' birthday has already happened this calendar year, make it next year
                nextBirthday = nextBirthday.AddYears(1)
            End If

            If nextBirthday >= matchEarliest AndAlso nextBirthday < matchLatest Then
                ' the record is in the required range
                sb.AppendLine(CStr(r.Item("Name")) & " " & dob.ToString("ddd dd MMMM"))
            End If

        Next

        TextBox1.Text = sb.ToString()

    End Sub

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

    End Sub

End Class

它包括发生在“今天”的生日(您可能不想错过),但是您可以

        Dim matchEarliest = DateTime.Today.AddDays(1)
        Dim matchLatest = matchEarliest.AddDays(7)

如果您今天不想加入。

答案 3 :(得分:0)

我做了一个叫做Employee的小类(它在代码的底部)。这个答案有点类似于@AndrewMorton。我将Sub分解为几个功能,可以对其进行更改以适应其他情况。

Private Sub DisplayUpcomingBirthdays()
    Dim lstBirthdays As New List(Of Employee)
    Dim dt = RetrieveBirthdays()
    For Each rw As DataRow In dt.Rows
        Dim CurrentYearBirthday As Date = GetCurrentYearBD(CDate(rw.Item("Birthdate")))
        If IsBDThisWeek(CurrentYearBirthday) Then
            lstBirthdays.Add(New Employee(CurrentYearBirthday, rw.Item("Name").ToString))
        End If
    Next
    Dim SortedList = SortByBirthdays(lstBirthdays)
    ListBox1.DataSource = SortedList
End Sub

Private Function RetrieveBirthdays() As DataTable
    Dim query = "Select Name, Birthdate From Employes;"
    Dim birthdt As New DataTable
    Using cn As New SqlConnection("YourConnectionString")
        Using cmd As New SqlCommand(query, cn)
            cn.Open()
            birthdt.Load(cmd.ExecuteReader)
        End Using
    End Using
    Return birthdt
End Function

Private Function GetCurrentYearBD(BirthDate As Date) As Date
    Dim Day As Integer = BirthDate.Day
    Dim Month As Integer = BirthDate.Month
    Dim Year As Integer = Now.Year
    'Bithday is celebrated on the 28th when it is not a leap year
    If Month = 2 AndAlso Day = 29 AndAlso Not DateTime.IsLeapYear(Year) Then
        Day = 28
    End If
    Return New DateTime(Year, Month, Day)
End Function

Private Function IsBDThisWeek(BD As Date) As Boolean
    Dim Tomorow = Now.AddDays(1)
    Dim WeekFromNow = Now.AddDays(7)
    If BD >= Tomorow AndAlso BD <= WeekFromNow Then
        Return True
    End If
    Return False
End Function

Private Function SortByBirthdays(Employees As List(Of Employee)) As List(Of Employee)
    Dim lst = (From emp In Employees
               Order By emp.Birthdate
               Select emp).ToList
    Return lst
End Function

Public Class Employee
    Public Property Birthdate As Date
    Public Property Name As String

    Public Sub New(BD As Date, eName As String)
        Birthdate = BD
        Name = eName
    End Sub

    Public Overrides Function ToString() As String
        Return $"{Name},  {Birthdate.ToString("MMMM dd")}"
    End Function
End Class