How to Calculate Two Different Dates like 2 years, 5 months - datetime

I want to calculate the difference between two dates and want to convert it like 2 years, 5 months or only 3 months, or 2 days according to the difference considering all months are 30 days...
For example;
From and including: Mar 12, 2009
To, but not including : Nov 26, 2011
The output must be : 2 years, 8 months, 14 days excluding the end date.
Another example;
Start: Jan 26, 2010
End: Feb 15, 2010
Output: 20 days from the start date to the end date, but not including the end date
I can calculate the difference as month, day or hour with Datediff but the question is how to convert it to years, months and dates. It's quite complicated actually as we don't know how many days there are between two months (30,31 maybe 28 days)
I use this Classic ASP code to convert the difference but there are lot's of disadvantages.
Function Convert_Date_to_Text(tarih1,tarih2,useDates)
if (tarih1<>"" AND tarih2<>"") then
if Tarih_Araligi_Belirle(tarih1,tarih2,"day")>0 then
Date1_Year = Year(tarih1)
Date1_Month = Month(tarih1)
Date1_Day = Day(tarih1)
Date2_Year = Year(tarih2)
Date2_Month = Month(tarih2)
Date2_Day = Day(tarih2)
If (Date1_Month = 12) and (Date1_Day = 31) and
(Date2_Month = 1) and (Date2_Day = 1) Then
NoOfyears = Date2_Year - Date1_Year - 1
NoOfmonths = 0
NoOfdays = 1
Else
NoOfyears = Date2_Year - Date1_Year
NoOfmonths = Date2_Month - Date1_Month
NoOfdays = Date2_Day - Date1_Day
End If
If NoOfyears = 1 Then
FormatString = "1 year "
Else If NoOfyears <= 0 then
FormatString = ""
Else
FormatString = CStr(NoOfyears) & " years "
End If:End If
If NoOfmonths = 1 Then
FormatString = FormatString & "1 month"
Else If NoOfmonths <= 0 then
FormatString = FormatString
Else
FormatString = FormatString & CStr(NoOfmonths) & " months "
End If:End If
if useDates=1 then
If NoOfdays = 1 Then
FormatString = FormatString & "1 day"
Else If NoOfdays <= 0 Then
FormatString = FormatString
Else
FormatString = FormatString & CStr(NoOfdays) & " days"
End If:End If
end if
end if
end if
Convert_Date_to_Text = FormatString
End Function
This web site calculates the difference perfectly. TimeAndDate.Com
Note: I'm using Classic ASP for several reasons (Company limitations). Sorry for this but I need an ASP function. It looks like TimeSpan doesn't exist in ASP :(
Kind Regards

If you can convert the input strings to DateTime variables, you can try something like this:
DateTime starTime = //something;
DateTime endTime = //something;
TimeSpan oneDay = new TimeSpan(1, 0, 0, 0); //creates a timespan of 1 day
TimeSpan deltaTime = (endTime - startTime) - oneDay;
I would asume asp has the DateTime and TimeSpan variable types.

Here's a function I have used in the past. If you test it, I think you'll find it accurate. Here's where I got it from.
Function YearsMonthsDays(Date1 As Date, Date2 As Date, Optional ShowAll As _
Boolean = False, Optional Grammar As Boolean = True)
' This function returns a string "X years, Y months, Z days" showing the time
' between two dates. This function may be used in any VBA or VB project
' Date1 and Date2 must either be dates, or strings that can be implicitly
' converted to dates. If these arguments have time portions, the time portions
' are ignored. If Date1 > Date2 (after ignoring time portions), the function
' returns an empty string
' ShowAll indicates whether all portions of the string "X years, Y months, Z days"
' are included in the output. If ShowAll = True, all portions of the string are
' always included. If ShowAll = False, then if the year portion is zero the year
' part of the string is omitted, and if the year portion and month portion are both
' zero, than both year and month portions are omitted. The day portion is always
' included, and if at least one year has passed then the month portion is always
' included
' Grammar indicates whether to test years/months/days for singular or plural
' By definition, a "full month" means that the day number in Date2 is >= the day
' number in Date1, or Date1 and Date2 occur on the last days of their respective
' months. A "full year" means that 12 "full months" have passed.
' In Excel, this function is an alternative to the little-known DATEDIF. DATEDIF
' usually works well, but can create strange results when a date is at month end.
' Thus, this formula:
' =DATEDIF(A1,B1,"y") & " years, " & DATEDIF(A1,B1,"ym") & " months, " &
' DATEDIF(A1,B1,"md") & " days"
' will return "0 years, 1 months, -2 days" for 31-Jan-2006 and 1-Mar-2006.
' This function will return "0 years, 1 month, 1 day"
Dim TestYear As Long, TestMonth As Long, TestDay As Long
Dim TargetDate As Date, Last1 As Date, Last2 As Date
' Strip time portions
Date1 = Int(Date1)
Date2 = Int(Date2)
' Test for invalid dates
If Date1 > Date2 Then
YearsMonthsDays = ""
Exit Function
End If
' Test for whether the calendar year is the same
If Year(Date2) > Year(Date1) Then
' Different calendar year.
' Test to see if calendar month is the same. If it is, we have to look at the
' day to see if a full year has passed
If Month(Date2) = Month(Date1) Then
If Day(Date2) >= Day(Date1) Then
TestYear = DateDiff("yyyy", Date1, Date2)
Else
TestYear = DateDiff("yyyy", Date1, Date2) - 1
End If
' In this case, a full year has definitely passed
ElseIf Month(Date2) > Month(Date1) Then
TestYear = DateDiff("yyyy", Date1, Date2)
' A full year has not passed
Else
TestYear = DateDiff("yyyy", Date1, Date2) - 1
End If
' Calendar year is the same, so a full year has not passed
Else
TestYear = 0
End If
' Test to see how many full months have passed, in excess of the number of full
' years
TestMonth = (DateDiff("m", DateSerial(Year(Date1), Month(Date1), 1), _
DateSerial(Year(Date2), Month(Date2), 1)) + IIf(Day(Date2) >= _
Day(Date1), 0, -1)) Mod 12
' See how many days have passed, in excess of the number of full months. If the day
' number for Date2 is >= that for Date1, it's simple
If Day(Date2) >= Day(Date1) Then
TestDay = Day(Date2) - Day(Date1)
' If not, we have to test for end of the month
Else
Last1 = DateSerial(Year(Date2), Month(Date2), 0)
Last2 = DateSerial(Year(Date2), Month(Date2) + 1, 0)
TargetDate = DateSerial(Year(Date2), Month(Date2) - 1, Day(Date1))
If Last2 = Date2 Then
If TestMonth = 11 Then
TestMonth = 0
TestYear = TestYear + 1
Else
TestMonth = TestMonth + 1
End If
Else
TestDay = DateDiff("d", IIf(TargetDate > Last1, Last1, TargetDate), Date2)
End If
End If
If ShowAll Or TestYear >= 1 Then
YearsMonthsDays = TestYear & IIf(TestYear = 1 And Grammar, " year, ", _
" years, ") & TestMonth & IIf(TestMonth = 1 And Grammar, " month, ", _
" months, ") & TestDay & IIf(TestDay = 1 And Grammar, " day", " days")
Else
If TestMonth >= 1 Then
YearsMonthsDays = TestMonth & IIf(TestMonth = 1 And Grammar, " month, ", _
" months, ") & TestDay & IIf(TestDay = 1 And Grammar, " day", " days")
Else
YearsMonthsDays = TestDay & IIf(TestDay = 1 And Grammar, " day", " days")
End If
End If
End Function

How about this? (no TimeSpan but not sure if classic asp compatible)
DateTime dateTime1 = new DateTime(2003,2,2);
DateTime dateTime2 = new DateTime(2001,1,1);
int daysDiff = dateTime1.Day - dateTime2.Day;
int monthsDiff = dateTime1.Month - dateTime2.Month;
int yearsDiff = dateTime1.Year - dateTime2.Year;
if (daysDiff < 0)
{
daysDiff += DateTime.DaysInMonth(dateTime1.Year, dateTime1.Month);
monthsDiff--;
}
if (monthsDiff < 0)
{
monthsDiff += 12;
yearsDiff--;
}
Console.WriteLine(daysDiff);
Console.WriteLine(monthsDiff);
Console.WriteLine(yearsDiff);

You can subtract DateTime objects to get a TimeSpan object:
DateTime startDate = GetStartDate();
DateTime endDate = GetEndDate();
TimeSpan duration = endDate - startDate;

This article includes a DateDiff class:
// ----------------------------------------------------------------------
public void DateDiffSample()
{
DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
Console.WriteLine( "Date1: {0}", date1 );
// > Date1: 08.11.2009 07:13:59
DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
Console.WriteLine( "Date2: {0}", date2 );
// > Date2: 20.03.2011 19:55:28
DateDiff dateDiff = new DateDiff( date1, date2 );
// differences
Console.WriteLine( "DateDiff.Years: {0}", dateDiff.Years );
// > DateDiff.Years: 1
Console.WriteLine( "DateDiff.Quarters: {0}", dateDiff.Quarters );
// > DateDiff.Quarters: 5
Console.WriteLine( "DateDiff.Months: {0}", dateDiff.Months );
// > DateDiff.Months: 16
Console.WriteLine( "DateDiff.Weeks: {0}", dateDiff.Weeks );
// > DateDiff.Weeks: 70
Console.WriteLine( "DateDiff.Days: {0}", dateDiff.Days );
// > DateDiff.Days: 497
Console.WriteLine( "DateDiff.Weekdays: {0}", dateDiff.Weekdays );
// > DateDiff.Weekdays: 71
Console.WriteLine( "DateDiff.Hours: {0}", dateDiff.Hours );
// > DateDiff.Hours: 11940
Console.WriteLine( "DateDiff.Minutes: {0}", dateDiff.Minutes );
// > DateDiff.Minutes: 716441
Console.WriteLine( "DateDiff.Seconds: {0}", dateDiff.Seconds );
// > DateDiff.Seconds: 42986489
// elapsed
Console.WriteLine( "DateDiff.ElapsedYears: {0}", dateDiff.ElapsedYears );
// > DateDiff.ElapsedYears: 1
Console.WriteLine( "DateDiff.ElapsedMonths: {0}", dateDiff.ElapsedMonths );
// > DateDiff.ElapsedMonths: 4
Console.WriteLine( "DateDiff.ElapsedDays: {0}", dateDiff.ElapsedDays );
// > DateDiff.ElapsedDays: 12
Console.WriteLine( "DateDiff.ElapsedHours: {0}", dateDiff.ElapsedHours );
// > DateDiff.ElapsedHours: 12
Console.WriteLine( "DateDiff.ElapsedMinutes: {0}", dateDiff.ElapsedMinutes );
// > DateDiff.ElapsedMinutes: 41
Console.WriteLine( "DateDiff.ElapsedSeconds: {0}", dateDiff.ElapsedSeconds );
// > DateDiff.ElapsedSeconds: 29
// description
Console.WriteLine( "DateDiff.GetDescription(1): {0}", dateDiff.GetDescription( 1 ) );
// > DateDiff.GetDescription(1): 1 Year
Console.WriteLine( "DateDiff.GetDescription(2): {0}", dateDiff.GetDescription( 2 ) );
// > DateDiff.GetDescription(2): 1 Year 4 Months
Console.WriteLine( "DateDiff.GetDescription(3): {0}", dateDiff.GetDescription( 3 ) );
// > DateDiff.GetDescription(3): 1 Year 4 Months 12 Days
Console.WriteLine( "DateDiff.GetDescription(4): {0}", dateDiff.GetDescription( 4 ) );
// > DateDiff.GetDescription(4): 1 Year 4 Months 12 Days 12 Hours
Console.WriteLine( "DateDiff.GetDescription(5): {0}", dateDiff.GetDescription( 5 ) );
// > DateDiff.GetDescription(5): 1 Year 4 Months 12 Days 12 Hours 41 Mins
Console.WriteLine( "DateDiff.GetDescription(6): {0}", dateDiff.GetDescription( 6 ) );
// > DateDiff.GetDescription(6): 1 Year 4 Months 12 Days 12 Hours 41 Mins 29 Secs
} // DateDiffSample

Dim intYears
Dim intMonths
Dim intDays
Dim strDate1
Dim strDate2
Dim strAnswer
strDate1 = "01/26/2010"
strDate2 = "02/15/2010"
intYears = DateDiff("yyyy",strDate1,strDate2)
intMonths = DateDiff("m",strDate1,strDate2)
intDays = DateDiff("d",strDate1,strDate2)
strAnswer = ""
if intYears > 0 then
strAnswer = strAnswer & CStr(intYears) & "years "
end if
if intMonths > 0 then
strAnswer = strAnswer & CStr(intMonths) & "months"
end if
if intDays > 0 then
strAnswer = strAnswer & CStr(intDays) & "days"
end if
Response.Write("The difference between these two dates is " & strAnswer)

Related

Access 2010 - Last Sunday in March & October

I have a series of dates, which are recorded in both BST and GMT (depending upon the time of year). I want them to all be in GMT but I can't work out how to get Access to return the last Sunday in March (when we switch from GMT to BST) and the last Sunday in October (when we switch back).
All help appreciated!
I'm working in Access 2010.
Thank you in advance.
You can use this generic function:
' Calculates the date of the occurrence of Weekday in the month of DateInMonth.
'
' If Occurrence is 0 or negative, the first occurrence of Weekday in the month is assumed.
' If Occurrence is 5 or larger, the last occurrence of Weekday in the month is assumed.
'
' If Weekday is invalid or not specified, the weekday of DateInMonth is used.
'
' 2016-06-09. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function DateWeekdayInMonth( _
ByVal DateInMonth As Date, _
Optional ByVal Occurrence As Integer, _
Optional ByVal Weekday As VbDayOfWeek = -1) _
As Date
Const DaysInWeek As Integer = 7
Dim Offset As Integer
Dim Month As Integer
Dim Year As Integer
Dim ResultDate As Date
' Validate Weekday.
Select Case Weekday
Case _
vbMonday, _
vbTuesday, _
vbWednesday, _
vbThursday, _
vbFriday, _
vbSaturday, _
vbSunday
Case Else
' Zero, none or invalid value for VbDayOfWeek.
Weekday = VBA.Weekday(DateInMonth)
End Select
' Validate Occurence.
If Occurrence <= 0 Then
Occurrence = 1
ElseIf Occurrence > 5 Then
Occurrence = 5
End If
' Start date.
Month = VBA.Month(DateInMonth)
Year = VBA.Year(DateInMonth)
ResultDate = DateSerial(Year, Month, 1)
' Find offset of Weekday from first day of month.
Offset = DaysInWeek * (Occurrence - 1) + (Weekday - VBA.Weekday(ResultDate) + DaysInWeek) Mod DaysInWeek
' Calculate result date.
ResultDate = DateAdd("d", Offset, ResultDate)
If Occurrence = 5 Then
' The latest occurrency of Weekday is requested.
' Check if there really is a fifth occurrence of Weekday in this month.
If VBA.Month(ResultDate) <> Month Then
' There are only four occurrencies of Weekday in this month.
' Return the fourth as the latest.
ResultDate = DateAdd("d", -DaysInWeek, ResultDate)
End If
End If
DateWeekdayInMonth = ResultDate
End Function
Then:
LastSundayMarch = DateWeekdayInMonth(DateSerial(Year(SomeDateOfYear), 3, 1), 5, vbSunday)
LastSundayOctober = DateWeekdayInMonth(DateSerial(Year(SomeDateOfYear), 10, 1), 5, vbSunday)
or as functions:
Public Function DateLastSundayMarch(ByVal DateOfYear As Date) As Date
DateLastSundayMarch = DateWeekdayInMonth(DateSerial(Year(DateOfYear), 3, 1), 5, vbSunday)
End Function
Public Function DateLastSundayOctober(ByVal DateOfYear As Date) As Date
DateLastSundayOctober = DateWeekdayInMonth(DateSerial(Year(DateOfYear), 10, 1), 5, vbSunday)
End Function
Now you can have expressions like:
=DateLastSundayOctober([SomeDateField])
to be used as ControlSource for a control or in the GUI query designer.
This will work:
Option Explicit
Function getLastSundayOfMarchOfThisYear() As Date
getLastSundayOfMarchOfThisYear = getLastSundayOfMonthOfThisYear(3)
End Function
Function getLastSundayOfOctoberOfThisYear() As Date
getLastSundayOfOctoberOfThisYear = getLastSundayOfMonthOfThisYear(10)
End Function
Private Function getLastSundayOfMonthOfThisYear(month As Long) As Date
Debug.Assert month >= 1 And month <= 12
Dim i As Long, _
tmpDate As Date, _
daysInMonth As Long
daysInMonth = Day(DateSerial(year(Date), month + 1, 1) - 1)
For i = daysInMonth To 1 Step -1
tmpDate = CDate(year(Date) & "-" & month & "-" & i)
If Weekday(tmpDate) = vbSunday Then
getLastSundayOfMonthOfThisYear = tmpDate
Exit Function
End If
Next
End Function

