How can I calculate the next birthday programmatically - vb.net

I have a data table with a date-of-birth column.
I would want to split the date apart and change the year part with today.year which is current year.
Below is my code:
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)
but I get this error:
Conversion from string "2019715" to type 'Date' is not valid.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidCastException: Conversion from string "2019715" to type 'Date' is not valid.
Source Error:
Line 149:
Line 150: Dim bday As Date = (Date.Today.Year & mdat.Month & mdat.Day)

VB.net is very peculiar when it comes to String to Date conversion.
I would recommend converting the Date from the individual components like this :
Dim bday as Date = New Date(Date.Today.Year, mdat.Month, mdat.Day)
Or as stated in the comments try using VB.Net DateTime
Dim bday as New DateTime(Date.Today.Year, mdat.Month, mdat.Day, 0, 0, 0)

thank you i think I have figured it out this is what i did. I calculated for the age with respect to current year and added the result to the year part of the date of birth.
here is the code
For Each rw As DataRow In birthdt.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)

I am basing this on what you wrote in a comment:
want to check those who have upcoming birthdays for a particular week.
It is fiddly to deal with leap years and dates which might be in the next year, but I think I've got all the cases covered here.
I made a table "Pets" in SQL Server with columns "Name" and "DOB", and put some data in.
I made a new Windows Forms project and added a multi-line textbox to Form1, and used this code:
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
It includes birthdays which happen "today" (you might not want to miss that), but you could
Dim matchEarliest = DateTime.Today.AddDays(1)
Dim matchLatest = matchEarliest.AddDays(7)
if you didn't want to include today.

I made a little class called Employee (it is at the bottom of the code). This answer is a bit similar to #AndrewMorton. I broke up the Sub into several functions that can be altered to suit without breaking the rest.
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

Related

Transfer Date from DataGridView to Crystal Reports VB.NET

When I use these codes Dim inDate As String = CStr(dgr.Cells(0).Value.ToString("MM-dd-yyyy")). The error says the conversion from string "MM-dd-yyyy" to type integer is not valid. But when I use these codes Dim inDate As String = CStr(dgr.Cells(0).Value. It displays the date from GridView but with a time format. I only want to display the date, not the datetime. To transfer data from grid view to crystal reports. I used DataSet and DataTable. The data type of date columns from the table is a string. These are my full code.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim report1 As New payslip
Try
Dim ds As New DataSet1
Dim ms As New MemoryStream
CompanyLogo_Picture.Image.Save(ms, CompanyLogo_Picture.Image.RawFormat)
Dim byt() As Byte = ms.ToArray
ds.DataTable1.Rows.Add(byt)
For Each dgr As DataGridViewRow In DataGridView3.Rows
Dim inDate As String = CStr(dgr.Cells(0).Value.ToString("MM-dd-yyyy"))
Dim inTime As TimeSpan = dgr.Cells(1).Value
Dim outDate As String = CStr(dgr.Cells(2).Value.ToString("MM-dd-yyyy"))
Dim outTime As TimeSpan = dgr.Cells(3).Value
ds.DataTable2.Rows.Add(inDate, inTime, outDate, outTime)
Next
report1.SetDataSource(ds)
report1.SetParameterValue("employeeName", TextBox6.Text)
report1.SetParameterValue("companyName", CompanyName_Label.Text)
report1.SetParameterValue("companyAddress", CompanyAddress_Label.Text)
report1.SetParameterValue("dateFrom", DateTimePicker1.Text)
report1.SetParameterValue("dateTo", DateTimePicker2.Text)
report1.SetParameterValue("dailyRate", payslip_dailyRate.Text)
report1.SetParameterValue("totalDays", payslip_totalDays.Text)
report1.SetParameterValue("mealAllowance", payslip_mealAllowance.Text)
report1.SetParameterValue("transportationAllowance", payslip_transpoAllowance.Text)
report1.SetParameterValue("medicalAllowance", payslip_medicalAllowance.Text)
report1.SetParameterValue("grossPay", payslip_grossPay.Text)
report1.SetParameterValue("SSS", payslip_sss.Text)
report1.SetParameterValue("philHealth", payslip_philhealth.Text)
report1.SetParameterValue("pagibig", payslip_pagibig.Text)
report1.SetParameterValue("loans", payslip_loans.Text)
report1.SetParameterValue("tardiness", payslip_tardiness.Text)
report1.SetParameterValue("totalDeductions", payslip_totalDeductions.Text)
report1.SetParameterValue("netPay", payslip_netPay.Text)
Catch ex As Exception
MsgBox(ex.Message)
End Try
Printer_Frm.CrystalReportViewer1.ReportSource = report1
Printer_Frm.ShowDialog()
End Sub
I tried every codes I know to convert these data to string type but nothing works. Is there another ways to get my required output for these? Thanks ^_^
My problem is now solved. I use these codes Dim inDate As String = Format(dgr.Cells(0).Value, "MM-dd-yyyy") instead of these Dim inDate As String = CStr(dgr.Cells(0).Value.ToString("MM-dd-yyyy")). Thanks guys ^_^

how to show todays data in datagridview

Public Sub filltable()
Dim qry As String = "select filename as FileName,filesize as FileSize,time as Time from files"
Dim ds As DataSet = New DataSet()
ds = GetQueryResult_Mysql(qry)
DataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnMode.Fill)
If (ds.Tables(0).Rows.Count > 0) Then
''For i As Integer = 0 To ds.Tables(0).Rows.Count
'' Dim fname As String = ds.Tables(0).Rows(i).Item("filename").ToString()
'' Dim fsize As String = ds.Tables(0).Rows(i).Item("filesize").ToString()
'' Dim ftime As String = ds.Tables(0).Rows(i).Item("time").ToString()
''Next
DataGridView1.DataSource = ds.Tables(0)
End If
End Sub
Assuming time is a time stamp that contains the date too
select filename as FileName,filesize as FileSize,time as Time from files WHERE time >= CURDATE()
Do please tag your database (and tag the version) next time; we shouldn't have to catch sight of a curiously named method buried in the middle of the code to know you're using MySQL

