Compare two dates but with current year - excel

I have a cell with a date:
30/04/1991
I need to make a compare with today's date, but with day and month of that cell, but with current year. But it isn't working.
I have the following:
MsgBox Format(Day(cell.Value) & "/" & Month(cell.Value) & "/" & Year(Now), "dd/mm/yyyy") < Format(Now, "dd/mm/yyyy")
The result is "30/04/2017 < 01/05/2017"
But msgbox result is "False". Which is wrong, given today's date as "01/05/2017"
What am I doing wrong?

To avoid issues with February 29th, you can compare just the month and date:
MsgBox Format(cell, "mmdd") < Format(Now, "mmdd")
Update
DatePart("y", Date) can be used to get the Day of year:
MsgBox DatePart("y", cell) < DatePart("y", Now)
Debug.Print DatePart("y", "2 28") // 59
Debug.Print DatePart("y", "2 29 16") // 60

I would recommend using DateDiff fuinction.
You can use Date instead of Now since you only need the date, and not the time.
If you use DateDiff you can keep the 2 values as Date variable, and instead of using DateValue with some & and "/", you can have a shorter and cleaner version DateSerial(Year(Date), Month(cell.Value), Day(cell.Value)).
Code:
MsgBox DateDiff("d", DateSerial(Year(Date), Month(cell.Value), Day(cell.Value)), Date) > 1
If you want to get also the number of days between these 2 dates:
MsgBox DateDiff("d", DateSerial(Year(Date), Month(cell.Value), Day(cell.Value)), Date)

I solved by myself with
MsgBox DateValue(Day(cell.Value) & "/" & Month(cell.Value) & "/" & Year(Now)) < DateValue(Date)

Related

vba excel datediff calculates different results

I am trying to calculate time difference in hours between two times.
But i am not getting the exspected result, as a matter of fact the same function
throws me two different results.
time between 14:22:00 and 22:57:48 should come as 8 hours 35 minutes and 48 sec.
However i get two different numbers.
If i store the value as a date i get 14:19:12
If i calculate in a msgbox on the go i get 8,5966...
Neither is correct, or maybe it is using some sort of format i am unaware of.
Screenshot shows both the msgbox and the storage test.
Also posted in exspected result.
Any suggestions?
Public Sub DDtest()
Dim EDay As Date
Dim ETime As Date
Dim DtgA As Date
EDay = Format(CDate(Replace(Worksheets("Data2020").Range("E2").Value, ".", "/")), "dd-mmm-yyyy")
ETime = Format(Worksheets("Data2020").Range("F2"), "hh:mm:ss")
DtgA = EDay + ETime
Dim EDay2 As Date
Dim ETime2 As Date
Dim DtgB As Date
EDay2 = Format(CDate(Replace(Worksheets("Data2020").Range("E3").Value, ".", "/")), "dd-mmm-yyyy")
ETime2 = Format(Worksheets("Data2020").Range("F3"), "hh:mm:ss")
DtgB = EDay2 + ETime2
Dim result As Date
result = Format(DateDiff("s", DtgA, DtgB) / (60 * 60), "hh:mm:ss")
MsgBox "Date 1:" & DtgA & vbNewLine & "Date 2:" & DtgB & vbNewLine & vbNewLine & DateDiff("s", DtgA, DtgB) / (60 * 60) & vbNewLine & result
End Sub
DateDiff("s", DtgA, DtgB) / (60 * 60) will return a decimal value, in this case is 8.59666666666667 hours
When you apply Format to convert it into hh:mm:ss, the value 8.59666666666667 is not being treated as hours. Excel thinks it's a decimal value that must be converted into date, and it's being treated as days.
In Excel, Dates are always numbers. Integer part is the date itself, while decimal part is time, a part of that day but not the day itself.
First day Excel can use is 01/01/1900 and numeric value is 1, 2 is 02/01/1900 and so on.
So Excel thinks 8.59666666666667 is 08/01/1900 14:19:12
If you divide those hours between 24, you will get the right result:
result = Format(DateDiff("s", DtgA, DtgB) / (60 * 60) / 24, "hh:mm:ss")
You get this:
Note the first value is decimal value and the second one is formatted as hh:mm:ss. But both of them show the same value, with different format.
UPDATE: Actually, if you force your dates values to make a difference of 8 and a half hours exactly, you will see perfectly how Excel works. Same value but with different format.
I've forced dates to be 12/12/2019 14:22:00 and 12/12/2019 22:52:00 and I get this:
Exactly 8 hours and a half, but first in decimal and second is format hh:mm:ss.
Why are you formatting before calculation? If cell value is date formatting doesn't meter.
date & time = 441040.598611111111111
Sub calcDatediff()
date1 = Worksheets("masterdata").Range("C11")
time1 = Worksheets("masterdata").Range("D11")
date2 = Worksheets("masterdata").Range("C12")
time2 = Worksheets("masterdata").Range("D12")
dtime1 = date1 + time1
dtime2 = date2 + time2
difftime = Format(dtime2 - dtime1, "HH:mm:ss", vbMonday, vbFirstFourDays)
End Sub