Require previous working day minus public holidays

I am newish to MS Access.
I require the equivalent formula from excel to mc access which will workout -1 day from my data-set less weekends/public holidays.
So this is what i use in excel atm: =WORKDAY(start date,days,[holidays])
Any help would be greatly appreciated.
There is no native function, but you can use this set of functions:
Option Explicit
' Common constants.
' Date.
Public Const DaysPerWeek As Long = 7
Public Const MaxDateValue As Date = #12/31/9999#
Public Const MinDateValue As Date = #1/1/100#
' Workdays per week.
Public Const WorkDaysPerWeek As Long = 5
' Average count of holidays per week maximum.
Public Const HolidaysPerWeek As Long = 1
' Adds Number of full workdays to Date1 and returns the found date.
' Number can be positive, zero, or negative.
' Optionally, if WorkOnHolidays is True, holidays are counted as workdays.
'
' For excessive parameters that would return dates outside the range
' of Date, either 100-01-01 or 9999-12-31 is returned.
'
' Will add 500 workdays in about 0.01 second.
'
' Requires table Holiday with list of holidays.
'
' 2015-12-19. Gustav Brock. Cactus Data ApS, CPH.
'
Public Function DateAddWorkdays( _
ByVal Number As Long, _
ByVal Date1 As Date, _
Optional ByVal WorkOnHolidays As Boolean) _
As Date
Const Interval As String = "d"
Dim Holidays() As Date
Dim Days As Long
Dim DayDiff As Long
Dim MaxDayDiff As Long
Dim Sign As Long
Dim Date2 As Date
Dim NextDate As Date
Dim DateLimit As Date
Dim HolidayId As Long
Sign = Sgn(Number)
NextDate = Date1
If Sign <> 0 Then
If WorkOnHolidays = True Then
' Holidays are workdays.
Else
' Retrieve array with holidays between Date1 and Date1 + MaxDayDiff.
' Calculate the maximum calendar days per workweek.
MaxDayDiff = Number * DaysPerWeek / (WorkDaysPerWeek - HolidaysPerWeek)
' Add one week to cover cases where a week contains multiple holidays.
MaxDayDiff = MaxDayDiff + Sgn(MaxDayDiff) * DaysPerWeek
If Sign > 0 Then
If DateDiff(Interval, Date1, MaxDateValue) < MaxDayDiff Then
MaxDayDiff = DateDiff(Interval, Date1, MaxDateValue)
End If
Else
If DateDiff(Interval, Date1, MinDateValue) > MaxDayDiff Then
MaxDayDiff = DateDiff(Interval, Date1, MinDateValue)
End If
End If
Date2 = DateAdd(Interval, MaxDayDiff, Date1)
' Retrive array with holidays.
Holidays = GetHolidays(Date1, Date2)
End If
Do Until Days = Number
If Sign = 1 Then
DateLimit = MaxDateValue
Else
DateLimit = MinDateValue
End If
If DateDiff(Interval, DateAdd(Interval, DayDiff, Date1), DateLimit) = 0 Then
' Limit of date range has been reached.
Exit Do
End If
DayDiff = DayDiff + Sign
NextDate = DateAdd(Interval, DayDiff, Date1)
Select Case Weekday(NextDate)
Case vbSaturday, vbSunday
' Skip weekend.
Case Else
' Check for holidays to skip.
' Ignore error when using LBound and UBound on an unassigned array.
On Error Resume Next
For HolidayId = LBound(Holidays) To UBound(Holidays)
If Err.Number > 0 Then
' No holidays between Date1 and Date2.
ElseIf DateDiff(Interval, NextDate, Holidays(HolidayId)) = 0 Then
' This NextDate hits a holiday.
' Subtract one day before adding one after the loop.
Days = Days - Sign
Exit For
End If
Next
On Error GoTo 0
Days = Days + Sign
End Select
Loop
End If
DateAddWorkdays = NextDate
End Function
' Returns the holidays between Date1 and Date2.
' The holidays are returned as a recordset with the
' dates ordered ascending, optionally descending.
'
' Requires table Holiday with list of holidays.
'
' 2015-12-18. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function DatesHoliday( _
ByVal Date1 As Date, _
ByVal Date2 As Date, _
Optional ByVal ReverseOrder As Boolean) _
As DAO.Recordset
' The table that holds the holidays.
Const Table As String = "Holiday"
' The field of the table that holds the dates of the holidays.
Const Field As String = "Date"
Dim rs As DAO.Recordset
Dim SQL As String
Dim SqlDate1 As String
Dim SqlDate2 As String
Dim Order As String
SqlDate1 = Format(Date1, "\#yyyy\/mm\/dd\#")
SqlDate2 = Format(Date2, "\#yyyy\/mm\/dd\#")
ReverseOrder = ReverseOrder Xor (DateDiff("d", Date1, Date2) < 0)
Order = IIf(ReverseOrder, "Desc", "Asc")
SQL = "Select " & Field & " From " & Table & " " & _
"Where " & Field & " Between " & SqlDate1 & " And " & SqlDate2 & " " & _
"Order By 1 " & Order
Set rs = CurrentDb.OpenRecordset(SQL, dbOpenSnapshot)
Set DatesHoliday = rs
End Function
' Returns the holidays between Date1 and Date2.
' The holidays are returned as an array with the
' dates ordered ascending, optionally descending.
'
' The array is declared static to speed up
' repeated calls with identical date parameters.
'
' Requires table Holiday with list of holidays.
'
' 2015-12-18. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function GetHolidays( _
ByVal Date1 As Date, _
ByVal Date2 As Date, _
Optional ByVal OrderDesc As Boolean) _
As Date()
' Constants for the arrays.
Const DimRecordCount As Long = 2
Const DimFieldOne As Long = 0
Static Date1Last As Date
Static Date2Last As Date
Static OrderLast As Boolean
Static DayRows As Variant
Static Days As Long
Dim rs As DAO.Recordset
' Cannot be declared Static.
Dim Holidays() As Date
If DateDiff("d", Date1, Date1Last) <> 0 Or _
DateDiff("d", Date2, Date2Last) <> 0 Or _
OrderDesc <> OrderLast Then
' Retrieve new range of holidays.
Set rs = DatesHoliday(Date1, Date2, OrderDesc)
' Save the current set of date parameters.
Date1Last = Date1
Date2Last = Date2
OrderLast = OrderDesc
Days = rs.RecordCount
If Days > 0 Then
' As repeated calls may happen, do a movefirst.
rs.MoveFirst
DayRows = rs.GetRows(Days)
' rs is now positioned at the last record.
End If
rs.Close
End If
If Days = 0 Then
' Leave Holidays() as an unassigned array.
Erase Holidays
Else
' Fill array to return.
ReDim Holidays(Days - 1)
For Days = LBound(DayRows, DimRecordCount) To UBound(DayRows, DimRecordCount)
Holidays(Days) = DayRows(DimFieldOne, Days)
Next
End If
Set rs = Nothing
GetHolidays = Holidays()
End Function

