I need to write a function which will convert 2 string parameters to dates and
return true/false after comparing the dates.
I have tried to implement this requirment by writing below mentioned code
Function CompareDate(StringDate1 As String, StringDate2 As String) As Boolean
Dim Date1 As Date
Dim Date2 As Date
Date1 = CDate(StringDate1)
Date2 = CDate(StringDate2)
If Date1 > Date2 Then
CompareDate = True
Else
CompareDate = False
End If
End Function
Dim test As Boolean
test = CompareDate("03-Mar-2016 02:43 PST", "01-Mar-2016 11:33 PST")
But I am getting "Type Mismatch" error at this line Date1 = CDate(StringDate1).
Any idea what needs to be modified to fix the issue.
Note : My function also needs to consider time and time zone while comparing dates.
try cdate(split(StringDate1," ")(0)) and (1) will give you the time to check also, when date1=date2? or you can replace the PST part
The parse problem is with the presence of a timezone. There are a lot of ways to manage this date time depending on what your endgame is but the most straightforward is just to drop off the timezone and let CDATE parse it. In the following code I assume that a) all of your times are in PST and b) there is a timezone on the end of every date. If these assumptions are wrong, modifications are necessary. If essential, managing multiple time zones could be done by converting everything to one time zone and, if desired, tracking what time zone it came from. But I don't know of any standard VBA module that knows the time zones so that would need an array from you.
Function CompareDate(strDate1 As String, strDate2 As String) As Boolean
Dim Date1 As Date
Dim Date2 As Date
Date1 = CDate(Left(strDate1, InStrRev(strDate1, " ")))
Date2 = CDate(Left(strDate2, InStrRev(strDate2, " ")))
CompareDate = (Date1 > Date2)
End Function
Maybe you could construct the timezone vs UTC offset array from the table here but I don't have time to process it right now. Pretty straightforward once you construct that array.
i think it would help if you formatted the date before doing CDate.
dateX = format(StringDate1, "mm/dd/yyyy")
You can also try somethign like this
dateX = cdate(format(stringdate1,"mm/dd/yyyy") - see that how works.
I don't have anythignt to test it with. If worst comes to worst, instead of passing the StringDate1 as string, pass it as Date and should be all set then. No need to do CDate in that case.
Function CompareDate(StringDate1 As Date, StringDate2 As Date) As Boolean
and Wherever you call this function CompareDate....do CDate then.. as such...
Call CompareDates(cdate(stringdate1), cdate(stringdate2))
The date portion gives you an integer value referring to the date, and the time portion gives you a fractional value for the time. So just add the two such as (using #Nathan_Sav code):
cdate(split(StringDate1," ")(0)) + cdate(split(StringDate1," ")(1))
Give this a try:
Function CompareDate(StringDate1 As String, StringDate2 As String) As Boolean
Dim Date1, Date2
Date1 = Split(StringDate1, " ")
Date2 = Split(StringDate2, " ")
CompareDate = IIf(DateDiff("d", Date1(0), Date2(0) > 0 And DateDiff("n", Date1(1), Date2(1)) > 0), True, False)
End Function
Related
I'm working on a problem where I need to determine the total time my program takes to execute. First line of code needs to write the current "Start time" and last lines of code need to write the current "End time". Then I'm subtracting "Start time" - "End Time" = Total Time.
I'm confused how I would use the FORMAT() function within VBA on the value of C2 to convert into seconds? Is there an other function that would work better than FORMAT? Basically I'm confused about Excel's Date Serial values and what they represent.
Code is below
EDIT: Thanks for the responses everyone. Both answers below work for what I'm trying to do.
sub ExecutionTime()
Worksheets("Table").Range("A2").Value = Now()
'All my executable code goes here. It's a relatively small program compiling a table so it
runs very quick.
Worksheets("Table").Range("B2").Value = Now()
Worksheets("Table").Range("C2").Value = Worksheets("Table").Range("A2").Value - Worksheets("Table").Range("B2").Value
end Sub
Do not use a Date data member or the Now method to analyze run time of your program. Instead, the Timer function is the most appropriate solution as it returns a Single representing seconds. It will require no type conversion and yields a more accurate result than an integer amount of seconds.
Using LimaNightHawk's answer as a template as you should be storing these in local variables instead of writing directly to the worksheet.
Dim startTime as Single
startTime = Timer()
' Do stuff
Dim endTime as Single
endTime = Timer()
Dim runTime as Single
runTime = endTime - startTime
Results should be written at the end of the routine.
With Worksheets("Table")
.Range("A2").Value = startTime
.Range("B2").Value = endTime
.Range("C2").Value = runTime
End With
Documentation on the timer function
In the first line of your program get the date (no need to format):
Dim startTime as Date
startTime = Now()
At the end of your program, get the date again:
Dim endTime as Date
endTime = Now()
Then use the DateDiff
Dim timeInSeconds as long
timeInSeconds = DateDiff("s", startTime, endTime)
DateDiff() is what you are looking for. The "s" defines that you are looking for the difference in seconds.
Worksheets("Table").Range("C2").Value = DateDiff("s", Worksheets("Table").Range("A2").Value, Worksheets("Table").Range("B2").Value)
EDIT: http://www.likeoffice.com/28057/excel-date to learn more about working with dates and times in Excel VBA. It is important to understand that dates work differently within the context of VBA, and have their own unique set of syntax functions for manipulating.
2nd EDIT: A cleaner version of this would be:
StartDateTime = Now()
'Run Code
Worksheets("Table").Range("C2").Value = DateDiff("s", StartDateTime, Now())
There's a few ways you can use VBA to format cells / variables.
In no particular order, firstly you can format ranges with the NumberFormat property which can be applied like so:
Worksheets("Table").Range("C2").Value = Now()
Worksheets("Table").Range("C2").NumberFormat = "ss"
The other way is that you could format Now() using the Format() function:
Worksheets("Table").Range("C2").Value = Format(Now(), "ss")
See the documentation from Microsoft to implement different formats:
NumberFormat: http://msdn.microsoft.com/en-us/library/office/ff196401%28v=office.15%29.aspx
Format: http://msdn.microsoft.com/en-us/library/office/gg251755%28v=office.15%29.aspx
How i generally go about bragging my process time to user
Sub Process()
Dim startTime as Date
Dim endTime as Date
startTime = Now
'Logic for what your process must do
endTime = Now
MsgBox "Process completed in : " & Format(endTime - startTime, "hh:mm:ss")
End Sub
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)
I'm using VS 2013 and VB language
My task is to store a user entered date in the format mm/dd/yyyy
Dim date1 As String = Format("MM/dd/yyyy")
Dim date2 As Date
Dim date3 As Date
date1 = Console.ReadLine()
date2 = DateTime.Now
date3 = DateTime.Parse(date1)
Console.ReadLine()
I first tried entering the date as Dim date1 as Date, but entering it in mm/dd/yyyy is invalid format.
So I tried this method, and get the error "String was not recognized as a valid DateTime"
How can I format the entered date so that it will be recognized as a valid datetime?
Thanks
User cannot be forced to enter the date in the format that you expect (particularly on a console application). So your best line of action is trying to parse this date and inform your user that the input is invalid
Dim isValid = False
Dim dt As DateTime
While(Not isValid)
Console.WriteLine("Please enter a date in the format MM/dd/yyyy")
Dim input = Console.ReadLine()
isValid = DateTime.TryParseExact(input, "MM/dd/yyyy", _
CultureInfo.InvariantCulture, DateTimeStyles.None, dt)
End While
DateTime.TryParseExact is a method of the DateTime that tries to parse the input string accordingly to a format specified. If the string complies to the format required then the method returns true and the last parameter is set to the datetime resulting from the conversion. Otherwise the method return false without throwing an exception so you could take the appropriate measures (in this case request again the input)
All dates are stored in memory as dates, and do not actually have formats. The formats appear when you change the date into a string (i.e. with the Date.ToString() method).
I think the best option here is to use Date.Parse() with no arguments, so that the command-line will accept all date formats (be prepared to catch format exceptions), and then when you need to display the date back to the user, format it using a format string and the Date.ToString() method.
Code example follows:
Dim strDateFormat = "MM/dd/yyyy"
Dim date2 As Date
Dim date3 As Date
date2 = Now()
date3 = Date.Parse(Console.ReadLine())
Console.WriteLine(date3.ToString(strDateFormat))
P.S. As you have it written, the command input overwrites your formatting string, so your formatting string is effectively useless.
I'm trying to compare the difference between two times in the day. I'm getting time in UTC format. Do I have to convert DateTime to integer in order to get the difference and if yes how?
This is my code
Dim ct As DateTime = DateTime.UtcNow
Dim int_ct As Integer = Convert.ToInt32(ct)
MsgBox(ct + " | " + int_ct)
If (System.IO.File.Exists(System.IO.Path.GetTempPath.ToString + "\tempfile.data")) Then
Dim time As DateTime = System.IO.File.ReadAllText(System.IO.Path.GetTempPath.ToString + "\tempfile.data")
Dim int_time As Integer = Convert.ToInt32(time)
If ((int_ct - unlockedtime) < int_time) Then 'unlockedtime is Int variable
Return False
Else
Return True
End If
End If
You don't need to do any timezone conversion, just make sure that both date/time values are in the same timezone when you capture them (though I suppose it might be wise use to UtcNow in case the system timezone changes in-between your two measurements.
You don't need to convert values to Int32 to get the difference, just use the DateTime.Subtract method:
Dim old As DateTime = GetOldDateTime()
Dim now As DateTime = DateTime.UtcNow
Dim diff As TimeSpan = now.Subtract( old )
If diff.TotalSeconds > someSecondsValue Then
DoSomething()
End If
Have you tried Datetime.Compare(dt1,dt2)? Depending on how much detail you need this might work for you.
Here is more information on the function:
http://msdn.microsoft.com/en-us/library/system.datetime.compare.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
As Dai said you may want to compare difference, but if you just want the date difference you can use the following:
DateDiff(DateInterval.Minute, Date1, date2)
This returns the difference as an integer, you can set whatever date interval you require as the firt parameter.
I need to get a date field from MM/dd/yyyy to yyyy/MM/dd in vb.net but it should still be a date field afterward so that I can match it against a date in a database.
At the moment all I'm managing to do is to change it to a string in that format.
I tried this type of code which also did not work.
DateTime.Parse(yourDataAsAString).ToString("yyyy-MM-dd")
fromDeString = String.Format("{0:yyyy/MM/dd}", aDate)
fromDate = Format("{0:yyyy/MM/dd}", aDate)
Any help would be much apreciated, thanks
You're not understanding that a date object does not store the digits in any particular format. The only way to get the digits formatted in the order you want is to convert it to a string. Why do you need to compare them in a particular format? A date is a date no matter how it is formatted. 12/15/78 == 1978/12/15.
If you are not able to compare dates from the DB against a date object in VB, it is likely that the date you are comparing to in the database is being returned to you in string format, in which case you should covert it to a date object for comparison.
Dim sDate As String = "2009/12/15" 'Get the date from the database and store it as a string
Dim dDate As New Date(2009, 12, 15) 'Your date object, set to whatever date you want to compare against
Select Case Date.Compare(dDate, Date.Parse(sDate))
Case 0
'The dates are equal
Case Is > 0
'The date in the database is less
Case Is < 0
'The date in the database is greater
End Select
Here's a sample module demonstrating the functionality you desire.
Imports System.Globalization
Module Module1
Sub Main()
Dim culture As New CultureInfo("en-us", True)
Dim mmDDyy As String = "10/23/2009"
Dim realDate As Date = Date.ParseExact(mmDDyy, "mm/dd/yyyy", culture)
Dim yyMMdd As String = realDate.ToString("yyyy/MM/dd")
End Sub
End Module
Hope this helps.
Kind Regards
Noel
Your second should actually work. Instead just try:
dim chislo as date = date.now dim message As String = $"
Today`s Date: {String.Format("{0:dddd, dd/MM/yyyy}", Chislo)} "
MsgBox(message)