VB.net How to Compare difference in years - vb.net

New VB coder here, trying to check if todays date is more then 10 years past a date from a grabbed database entry, and display a message if it is.
The Database is already imported and set up in the VB application H ave made, and working, I made a report to display the information.
I am guessing I need to use the Datediff but I can't seem to get it to work, Thanks.
I will give my variable name here
Dim Custsince as Date
'From the Database here
CustSince = CustListodr("Custsince")
Thanks in advance, working with dates is not my strong point.

You can just use a TimeSpan directly by subtracting the dates:
Dim customerLength = DateTime.Now - Custsince
Dim approxYears = customerLength.TotalDays / 365

If the date read from the database is already stored in a Date variable, you can simply subtract one date from another to get the difference. The result of subtracting two dates is a TimeSpan object. TimeSpan objects contain useful properties that allow you to see how long the span of time is in various units (e.g. days, hours, minutes). For instance:
Dim date1 As Date = ...
Dim date2 As Date = Date.Now
Dim span As TimeSpan = date2 - date1
If span.TotalDays >= 3650 then ' Ten years
'...
End If
Alternatively, if you need to compare calendar years, rather than the actual span of time, you can compare the years from each date, like this:
If date2.Year - date1.Year >= 10 Then
'...
End If
If the date being read from the database is stored as a string, rather than as a Date value, you would need to use Date.Parse or Date.ParseExact to convert the string into a Date value.

Related

Declare either .Text, .Value, .Value2 using array to fetch data from excel