Day(Now) displaying January, 1900?

For whatever reason, everytime I try to use the Day(Now) function in VBA, it keeps displaying "1/9/1900". The Date function displays correctly, so I'm not sure what the issue here is.
Sub Test()
Dim datDay As Date
datDay = Day(Now)
MsgBox datDay
End Sub
Here's an image of the error.
The Day will be an integer somewhere between 1 and 31, depending on, well, the "day" part of the date returned by the DateTime.Now function.
The way dates are stored, they're essentially Double values, with the integer part being a number of days, and the decimal part being the time of day.
Debug.Print Format(CDate(0), "yyyy-mm-dd")
Output: 1899-12-30
We are June 10th, so the date value of 10 corresponds to January 9, 1900.
You want to store the value returned by Day, Month, and Year functions, into Long integer variables; not Date.
Dim datDay As Long
datDay = DateTime.Day(DateTime.Date) ' datDay is 10 because DateTime.Date is 2019-06-10.
Note: while unqualified Day, Date, Month, and Year (and others) functions work perfectly fine, it's probably a good idea to qualify them with the module they are declared in (VBA.DateTime), to avoid potentially confusing ambiguities, e.g. Date is both the name of a property of the DateTime module, and it's also a data type (Dim foo As Date), and the two have very different meanings.
Try:
Option Explicit
Sub Test()
Dim datDay As Date
datDay = Date
MsgBox "Whole date: " & datDay & vbNewLine & _
"Month: " & Month(Date) & " (" & Format(Date, "mmmm") & ")" & vbNewLine & _
"Day: " & Day(Date) & " (" & Format(Date, "dddd") & ")"
End Sub
Result:
Replace
datDay = Day(Now)
with
datDay = Day(Now())
Not sure if this will fix the problem, but =Day(Now()) works correctly when typed directly into a cell.
Your problem is datDay is typed as a Date. =Day(Now()) returns just 10, as today is June 10th. As a full Date value, this is 1/10/1900, since Excel indexes day 0 as 1/0/1900.

How to calculate business hours elapsed in excel

I need to calculate business hours elapsed in MS Excel. Here i have two dates, start and End date with respective timings. Some places i might not have end date and timings. Business hours are 7AM EST - 17 PM EST. how can i calculate number of business hours elapsed here ? (Excluding Weekends)
Tried "=IF(ISBLANK(P2),(NETWORKDAYS(O2,NOW())-1)*("17:00"-"7:00")+IF(NETWORKDAYS(NOW(),NOW()),MEDIAN(MOD(NOW(),1),"17:00","7:00"),"17:00")-MEDIAN(NETWORKDAYS(O2,O2)MOD(O2,1),"17:00","7:00"),(NETWORKDAYS(O2,P2)-1)("17:00"-"7:00")+IF(NETWORKDAYS(P2,P2),MEDIAN(MOD(P2,1),"17:00","7:00"),"17:00")-MEDIAN(NETWORKDAYS(O2,O2)*MOD(O2,1),"17:00","7:00"))", need to exclude holidays as well here.
You can split this into three components (fraction of first day, full workdays, fraction of last day)
Lets start with the middle part. Here you can use NETWORKDAYS and subtract the start and end date. I am assuming a start date in A1 and end date in B1. In order to exclude holidays you need to maintain a list of holidays in your sheet. The formula assumes that this list is in range C1:C10. The results is multiplied by 10 as there are 10 hours in your workday.
=MAX((NETWORKDAYS(A1,B1,C1:C10)-NETWORKDAYS(A1,A1,C1:C10)-NETWORKDAYS(B1,B1,C1:C10))*10,0)
For the fractions you will need to determine if the day itself is a holiday, we use the NETWORKDAYS function again as a factor which will be either 0 or 1. Now we only need to determine the hours to add for the day. Depending on the granularity you want you can consider hours, minutes or even seconds. I will use hours and minutes as a fraction (minutes/60 = hours).
For the first day you get
=MAX(17-MAX(HOUR(A1)+MINUTE(A1)/60,10),0)*NETWORKDAYS(A1,A1,C1:C10)
For the last day you get
=MAX(MIN(HOUR(B1)+MINUTE(B1)/60,17)-10,0)*NETWORKDAYS(B1,B1,C1:C10)
Putting it all together leaves us with:
=MAX(17-MAX(HOUR(A1)+MINUTE(A1)/60,10),0)*NETWORKDAYS(A1,A1,C1:C10)+MAX((NETWORKDAYS(A1,B1,C1:C10)-NETWORKDAYS(A1,A1,C1:C10)-NETWORKDAYS(B1,B1,C1:C10))*10,0)+MAX(MIN(HOUR(B1)+MINUTE(B1)/60,10)-10,0)*NETWORKDAYS(B1,B1,C1:C10)
I believe this UDF will do what you need.
It calculates the hours and returns it as a float, then you need to multiply that with 24 to get the hours.
Function workhours(startdate As Date, enddate As Date)
Opentime = "7:00"
Closetime = "17:00"
Fulldays = Int(enddate - startdate) - 1
DayOneHours = CDate(Year(startdate) & "-" & Month(startdate) & "-" & Day(startdate) & " " & Closetime) - startdate
BeforeOpen = CDate(Year(startdate) & "-" & Month(startdate) & "-" & Day(startdate) & " " & Opentime) - startdate
HoursDayOne = DayOneHours - BeforeOpen
If enddate < CDate(Year(enddate) & "-" & Month(enddate) & "-" & Day(enddate) & " " & Opentime) Then
HoursLastDay = 0
Else
HoursLastDay = enddate - CDate(Year(enddate) & "-" & Month(enddate) & "-" & Day(enddate) & " " & Opentime)
End If
workhours = Fulldays * (CDate(Closetime) - CDate(Opentime)) + HoursDayOne + HoursLastDay
End Function
Use it in Excel like:
=workhours(A1,B1)*24