How to add duration between two times to listview in vb .NET

I have a ListView that I want to get the duration between the two times and add in the fifth column for each row.
I have no any idea how i can do this.
If you can help me, so show me with code please.
Like this:
I tried with this code, but it's not work:
For Each it As ListViewItem In ListView1.Items
Dim dFrom As DateTime
Dim dTo As DateTime
Dim sDateFrom As String = it.SubItems(1).Text
Dim sDateTo As String = it.SubItems(2).Text
If DateTime.TryParse(sDateFrom, dFrom) AndAlso DateTime.TryParse(sDateTo, dTo) Then
Dim TS As TimeSpan = dTo - dFrom
Dim hour As Integer = TS.Hours
Dim mins As Integer = TS.Minutes
Dim secs As Integer = TS.Seconds
Dim msec As Integer = TS.Milliseconds
Dim timeDiff As String = ((hour.ToString("00") & ":") + mins.ToString("00") & ":") + secs.ToString("00") + "." + msec.ToString("000")
it.SubItems.Add(timeDiff)
End If
Use the same loop where you populate the control to calculate and add the duration subitem. You don't need to do that in a separate loop. Convert the StartDate & EndDate strings to DateTime or TimeSpan objects, subtract the end time from the start time to get a TimeSpan object with the duration, call the ToString method and pass the "s\.fff" format to set the value of the duration's subitem.
Example
Imports System.Globalization
Dim inFormat = "hh\:mm\:ss\,fff"
Dim outFormat = "s\.fff"
Dim provider = CultureInfo.InvariantCulture
For Each lvi As ListViewItem In listView1.Items
Dim tsStart As TimeSpan, tsEnd As TimeSpan
If TimeSpan.TryParseExact(lvi.SubItems(1).Text, inFormat, provider, tsStart) AndAlso
TimeSpan.TryParseExact(lvi.SubItems(2).Text, inFormat, provider, tsEnd) Then
lvi.SubItems.Add((tsEnd - tsStart).ToString(outFormat))
End If
Next
In case and in somehow you already have the duration subitem in the collection, set it's .Text property instead of calling the .Add(...) method.
lvi.SubItems(4).Text = (tsEnd - tsStart).ToString(outFormat)
Again, you don't need a separate loop, in the main loop where you add the other subitems, replace the lvi.SubItems(1).Text and lvi.SubItems(2).Text parameters in the preceding example with their sources. Their properties in a model or their variables if you don't have a model.
I don't know your code
I think you can do it by using the source below.
Dim dFrom As DateTime
Dim dTo As DateTime
Dim sDateFrom As String = "00:00:06.200"
Dim sDateTo As String = "00:00:07.680"
If DateTime.TryParse(sDateFrom, dFrom) AndAlso DateTime.TryParse(sDateTo, dTo) Then
Dim TS As TimeSpan = dTo - dFrom
Dim hour As Integer = TS.Hours
Dim mins As Integer = TS.Minutes
Dim secs As Integer = TS.Seconds
Dim msec As Integer = TS.Milliseconds
Dim timeDiff As String = ((hour.ToString("00") & ":") + mins.ToString("00") & ":") + secs.ToString("00") + "." + msec.ToString("000")
MsgBox(timeDiff) 'output
End If
Be sure you have a column ready to receive the new SubItem.
I proceeded with the comma that I asked about in comments. You can changed the .ParseExact if it is really a period.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
With ListView1.Columns
.Add("Start Time")
.Add("End Time")
.Add("Duration")
End With
Dim li As New ListViewItem("00:00:06,200")
li.SubItems.Add("00:00:07,680")
ListView1.Items.Add(li)
End Sub
Even though the first column is the ListViewItem is the Text property, it is also SubItems(0). This can be confusing. You do have your indexes correct.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
For Each li As ListViewItem In ListView1.Items
Dim sDateFrom As String = li.SubItems(0).Text 'also works with il.Text
Dim sDateTo As String = li.SubItems(1).Text
Dim FormatString = "hh:mm:ss,fff"
Dim provider = CultureInfo.InvariantCulture
Dim StartTime = Date.ParseExact(sDateFrom, FormatString, provider)
Dim EndTime = Date.ParseExact(sDateTo, FormatString, provider)
Dim TS As TimeSpan = EndTime - StartTime
'Dim timeDiff As String = $"{TS.Hours:00}:{TS.Minutes:00}:{TS.Seconds:00}.{TS.Milliseconds:000}"
'or
Dim timeDiff = TS.ToString("c")
li.SubItems.Add(timeDiff)
Next
End Sub
When you have a string with several variables that need to be inserted use an interpolated string which is preceded by a $. This allows you to insert your variables directly in line enclosed in { }. This is much easier to write, read, and understand. You also avoid many mistakes with quotes and concatenation characters. Formatting of the variables is accomplished by the format following a colon inside the braces. If you can stand a few extra zeros, you can format the TimeSpan directly with .ToString("c").