I use Excel automation with Excel interop. My code takes excel sheet using array fetch. As you can see below i take all of them as .Value2, however i would like to specify for example that one of my excel column to be taken as .Text. How to achieve that?
'Convert from interop object to native vb.net object, indexed 1 to length
Dim data As Object(,) = DirectCast(_xlWorkSheet.UsedRange.Value2, Object(,))
For row As Integer = 2 To data.GetUpperBound(0) - 1
Dim newDataRow As DataRow = dt.NewRow()
Dim dattime As DateTime = DateTime.FromOADate(data(row, 11))
Next
i have one column in excel that has format: [h]:mm:ss means hours could exceed clock hour so means there could be e.g 783:34:12. When i tried to use formatting for instance: NumberFormat ="#" or whatever else i always got wrong result.
Based on that description, I will assume that the value is entered into Excel as a numeric Double. i.e.: 783:34:13 equals 32.64875.
In VB.Net, you could generate a TimeSpan structure to yield the resulting day, hour, minutes and seconds components. In the following, rng is an Excel.Range representing a single cell.
Dim val As Double = CDbl(rng.Value2)
Dim ts As TimeSpan = DateTime.FromOADate(val) - DateTime.FromOADate(0)
Now if you wanted to format this TimeSpan as a string similar to that displayed in Excel, you could do something like this:
Dim s As String = String.Format("{0}:{1:00}:{2:00}", (ts.Days * 24) + ts.Hours, ts.Minutes, ts.Seconds)
The reason I am recommending this technique over getting the Text property of an Excel.Range is that the Text property will return exactly what you would see in Excel including the ever helpful "###" when the column is not wide enough to display the formatted value.
Edit To Address Comments:
can you explain why you do this: - DateTime.FromOADate(0) ?
Excel encodes a date-time value as a decimal number of 24 hour periods (days) from a specified date-time that has the value of zero. Your data is apparently making use of this fact to allow you to have a cell with a value of 783:34:12 (783 hours, 34 minutes, 12 seconds) or 32.64875 as a decimal value.
In order to retrieve the offset in (days, hours, minutes, seconds) the original value represents, you need to subtract date-time represented by its basis value (zero).
i saw mismatch e.g: in excel : 0:04:07 (real value behind is: 12:04:07 AM) after your function i get this: 0:04:06 (so 1 sec diffrence why is that?
I can not reproduce this issue. It is likely a rounding issue due too the limitations of floating point value representation.
Also, be advised that Excel supports two different date basis systems; the 1900 Date System (the default) and the 1904 Date System. The DateTime.FromOADate function does its conversion based on the 1900 Date System. The difference between these two systems is the date that is treated as zero. You should check the WorkBook.Date1904 property to see if you need to add addition days (1462 days) to the value retrieved from Excel when converting to a .Net DateTime.
This could effect the result of this code:
Dim dattime As DateTime = DateTime.FromOADate(data(row, 11))
See: Differences between the 1900 and the 1904 date system in Excel for more information.

Error: Date Type Conversion from String in VB .Net

For the following code, I am receiving this error: "Conversion from String "10/22.2014 12:00:00 A10" to type 'Date' is not valid." Note - in comparison to the code, below - the error message's conversion of AM to A10.
What I Am Trying To Do
I am trying to give a user the ability to query a database for transactions that occurred, today. In order to do this, I need to specify the timestamp for the transaction, i.e. MM/dd/yyyy timestamp. I have consulted the MSDN documentation; however, am unable to get my code to function, properly.
By default, Date objects appear to drop their timestamp (this may be a result of the code I am working with, e.g. the casting); therefore, when specifying a date range of "today" (Today's Data - Today's Date), I am left with the default behaviour of the object: Today's Date 12:00:00 AM - Today's Date 12:00:00 AM. Regardless as to why this is happening, this is the problem with which I am left.
The objective: MM/dd/yyyy 12:00:00 AM - MM/dd/yy 11:59:59 PM (the day being the same).
My goal is to force a particular timestamp for a Date object (note this is not a DateTime object). By specifyiong the time range, I am able to grab all data from a database for today.
What I've Got
Below, is the code and, below that, the description (I've tried to condense the code as much as possible). You'll also note that this is only half of the code, i.e. the FromDate portion (presumably the format can be replicated for the ToDate:
Public Shared Function ToFromDate(ByVal aValue As Object) As Date
Dim Result As Date
Try
Result = CDate(aValue)
Catch ex As Exception
Result = Now
End Try
Result = CDate(String.Format("{0:MM/dd/yyyy 12:00:00 AM}", Result))
Return Result
End Function
The above code takes as an argument a DateTime, e.g. 10\10\2010 12:15:63 PM (and, for the purposes of my problem, the timestamp is included). Again, I am trying to take that Date with timestamp and change the time. Result receives aValue, casting the object as Date to "ensure" it is a date.
After Result receives a value (as when declaring a Date it is initialized to #12:00:00 AM#, interestingly enough), I attempt to CDate() a formatted String object. I have also attempted to remove the second cast, yet still receive the same error (the Result = CDate(String...) line throwing the error).
Question(s)
The main question: how do I appropriately cast a date to include a specified time?
The second, trivial question: what's with the # surrounding the Date? Is this a SQL 'thing'?
Here's my work around for the above not working, so far:
Dim Result As Date
Dim DateString As String = CStr(aValue)
Dim TestDateString As String = DateString.Substring(0, DateString.IndexOf("/"))
Dim NewDateString As String = ""
If TestDateString.Length = 2 Then
NewDateString = DateString.Substring(0, 10)
Else
NewDateString = DateString.Substring(0, 8)
End If
NewDateString = NewDateString + " 12:00:00 AM"
NewDateString = CObj("#" + NewDateString + "#")
Result = CDate(NewDateString)
Return Result
First, a date is the number of ticks since a point in time. Formatting it to a string and then converting to a date does nothing but spin the wheels of your CPU.
Because of culture issues, you should always create dates using NEW DATE(?,?,?,etc)
Second, the # is a vb6 way of creating dates (and MS Access) that is there for backwards compatibility.
Third, If you have a date (no time or as of midnight), and you want it to be as of say 6AM, you simply add the time you want. IE:
Dim d As Date = New Date(2014,1,1)
d = d.AddHours(6)
'Result: d = 1/1/2014 6:00:00 AM
Lastly, if you have a date and time and you want to remove the time, there are many ways but this is the one I like:
Dim d As Date = Now
d = New Date(d.Year, d.Month, d.Day)

How to compare dateformat rather than using of time

How can I compare the last characters using of month, day, and year or the completedate rather than using datetime, Example case is Textbox3 is greater than textbox9 because Textbox3 day = 26 and textbox9 day = 25.
Mycode:
'in my case I have 2 Textbox.
'Date format: hh.mm MM/DD/YYYY
'Textbox3= 02.02 03/26/2014
'TextBox9= 21.01 03/25/2014
If Val(Strings.Left(TextBox9.Text.Trim, 5)) < Val(Strings.Left(Textbox3 .Text.Trim, 5))Then
TimeError.ShowDialog()
End If
Really, the fastest, most reliable, and most effective way to do this is to parse the values into a DateTime. And taking a step back from there, the fastest, most effective way to get a date time from a textbox is to use a DateTimePicker control.
But if that's not an option, we can build on the code I gave you last time:
Dim temp1() As String = Textbox3.Text.Trim().Split(" .".ToCharArray())
Dim temp2() As String = Textbox9.Text.Trim().Split(" .".ToCharArray())
If DateTime.Parse(temp2(2)) < DateTime.Parse(temp1(2)) Then
TimeError.ShowDialog()
End If
I'll add that you probably want to also have code to compare the time values in the case where the date portions are equal. Given this as a starting point, you should be able to write that code on your own.
in vb.net you can comopare dates like this:
dim date1 as date = cdate(Textbox1.text)
dim date2 as date = Date.now()
if date1.date=date2.date then ....
and months like this
if date1.month=date2.month then ...

VB.Net 2005, how can I subtract a date from the (current date minus 7 days) and produce a number of days?

I have a date in the future e.g. 13/10/2008 I need to subtract the current date (today is the 28/09/2010) minus 7 days, so thats 21/09/2010 minus 13/10/2008, which would equal erm, 720 something ?
But the current date won't always be 28/09/2010, obviously.
I need the code for this.
EDIT: When i said future I mean past :)
Sub Main()
Dim dt As DateTime = New DateTime(2008, 10, 13)
' be careful what you are subtracting from what
' the date you have is not in the future (year 2008)
' if the date is in the future: (dt.Subtract(DateTime.Now.AddDays(-7))).TotalDays
' or simply take the absolute value
Dim days As Double = (DateTime.Now.AddDays(-7).Subtract(dt)).TotalDays
Console.WriteLine(days)
End Sub
You will also notice that the TotalDays property is of type Double.
13/10/2008 is not exactly in the future :)
Sorry for using C# code, but:
(dateInFuture - DateTime.Now.AddDays(-7)).TotalDays
Should work. Of course the other way around if you mean in the past:
(DateTime.Now.AddDays(-7) - dateInPast).TotalDays
Dim ValidDate As Date =cDate("Tuesday, December 31, 2013") 'A date in Future
Dim date1 As New System.DateTime(ValidDate.Year, ValidDate.Month, ValidDate.Day)
Dim date2 = Now
Dim Diff1 As System.TimeSpan
Diff1 = date1.Subtract(date2)
Dim TotRemDays = (Int(Diff1.TotalDays))
MsgBox(TotRemDays)
"I need the code for this" seems a bit too much like "Plz give meh teh codez", and your "date in the future" seems a little bit in the past.
Anyway, you should investigate the relevant methods of the DateTime structure, in particular the Subtract method (both overloads, or in alternative its subtraction operator), and you should have a look at the TimeSpan structure too.
You could create a DateTime for the date of today, subtract a TimeSpan of 7 days to it, and then subtract such result to a DateTime representing your date in the future (or, if it is in the past, do the opposite). You'll get a TimeSpan representing the difference in time between the two dates, from which you can easily get the number of days using its Days property.
As other said, to do the first subtraction you can also use the AddDays method of the DateTime structure.

How would I find the closest valid date to one given as an invalid date string?

This issue stems from an accounting package that spits out text-based reports with rows of data having invalid dates, like February 31st or September 31st.
The reports are formatted with spaces and mono-spaced fonts. My goal is to parse out the data needed and generate a more formal report (SSRS).
What I am interested in fixing is the situation where a date is invalid and can't be directly converted into a DateTime struct. The date format from the report is MMM-dd-yy (e.g. Feb-30-10). I would like to convert the invalid date strings into the closest valid DateTime in the same month before showing them in the formal report. I've seen this done two ways in my time as a developer, both very poorly, so I want to come up with a simple way of doing it (if there isn't a built-in way I don't know about).
The first bad method I've seen(I can't believe I'm even showing you!):
Dim month As Integer = <Parse out the month from the bad date string>
Dim day As Integer = <Parse out the day from the bad date string>
Dim year As Integer = <Parse out the year from the bad date string>
Dim validDate As DateTime
While True
Try
validDate = New DateTime(year, month, day)
Exit While
Catch ex As ArgumentOutOfRangeException
day -= 1
End Try
End While
I hope I don't have to explain what I don't like about that method.
The second bad method:
Dim badDateString As String = <Current date string from text report>
Dim validDate As DateTime
If DateTime.TryParseExact(badDateString, "MMM-dd-yy", Nothing, Globalization.DateTimeStyles.None, validDate) Then
Return validDate
End If
badDateString = badDateString.Replace("31", "30")
' ... try the parse again, if still not valid, replace "30" with "29"
' ... try the parse again, if still not valid, replace "29" with "28"
These make for some sad code and me a sad developer.
I've been trying to think of a more efficient way of doing this. Any ideas?
EDIT:
I found a solution and have posted it, but I liked Guffa's answer more.
Reading the previous code, the last code is pretty much what I was going to suggest.
Here is a variation of the code:
Return New DateTime(year, month, Math.Min(day, DateTime.DaysInMonth(year, month)))
Here was the solution I discovered before Guffa answered. It takes the parts of a date (month, day, year), uses the number of days in that particular month/year combination to validate the incoming day part, and adjusts if necessary before constructing a new DateTime.
Dim validDate As DateTime
Dim dayMax As Integer = DateTime.DaysInMonth(year, month)
Dim newDay = day
If day > dayMax OrElse day < 1 Then
newDay = dayMax
End If
validDate = new DateTime(year, month, newDay)
Return validDate