Compare string dates in vb.net - vb.net

Hi in my program i am converting the dates in string for my application purposes. I want to compare those strings to see if the dates have the appropriate difference between them. Example date1 = "07/02/2015 12:12:000" and date2 = "08/02/2015 16:15:000". How can i compare for starters only the year value without parsing the string to date. Thanks in advance.
I have tried with .Length -something but with no luck at all.

Convert to DateTime objects and then use the normal arithmetic operations to compare them.
dim d1 = DateTime.Parse(input1); // Use ParseExact or more control
dim d2 = DateTime.Parse(input2);
If d1.Year != d2.Year Then
' years do not match
End If
' or even...
If (d1 - d2).Days > 365 Then
// more than a year apart (modulo leap years)
End If
Meta comment: I know you said "without parsing", but unless you have a really good reason (and tell us) and sensible answer will be to parse: because it is much easier and far easier to get right.

Related

SSRS comparing dates in an expression

I have some basic expressions to highlight certain fields:
=IIF(Fields!Failure.Value > 0, "Red", "Transparent")
However, I have another field that contains dates in the following format:
22/08/2016 22/08/2016 - each field can contain multiple dates.
This is stored in SQL as a VARCHAR.
I need to run a similar expression in my report to achieve the following:
If the date is 1 day older than the date the report is run, highlight the field. If the date is greater than 1 day older, highlight the field a different colour.
I#m familiar with basic expressions, but I can't think of an easy way to obtain the current date, and then compare between the two.
As others have said, you really shouldn't be using hacks like this...
But, this should work for you:
=iif(Len(Replace(Replace(Fields!DateField.Value," ",""), Format(Today, "dd/MM/yyyy"),"")) = 0, "Transparent" ,iif(Len(Replace(Replace(Replace(Fields!DateField.Value," ",""), Format(Today, "dd/MM/yyyy"),""), Format(Today().AddDays(-1), "dd/MM/yyyy"),"")) = 0, "Green", "Red"))
Essentially, remove the joining character (in this case, space) and then replace all instances of the current date in the given format. If there are any characters left, you have a date that doesn't match today. Then take that value and repeat for any instances of yesterday.
Obviously this will fall down if your date formatting changes.
But then you already knew that comparing dates as strings was a bad idea, right...
You can use the Split function to generate an array of values. Of course, you'll still need to select one of those to test. The following may get you going again.
=Iif(
CDate(
Split(
"21/08/2016, 22/08/2016",
","
).GetValue(0)
) < Today,
"True",
"False"
)
If, however, you are dealing with a date string that can contain any number of dates and you to test all of them then a simple SSRS expression won't handle that. Fortunately we can use a bit of custom code.
Right-click the report background and select report properties. Click the 'Code' item and paste the following into code box
Public Function TestDate(DateString As String) As String
Dim DatesArray() As String = Split(DateString)
Dim ReturnValue As String = "Transparent"
For Each d As String In DatesArray
If Date.Parse(d) = DateAdd(DateInterval.Day, -1, Date.Today) Then
ReturnValue = "Red"
End If
If Date.Parse(d) < DateAdd(DateInterval.Day, -1, Date.Today) Then
ReturnValue = "DarkRed"
End If
Next
Return ReturnValue
End Function
Now change the expression as below
=Code.TestDate("21/08/2016 22/08/2016")
I've used Date.Today in the VB to restrict the comparison of the date to the day. If you wanted to be more precise ie: the exact time, use Date.Now instead

SQL Use Greater/Less Than with like and wildcards

I'm currently a bit stumped on how to implement a certain thing. Basically I have an embedded database(which really hates JOINs, performance-wise) and the requirement of adding a wildcard mechanism to a search field. Currently the search field allows the User to input a date and some amounts/revenues which is matched using something like:
SELECT * FROM table where date >= '{0}' AND date <= '{1}'
EDIT: This is due to the fact that a .NET adapter generates the SQL at runtime with various combinations of AND-clauses being possible. Could be the user inputs only a value for {0}, could be he only inputs one for {1}, could be he inputs both, could be he inputs none. Therefore BETWEEN sadly would fall flat unless I start some serious regexing.
I would like to use the keyword LIKE to implement something like:
SELECT * FROM table where date >= LIKE '{0}' AND date <= LIKE '{1}'
with {0} being something like "2015.01*"
I recognize that Date might be a bit much, but using stuff like amounts or revenues is this possible? If so, what's the right syntax? Google is not my friend on this...
Thanks for all your help in advance!
LIKE is doing a regular expression matching, so for example LIKE '%a' matches '1a', but also '2a'. From this it is quite clear that a >= LIKE '...' is not possible.
What you could do is build a string from the date, so that you have for example 'YYYYMMDD', then you could easily compare with LIKE 'YYYYMM%' or with >= 'YYYYMM'.
Still I do not understand why you don't just use the SELECT * FROM table where date >= '{0}' AND date <= '{1}' (or a variant of that query using between) that you already proposed.