How to filter a dataview rows by monthcalendar?

Respected Sir,
I am trying to filter dataview by monthcalendar bythe below script, but i am not getting rows fitered. whats the error i am doing in this script ?
If Me.myDataSet.myTable.Rows.Count > 0 Then
Dim myDataView As New DataView
myDataView.Table = Me.myDataSet.myTable
Dim myDate As String = String.Format("[vstime] = '{0:M/dd/yyyy}' ", MonthCalendar1.SelectionRange.Start.Date)
myDataView.RowFilter = String.Format(myDate)
End If
yours faithfully
Murulimadhav
Ok, i solved it by this example
How to use BindingSource.Filter for a Date in visual basic 2012?
or is there any simpler solution than this ?
Public myFilterDate As DateTime
Public Sub myDayFilter(ByVal myFilterDate)
If Me.myDataSet.myTable.Rows.Count > 0 Then
myFilterDate = MonthCalendar1.SelectionRange.Start.Date
Dim dateFrom As DateTime = myFilterDate.Date
Dim dateTo As DateTime = dateFrom.AddDays(1).Subtract(New TimeSpan(1))
Dim filterBuilder As New StringBuilder()
Dim filterFormat As String = "vstime {0} #{1:yyyy/MM/dd HH:mm:ss}#"
With filterBuilder
.AppendFormat(filterFormat, ">=", dateFrom)
.Append(" AND ")
.AppendFormat(filterFormat, "<=", dateTo)
End With
Me.myBindingSource1.Filter = filterBuilder.ToString()
End If
End Sub
Private Sub MonthCalendar1_DateChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DateRangeEventArgs) Handles MonthCalendar1.DateChanged
myDayFilter(myFilterDate)
End Sub
thanking you
Your faithfully
Murulimadhav