Conversion of DateTime to relative time

The following code does not seem to work correctly when comparing DateTimes under certain circumstances.
For example, when the comparison DateTime is less than 24 hours, the function will return the incorrect minutes. Is there a better way to approach this?
Public Function GetElapsedTimeAsString(givenDate As DateTime) As String
Return ConvertTimeSpanToTotalAgo(DateTime.Now.Subtract(givenDate))
End Function
Private Shared Function ConvertTimeSpanToTotalAgo(diffDate As TimeSpan) As String
Dim d As New StringBuilder()
If diffDate.Days > 0 Then
d.AppendFormat("{0} Day ago ", diffDate.Days)
ElseIf diffDate.Minutes > 0 Then
d.AppendFormat("{0} Minutes ago ", diffDate.Minutes)
ElseIf diffDate.Seconds > 0 Then
d.AppendFormat("{0} Seconds ago ", diffDate.Seconds)
ElseIf diffDate.Milliseconds > 0 Then
d.AppendFormat("Just Now", diffDate.Milliseconds)
End If
Return d.ToString()
End Function
If the number of days, minutes, seconds and milliseconds is zero, and the number of hours is nonzero, it'll report nothing, i.e. an empty string. You need to add
If diffDate.Hours > 0 Then
d.AppendFormat("{0} Hours ago ", diffDate.Hours
at the very least.
Maybe deal with pluralisation as well: you're mixing plural and singular, e.g.
If diffDate.Hours > 0 Then
Dim text = If (diffDate.Hours > 1, "Hours", "Hour")
d.AppendFormat("{0} {1} ago ", diffDate.Hours,text
Apologies if this doesn't build - I'm from a C# background, and was looking for a VB.NET equivalent to the ternary operator.
The following function will properly display the elapsed Days, Hours, Minutes, Seconds, and optionally Milliseconds between two DateTimes.
MessageBox.Show("Completed in " & GetElapedTimeDescription(DateTime.Now, DateTime.Now.AddDays(5).AddHours(1).AddMinutes(3).AddSeconds(1)) & ".")
displays: "Completed in 5 Days, 1 Hour, 3 Minutes, 1 Second."
Private Shared Function GetElapedTimeDescription(ByVal startTime As DateTime, ByVal endTime As DateTime, Optional ByVal includeMilliseconds As Boolean = False) As String
Dim ts As TimeSpan = endTime - startTime
Dim elapsed As New System.Text.StringBuilder(100)
If startTime > endTime Then
ts = startTime - endTime
End If
If ts.Days > 0 Then
elapsed.AppendFormat("{0} Day{1}, ", ts.Days, If(ts.Days > 1, "s", ""))
End If
If ts.Hours > 0 Then
elapsed.AppendFormat("{0} Hour{1}, ", ts.Hours, If(ts.Hours > 1, "s", ""))
End If
If ts.Minutes > 0 Then
elapsed.AppendFormat("{0} Minute{1}, ", ts.Minutes, If(ts.Minutes > 1, "s", ""))
End If
If ts.Seconds > 0 Then
elapsed.AppendFormat("{0} Second{1}, ", ts.Seconds, If(ts.Seconds > 1, "s", ""))
End If
If includeMilliseconds Then
If ts.Milliseconds > 0 Then
elapsed.AppendFormat("{0} Millisecond{1}, ", ts.Milliseconds, If(ts.Milliseconds > 1, "s", ""))
End If
End If
If elapsed.ToString() = "" Then
elapsed.Append("Less than 1 Second")
End If
If elapsed.ToString().EndsWith(", ") Then
elapsed.Remove(elapsed.Length - 2, 2)
End If
Return elapsed.ToString()
End Function

How long time till a Weekday or a Date

I want to find out how long time there is till a specific Weekday from Now.
I have searched everywhere, but can't really find anything.
I THINK I have to use the DateDiff-function together with the WeekDay-function somehow.
The scenario is:
I have variable varWeekDay with the day of the week, ex: 1 / 2 / 3 / 4 / 5 / 6 / 7
And another variable varStartTime with a time of the day: hh:mm
And the last variable varStopTime also with a time of the day: hh:mm
if varWeekday = Weekday(now, 2) and varStartTime < formatdatetime(now, 4) then
.... Write how long time till start in hours / minutes
elseif varWeekday = Weekday(now, 2) and varStartTime >= formatdatetime(now, 4) and varStopTime < formatdatetime(now, 4) then
response.write("Already started!")
else
.... Write how long time till start in days / hours / minutes
end if
"How long time" could be like: "2 days, 3 hours and 27 minutes from now"
The same output should be generated from a specific datetime. Ex: 06/08/2012 23:55 is "1 day and 13 minutes from now"
I really hope you guys can help! :)
I didn't fully understand what you needed with the start time and end time, but this script will tell you how much time there is between now and the start of a specific day of the week.
<%
Dim varNow : varNow = Now()
Dim varWeekday : varWeekday = 7 'This is the weekday to look for (1 is Sunday, 7 is Saturday)
'This next line sets the time to the start of the day
Dim varThisDate : varThisDate = DateSerial(Year(varNow), Month(varNow), Day(varNow))
Dim varThisWeekday
Do
varThisDate = DateAdd("d", 1, varThisDate)
varThisWeekday = Weekday(varThisDate)
If varThisWeekday = varWeekday Then
Exit Do
End If
Loop
'These next lines just convert and display the remaining time into the different units
Response.Write("Until next " & WeekdayName(varWeekday) & "<br />")
Dim varSeconds : varSeconds = DateDiff("s", varNow, varThisDate)
Dim varDays : varDays = Int(varSeconds / 60 / 60 / 24)
varSeconds = varSeconds - (varDays * 24 * 60 * 60)
Dim varHours : varHours = Int(varSeconds / 60 / 60)
varSeconds = varSeconds - (varHours * 60 * 60)
Dim varMinutes : varMinutes = Int(varSeconds / 60)
varSeconds = varSeconds - (varMinutes * 60)
Response.Write("Days: " & varDays & "<br />")
Response.Write("Hours: " & varHours & "<br />")
Response.Write("Minutes: " & varMinutes & "<br />")
Response.Write("Seconds: " & varSeconds & "<br />")
%>

Relative date/time for classic ASP

Does anyone have a relative date/time from now to a natural/human for classic ASP function in VBScript? This is like Twitter.
Examples:
Less than 1 minute ago
About 5 minutes ago
About an hour ago
About 3 hours ago
Yesterday
Wednesday
etc.
This is the one I use. Pretty certain I just ripped it from Jeff's example that he used for this site.
Yes, yes I did: How can I calculate relative time in C#?
Function RelativeTime(dt)
Dim t_SECOND : t_SECOND = 1
Dim t_MINUTE : t_MINUTE = 60 * t_SECOND
Dim t_HOUR : t_HOUR = 60 * t_MINUTE
Dim t_DAY : t_DAY = 24 * t_HOUR
Dim t_MONTH : t_MONTH = 30 * t_DAY
Dim delta : delta = DateDiff("s", dt, Now)
Dim strTime : strTime = ""
If (delta < 1 * t_MINUTE) Then
If delta = 0 Then
strTime = "just now"
ElseIf delta = 1 Then
strTime = "one second ago"
Else
strTime = delta & " seconds ago"
End If
ElseIf (delta < 2 * t_MINUTE) Then
strTime = "a minute ago"
ElseIf (delta < 50 * t_MINUTE) Then
strTime = Max(Round(delta / t_MINUTE), 2) & " minutes ago"
ElseIf (delta < 90 * t_MINUTE) Then
strTime = "an hour ago"
ElseIf (delta < 24 * t_HOUR) Then
strTime = Round(delta / t_HOUR) & " hours ago"
ElseIf (delta < 48 * t_HOUR) Then
strTime = "yesterday"
ElseIf (delta < 30 * t_DAY) Then
strTime = Round(delta / t_DAY) & " days ago"
ElseIf (delta < 12 * t_MONTH) Then
Dim months
months = Round(delta / t_MONTH)
If months <= 1 Then
strTime = "one month ago"
Else
strTime = months & " months ago"
End If
Else
Dim years : years = Round((delta / t_DAY) / 365)
If years <= 1 Then
strTime = "one year ago"
Else
strTime = years & " years ago"
End If
End If
RelativeTime = strTime
End Function
taken from ajaxed
'here comes some global helpers...
public function sayDate(dat, mode, relativNotation)
if not isDate(dat) then
sayDate = "unknown"
exit function
end if
if relativNotation then
diff = dateDiff("s", dat, now())
if diff <= 10 and diff >= 0 then
sayDate = "Just now" : exit function
elseif diff < 60 and diff >= 0 then
sayDate = diff & " seconds ago" : exit function
elseif diff = 60 and diff >= 0 then
sayDate = diff & " minute ago" : exit function
elseif diff <= 1800 and diff >= 0 then
sayDate = int(diff / 60) & " minutes ago" : exit function
elseif diff < 86400 and diff >= 0 then
sayDate = plural(int(diff / 60 / 60), "hour", empty) & " ago"
else
if datevalue(dat) = date() then
sayDate = "Today"
elseif dateValue(dat) = dateAdd("d", 1, date()) then
sayDate = "Tomorrow"
elseif dateValue(dat) = dateAdd("d", -1, date()) then
sayDate = "Yesterday"
end if
end if
end if
if relativNotation and lCase(mode) = "datetime" and isEmpty(sayDate) then
diff = dateDiff("d", dat, now())
sayDate = plural(diff, "day", empty) & " ago"
exit function
end if
if isEmpty(sayDate) then
sayDate = day(dat) & ". " & monthname(month(dat), true)
if year(dat) <> year(now()) then sayDate = sayDate & " " & year(dat)
end if
if lCase(mode) <> "datetime" then exit function
if uBound(split(dat, " ")) <= 0 then exit function
'sayDate = sayDate & ", " & str.padLeft(hour(dat), 2, "0") & ":" & str.padLeft(minute(dat), 2, "0")
end function
public function plural(val, singularform, pluralform)
plural = singularform
if val <> 1 then plural = pluralform
if isEmpty(plural) then plural = singularform & "s"
plural = val & " " & plural
end function
I write my own function like this, could be found at http://asp.web.id/asp-classic-relative-date-function.html
it is used conversion asp date to unixtimestamp format and calculate the time margin. it is customizable you could also create relative date for upcoming date using this function.
DateAdd("n", -1, Now)
DateAdd("n", -5, Now)
DateAdd("h", -1, Now)
DateAdd("h", -3, Now)
DateAdd("d", -1, Date)
DateAdd("d", -1, Date)
Not sure about what you mean by Wednesday part.
Can you elaborate?

Resources