SQL Query - Greater Than with Text Data Type

I've searched around and couldn't find an answer anywhere.
I'm querying a database that has stored numbers as a VARCHAR2 data type. I'm trying to find numbers that are greater than 1450000 (where BI_SO_NBR > '1450000'), but this doesn't bring back the results I'm expecting.
I'm assuming it's because the value is stored as text and I don't know any way to get around it.
Is there some way to convert the field to a number in my query or some other trick that would work?Hopefully this makes sense.
I'm fairly new to SQL.
Thanks in advance.
If the number is too long to be converted correctly to a number, and it is always an integer with no left padding of zeroes, then you can also do:
where length(BI_SO_NBR) > length('1450000') or
(length(BI_SO_NBR) = length('1450000') and
BI_SO_NBR > '1450000'
)
You can try to use like this:
where to_number(BI_SO_NBR) > 1450000
Assuming you are using Oracle database. Also check To_Number function
EDIT:-
You can try this(after OP commented that it worked):
where COALESCE(TO_NUMBER(REGEXP_SUBSTR(BI_SO_NBR, '^\d+(\.\d+)?')), 0) > 1450000
If you are talking about Oracle, then:
where to_number(bi_so_nbr) > 1450000
However, there are 2 issues with this:
1. if there is any value in bi_so_nbr that cannot be converted to a number, this can result in an error
2. the query will not use an index on bi_so_nbr, if there is one. You could solve this by creating a function based index, but converting the varchar2 to number would be a better solution.

Datevalue can't read december month

I work on a macro vba which manipulate different dates.
I have an incomprehensive error with Decembre. For exemple
DateValue("11-NOV-14")
return : 11/11/2014
DateValue("11-DEC-14")
return an error type '13'
I already try to put the string into a var and pass it to DateValue but same results.
Maybe i can get around this problem but i want to know why i have this mystic error.
Thanks for your help.
Your is a system-dependent problem. The month of November passes well because, in French, November = Novembre so "11-NOV-14" is equal to the English version.
However, "Décembre" is different because it has an accent on the second letter. In fact, on a French system, this will be ok:
a = DateValue("11-DéC-14")
while this will be not:
a = DateValue("11-DEC-14")
To avoid this problem and make the code "language-independent" (without asking the user to change the date formatting from the Control Panel), I think you should add a function that translate dates from string to date values:
Function MyDateValue(ByVal myDate As String) As Date
myDay = Left(myDate,2)
myMonth = Right(Left(myDate,6),3)
Select Case myMonth
Case "JAN":
myMonth = 1
'etc.
End Select
myYear = Right(myDate,2)
MyDateValue = DateSerial(myYear,myMonth,myDay)
End Function
So, you will be able to use myDateValue rather than DateValue and will make sure that it will work with your input data whatever will be the system language.

How can I return a substring based on CharIndex for starting and end points from a field in a table?

I've been working on this problem most of the morning and I think I have the solution mostly but I must have something wrong somewhere.
I have a table that keeps as a column a long html file.
I need to search that column and return a part of that html file in mssql but I do not have index numbers to use.
My query so far:
SELECT SUBSTRING(ColName, CHARINDEX('TxTStart', ColName), CHARINDEX('TxTEnd', ColName))
FROM htmlTable ht
WHERE ht.Date_ = '2009-01-01'
My thinking is that the length in this query will not be correct to obtain the whole substring from txtStart to TxtEnd.
Should I possibly use RTRIM, just take all the string and then cut off what I need after ?
Should the above actually work and I just have something else wrong?
Or am I completely off base here?
Thanks in advance for any help or hints.
The 3rd parameter is length, so you need to subtract the end and start to get the length. try this
SELECT SUBSTRING(ColName, CHARINDEX('TxTStart', ColName), CHARINDEX('TxTEnd', ColName) - CHARINDEX('TxTStart', ColName))
FROM htmlTable ht
WHERE ht.Date_ = '2009-01-01'