How to find number of working days for a month?

In an Excel sheet I have a date (October,2018).
From this I have to populate start date and end date of that month and number of working days in another column.
the format you're looking for would be something like this: reference
Range("C5") = Format(date_example, "mmm-yy")
Try this
Sub DateTest()
'convert the cell to text format and prints the date
Range("C5").NumberFormat = "#"
Range("C5") = Format(#10/18/2018#, "mmm-yy")
'gets the no of days between two dates
MsgBox "No of days : " & DateDiff("d", #1/1/2019#, Date, vbMonday)
'gets the no of working days between two dates
MsgBox "No of working days : " & WorksheetFunction.NetworkDays(#1/1/2019#, Date)
End Sub

How to get current month?

I can't get the current month.
It seems very simple to get the current year and day, as tested with the following:
MsgBox Year(Date)
MsgBox Day(Date)
MsgBox Year(Now)
MsgBox Day(Now)
How is it possible to show the current month as either a number (1, 2 etc.) or a full name?
I could use TODAY() in a cell and convert that in VBA with something like CurrentMonth = MonthName(Month(Sheet1.Range("A1"))) but I would like to do this directly in VBA for Excel.
Try,
debug.print Format(Date, "mmm") 'Mar
debug.print Format(Date, "mmmm") 'March
debug.print Format(Date, "m") '3
debug.print Format(Date, "mm") '03
Month(Now)
Returns the index number associated with the current month.
Jeeped's code below is the most compact, but to give you an idea of how indexes work, the following code will return the month name based on the index returned:
Dim months(11) As String
months(0) = "Jan"
months(1) = "Feb"
months(2) = "Mar"
months(3) = "Apr"
months(4) = "May"
months(5) = "Jun"
months(6) = "Jul"
months(7) = "Aug"
months(8) = "Sep"
months(9) = "Oct"
months(10) = "Nov"
months(11) = "Dec"
Dim nowMonth As Integer
nowMonth = Month(Now)
For i = 0 To 11
If nowMonth = (i + 1) Then
MsgBox (months(i))
End If
Next
Found an easier solution to get the current Month Name
Just use MonthName(Month(Now)) and assign it to a string.
Month(Now) gives you the month number and MonthName() uses that number to display the current month
A really helpful and simple way is to combine the format function together with date.
Examples (assuming today is Oct 23, 2019):
To get current month as a number as in original question:
MsgBox Format(Date, "mm")
^ Will return: 10
To get current month as short text:
MsgBox Format(Date, "mmm")
^ Will return: Oct
To get current month with full text:
MsgBox Format(Date, "mmmm")
^ Will return: October
You can combine these with days and years as well.
Additional examples:
MsgBox Format(Date, "dd-mmm-yyyy")
^ Will return 23-Oct-2019
MsgBox Format(Date, "dddd-mmmm-dd-yyyy")
^ Will return: Wednesday-October-23-2019
This is creating a custom format, so you can rearrange the dd, mm, yyyy areas as you see fit, such as:
MsgBox Format(Date, "yyyy/mm/dd")
^ Will return: 2019/23/10
Here is the best way I have found to do it:
Sub getMonth()
'MsgBox DatePart("m", Date)
'MsgBox Evaluate("MONTH(""" & Date & """)")
'MsgBox VBA.DateTime.Month(Date)
MsgBox Format(Date, "mmmm")
End Sub
Below is how I found the previous month based on the current month name, the assignment to monthNum is the piece needed to solve your question.
month = "February"
'****'
monthNum = Application.Evaluate("=MONTH(1&" & Chr(34) & month & Chr(34) & ")") 'Returns month #
'****'
If monthNum = 1 Then
monthNum = 12
Else
monthNum = monthNum - 1
End If
month = MonthName(monthNum) 'Returns January

Resources