I use the following in my sort class when comparing date/time values.
This is the general idea. Maybe this will help.
ReDim astrData(lngLow To lngHigh - 1) ' Resize temp data array
strFmt = String$(28, 48) ' Twenty-eight zeroes
' Convert date and/or time
' CStr(CDec(CDbl(CDate("3/18/2006 6:18:46 AM")))) -> "38794.2630324074" (Date and time)
' CStr(CDec(CDbl(CDate("3/18/2006")))) -> "38794" (Date only)
' CStr(CDec(CDbl(CDate("6:18:46 AM")))) -> "0.263032407407407" (Time only)
For lngIndex = lngLow To (lngHigh - 1)
strTemp = CStr(CDec(CDbl(CDate(avntData(lngIndex))))) ' Create big number
astrData(lngIndex) = Left$(strTemp & strFmt, 28) ' Format fixed length big number
Next lngIndex ' ex: "38794.2630324074000000000000"
Select Case mlngSortDirection
Case eSort_Ascending
If StrComp(astrData(lngLow), astrData(lngHigh - 1), vbBinaryCompare) = 1 Then
SwapData avntData(lngLow), avntData(lngHigh - 1)
End If
Case eSort_Descending
If StrComp(astrData(lngLow), astrData(lngHigh - 1), vbBinaryCompare) = -1 Then
SwapData avntData(lngLow), avntData(lngHigh - 1)
End If
Yes, if efficience isn't a concern, you could use
strTemp = Format(CDec(CDbl(CDate(avntData(lngIndex)))), "00000000.#")
to avoid lexical disorder as described by Peter.
But why don't you simply do a If date1 > date2 then...
Have anything against speed and simplicity?
I found this piece of code by Karl Peterson. Works great. I have tested with random dates and/or times between 1800 to present. This should work for you.
ReDim adblData(lngLow To lngHigh - 1) ' Resize temp data array
For lngIndex = lngLow To (lngHigh - 1)
' Convert date and/or time to
' seconds prior to loading array
' ex: 12-May-1866 3:27:36 AM -> -3270573144 (date and time)
' 5/12/1866 -> -3270585600 (date only)
' 3:27:36 AM -> -2209149144 (time only)
adblData(lngIndex) = DateToSeconds(CDate(avntData(lngIndex)))
Next lngIndex
Do my sort comparison "if x > y", etc.
Private Function DateToSeconds(ByVal datDate As Date) As Double
I found this piece of code by hensa22 in the original reply to this thread. Works great. I have not tested it because there is not need to - the documentation says it works for any date which can be represented by a Date object. This will work for you, so why don't you use it?
Code:
var_d1 > var_d2
Now, your code still does not work properly. It may work for the dates you tested it with but it is not hard to find some dates it doesn't work for.
Suppose we had a list of events associated with the Star Trek universe. We want to sort these by date:
1947 - Quark, Rom and Nog crash land at Roswell and spark of all those alien rumours
2063 - Zephram Cochrane makes the first human warp flight in the Phoenix
2165 - Sarek, father of Spock, is born on Vulcan
(NB: I took these off Wikipedia - I'm not enough of a geek to know these! I just wanted some events in the near future...)
Approx seconds since 1st Jan 1970 (i.e. dblSeconds in your code):
1947 = -725824800
2063 = 2934856800
2165 = 6153732000
(all calculated by (year-1970)*365.25*86400)
Then after the Select statement they become:
1947 - this is negative so neither case fits, so result stays as -725824800
2063 - initial value is >= 2147483648 (BIT_31) so we subtract BIT_32 giving us -1360110496
2165 - initial value is >= 4294967296 (BIT_32) so we set it to 0
The final order (from low to high) will be 2063, 1947, 2165. I don't know how time works where you live but this doesn't seem correct to me somehow.
Why do you persist in giving an incorrect answer to a thread which was answered correctly in the very first reply?
Thanks for that correction dglienna. According to this link (http://msdn.microsoft.com/en-us/libr...(v=vs.60).aspx) the valid range is January 1, 1980 through December 31, 2099 (for Win95) or January 1, 1980 through December 31, 2079 (for WinNT). This doesn't affect my conclusions about Kenaso's code, though.
Anything which is more than 2147483648 seconds later than 1st Jan 1970, which is any date later than about 2038, will wrap around to negative values. So 2063 will still be considered earlier than 1980.
Karl has been coding for quite some time and is very respected in the Visual Basic world. Please take the time to read his article as it is very short and informative. Thank you.
Karl has been coding for quite some time and is very respected in the Visual Basic world. Please take the time to read his article as it is very short and informative. Thank you.
Karl's reputation is completely irrelevant here. Once you have a piece of code, whether it is correct or not does not depend upon the author's reputation. It depends solely upon whether, when you run it, it gives the correct answer.
But Karl is not actually at fault here. His code is a bit weird but serves the purpose he designed it for - which is to encode a VB Date as UNIX time in a Long variable, with dates from 1970 to 2038 being encoded as positive values and dates from 2038 to 2106 being encoded as negative values.
He provides two functions which convert back and forth between these, called NetTimeToVbTime() and VbTimeToNetTime().
His code works when used for the purpose for which it was written. But nowhere in that article does it say that you can determine which of two dates is earliest by encoding them using his function and then comparing the results using the < operator. This is what you are doing, though, so this is why the method you presented doesn't work.
Have you actually read and understood my walkthroughs of the DateToSeconds() function you posted? If you had then you would see exactly why it doesn't work for comparing dates.
To make it easy for you I have knocked up a little app. A screenshot of this is shown below. All you have to do is put a date in each text box and click the 'Compare!' button. It will then tell you whether the first date is considered to be earlier than the second date, using both the correct way to compare dates (the < operator) or the wrong way (comparing the values of DateToSeconds() for the two dates). Give it a go. If you still insist that your way of comparing dates is valid please tell me exactly what is wrong with this application.
Originally Posted by Kenaso
Star Trek??
I just needed a concrete example of why you might want to compare dates in the range ~1900 up to ~2100. A list of things in the Star Trek timeline was the first thing that came to mind for dates like these.
I'll just post the code here as well so people don't have to download the zip file if they just want to see it. The comparisons are highlighted in red:
Code:
Private firstDate As Date
Private secondDate As Date
Private Sub cmdCompare_Click()
' Set the dates from text boxes
firstDate = CDate(txtFirstDate.Text)
secondDate = CDate(txtSecondDate.Text)
CompareUsingLessThan (void)
CompareUsingDateToSeconds (void)
End Sub
Private Function CompareUsingLessThan(void)
If firstDate < secondDate Then
lblLessThanResult.Caption = "< operator says: Yes"
Else
lblLessThanResult.Caption = "< operator says: No"
End If
End Function
Private Function CompareUsingDateToSeconds(void)
If DateToSeconds(firstDate) < DateToSeconds(secondDate) Then
lblDateToSecondsResult.Caption = "DateToSeconds() says: Yes"
Else
lblDateToSecondsResult.Caption = "DateToSeconds() says: No"
End If
End Function
Private Function DateToSeconds(ByVal datDate As Date) As Double
' 16-Feb-2010 Karl E. Peterson http://vb.mvps.org/
Dim dblSeconds As Double
Const BASE_DATE As Date = #1/1/1970#
Const BIT_31 As Double = 2147483648#
Const BIT_32 As Double = 4294967296#
' Calculate difference in seconds between
' base date and date passed here
dblSeconds = CDbl(DateDiff("s", BASE_DATE, datDate))
Select Case dblSeconds
Case Is >= BIT_32: dblSeconds = 0
Case Is >= BIT_31: dblSeconds = dblSeconds - BIT_32
End Select
DateToSeconds = dblSeconds
End Function
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.