How to set AccountExpires in VB.NET via a AD DirectoryEntry

I needed to set the accountExpires property in the AD DirectoryEntry couldn't find a simple answer.
Found some information;
http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.userprincipal.aspx
http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/182bfb6a-8b23-4c96-9379-101a4d91241a
http://www.rlmueller.net/AccountExpires.htm
Saw some articles re ADS****.dll but didn't think I needed to use this method
Dim valueToSet As Date = Now.AddDays(10)
Dim ADSPath As String = "LDAP://cn=..."
Dim de As DirectoryEntry = New DirectoryEntry(ADSPath)
Dim d As TimeSpan = valueToSet.ToUniversalTime - Date.Parse("01/01/1601")
Dim ValueToSetAsString As String = d.Ticks.ToString
' it appears that the ticks value is too large for the value of the directory entry
' converting to a string (18 chars or so) works!
de.Properties("accountexpires").Value = ValueToSetAsString
Thanks to Brian it looks like the large amount of code wrote above can be simplified;
de.Properties("accountexpires").Value = valueToSet.ToFileTime.ToString
A function to return the AccountExpires and other largeInteger issues in VB.NET
Function ConvertADValueToDateTime(ByVal li As Object) As DateTime
' http://bytes.com/topic/visual-basic-net/answers/512901-lastlogontimestamp
Try
Dim lngHigh = li.HighPart
Dim lngLow = li.LowPart
Dim lastLogon = (lngHigh * 2 ^ 32) - lngLow
Dim returnDateTime As DateTime = DateTime.FromFileTime(lastLogon)
Return returnDateTime
Catch ex As Exception
Return Nothing
End Try
End Function
Example use :
Dim d As DateTime = ConvertADValueToDateTime(de.Properties("accountexpires").value)
If d = "01/01/1601" Then
' no expiry date
Return Nothing
Else
Return d
End If
An alternative method
Convert LDAP AccountExpires to DateTime in C#
Something like this will set your account to expire in 30 days:
Dim de As New DirectoryEntry("LDAP://cn=foo,cn=users,dc=contoso,dc=com")
de.Properties["accountExpires"].Value = DateTime.UtcNow.AddDays(30).ToFileTime()
de.CommitChanges()
This uses a DateTimePicker on a form but it should be trivial to use any other date format..
Imports System.DirectoryServices
Imports System.DirectoryServices.ActiveDirectory
Imports System.IO
'Get the user
Dim EntryString As String
EntryString = "LDAP://...."
Dim dirEntry As DirectoryEntry
dirEntry = New DirectoryEntry(EntryString)
Dim dirSearcher As New DirectorySearcher(dirEntry)
dirSearcher.Filter = "(&(objectCategory=Person)(objectClass=user)(SAMAccountName=" & Trim(Form1.AccountNameTB.Text) & "))"
dirSearcher.SearchScope = SearchScope.Subtree
Dim searchResults As SearchResult = dirSearcher.FindOne()
'Set the date
Dim d1 As Date = Form1.AccountExpiresDTP.Value
Dim d2 As New DateTime(d1.Year, d1.Month, d1.Day)
d2 = d2.AddDays(1) 'Add one day so that it matches what is in AD
Dim ft As Long = d2.ToFileTime()
dirEntryResults.Properties("accountExpires").Value = ft.ToString 'You do need to turn it into a string
dirEntryResults.CommitChanges()
dirEntryResults.Close()