SSRS exact month difference - date

This may have been asked before but I've not been able to find it having searched! In Oracle SQL there's a function called MONTHS_BETWEEN which returns a fractional value if the two dates you are comparing are not both the first day of the month for example. I need to do something similar in SSRS report builder, I've tried using DateDiff("m",Date1,Date2) however this always returns an integer and I think from what I can tell it just compares the two months from the dates, so when I compare 30/09/20 and 01/04/21 I get 7 months when actually it is much closer to 6.
Is there a function or a fix that can be used in SSRS to get that more accurate value?
Thank you!
For example I would like to get the following result:
Difference between 30/09/20 and 01/04/21 = 6.1
Difference between 01/08/20 and 30/09/20 = 1.9
It doesn't have to super accurate as I will be rounding to the nearest integer but I'm looking for something that will recognise that in the second example nearly 2 months have been covered and in the first example it's only just over 6 months.

If you only need an approximation then you could just calculate the number of days difference and divide by 30.
using the following expression...
=DATEDIFF("d", Fields!startDate.Value, Fields!endDate.Value)/30
I put a few more examples into a table and got the following results.

The following code mimics oracle definition of months_between
Public Function MonthsBetween( d1 As Date, d2 As Date) As Decimal
Dim df As Decimal
df = DateDiff("m", d1, d2)
If Day(d1) <> Date.DaysInMonth(Year(d1), Month(d1)) Or Day(d2) <> Date.DaysInMonth(Year(d2), Month(d2)) Then
df = df + Cdec((Day(d2)-Day(d1))/31)
End If
Return df
End Function
Integer result when both dates are last day of month
Negative result when date1 > date2
Decimal part based on 31 days month
For your expression use something like
=Code.MonthsBetween(Fields!date1.Value , Fields!date2.Value)
UPDATE
The following expression works in the same manner
= Cdec(
DateDiff("m", Fields!date1.Value, Fields!date2.Value)
+
Iif (
Day(Fields!date1.Value) <> Date.DaysInMonth(Year(Fields!date1.Value), Month(Fields!date1.Value)) Or
Day(Fields!date2.Value) <> Date.DaysInMonth(Year(Fields!date2.Value), Month(Fields!date2.Value)) ,
Cdec( (Day(Fields!date2.Value) - Day(Fields!date1.Value))/31),
0.0
)
)

Related

DAX Calculate Billing Days Between Two Variable Dates

I have a dimdate table that is represented below. I have each day flagged as BusinessDay Y/N. I also have a DimSalesRep table that has a daily goal for each rep. I want to be able to allow users to input a StartDt and EndDt with filters on the report and have a calculated column look at the business days between those dates. I can calculate daysbetween with defined dates but I am unsure how I would use DAX with variable dates that are applied through Report filters.
I should also note I am not sure how best to handle a startdt and enddt filter based of the column, TheDate
Cheers!
Reference your dimdate table twice
StartDate = 'dimdate'
EndDate = 'dimdate'
and use this measure:
Num BusinessDays =
CALCULATE(
COUNTROWS('dimdate'),
'dimdate'[BusinessDay] = "Y",
'dimdate'[Date] >= SELECTEDVALUE(StartDate[Date]),
'dimdate'[Date] <= SELECTEDVALUE(EndDate[Date])
)

Sum values associated with a date equal to or less than today in Google Sheets [duplicate]

This question already has an answer here:
How to compare dates or date against today with query on google sheets?
(1 answer)
Closed 5 months ago.
So I have a table that looks like this:
date
goal
10/1/2022
10000
10/2/2022
10000
10/3/2022
10000
10/4/2022
10000
10/5/2022
10000
10/6/2022
10000
I would like to create a formula that Sums the goal column for the dates less than or equal to the current day. I currently have this:
=query(A4:B1000, "select SUM(B) WHERE A <= today()")
But this is throwing the following error: Unable to parse query string for Function QUERY parameter 2: PARSE_ERROR: Encountered " "(" "( "" at line 1, column 31. Was expecting one of: <EOF> "group" ... "pivot" ... "order" ... "skipping" ... "limit" ... "offset" ... "label" ... "format" ... "options" ... "and"
Any thoughts on how to proceed would be helpful. Thanks!
This is a typical use case for SUMIF, which will sum values in a range that meet a condition (a condition on that same range, or on a corresponding range):
=sumif(A4:A1000,"<="&TODAY(),B4:B1000)
will sum the values in B4:B1000 for which the corresponding value in A4:A1000 is less than or equal to today.
Or you can still use a query if you prefer as long as you get the right syntax - see this for example.
=query(A2:B1000, "select SUM(B) WHERE A <= date '"& text(today(),"yyyy-mm-dd")&"'")
Dates in my locale are in dd/mm/yyyy format so 6/10/2022 is tomorrow at time of writing.

DateDiff not available on Access 2013

I am trying to use the so called DateDiff function to subtract the End Date from the Start Date and obtain the numbers of days apart.For example:
10/11/1995 - 7/11/1995 = 3 (extract the 'dd' from DD/MM/YYYY format)
As date values are double with the integer part counting for a day, you can use this simple expression:
[Due Date]-[Start Date]
or, for integer days only:
Fix([Due Date]-[Start Date])
That said, you should a query for tasks like this.

What is the Impala SQL equivalent function of NEXTDAY in Netezza?

I have a SELECT statement that I am trying to convert from Netezza SQL to Impala SQL. The output looks something like 140612, which is a date that is obtained by subtracting 7 from the current date and then pulling out the monday of that week.
I need to have this readable for Impala, then format it, then turn it into a string.
The query is :
TO_CHAR(next_day(DATE(a.date)-7, 'Monday'), 'YYMMDD') AS START_DATE
Assuming a.date is a timestamp, and T is the day of the week (1 = Sunday, 7 = Saturday; for your example above, Monday = 2, so T = 2) you should be able to use use
date_add(a.date, 7 - pmod(dayofweek(a.date) - T, 7));
in place of next_day in the above query. Check out the documentation on Impala's built-in date and time functions for more detail.

Quartz .Net - Meaning of BigInt DateTime

we've used sql server as our persisted data store for Quartz.net. I'd like to write some queries looking # the Time values. Specifically - Qrtz_Fired_Triggers.Fired_Time, Qrtz_Triggers.Next_fire_time, Prev_fire_time.
For the life of me, I can't find anything that says what this data is - ticks, milliseconds, microseconds, nanoseconds. I've guessed at a couple of things, but they've all proven wrong.
The best answer would include the math to convert the big int into a datetime and perhaps even a link(s) to the pages/documentation that I should have found - explaining the meaning of the data in those fields.
If you have specific instructions on using Quartz .Net libraries to view this information, that would be appreciated, but, I really have 2 goals - to understand the meaning of the date/time data being stored and to keep this in T-SQL. If I get the one, I can figure out T-SQL or out.
On the SQL side, you can convert from Quartz.NET BIGINT times to a DateTime in UTC time with:
SELECT CAST(NEXT_FIRE_TIME/864000000000.0 - 693595.0 AS DATETIME) FROM QRTZ_TRIGGERS
Numbers Explanation
Values stored in the column are the number of ticks from .NET DateTime.MinValue in UTC time. There are 10000 ticks per millisecond.
The 864000000000.0 represents the number of ticks in a single day. You can verify this with
SELECT DATEDIFF(ms,'19000101','19000102')*10000.0
Now, if we take March 13, 2013 at midnight, .NET returns 634987296000000000 as the number of ticks.
var ticks = new DateTime(2013, 3, 13).Ticks;
To get a floating point number where whole numbers represent days and decimal numbers represent time, we take the ticks and divide by the number of ticks per day (giving us 734939.0 in our example)
SELECT 634987296000000000/(DATEDIFF(ms,'19000101','19000102')*10000.0)
If we get put the date in SQL and convert to a float, we get a different number: 41344.0
SELECT CAST(CAST('March 13, 2013 0:00' AS DATETIME) AS FLOAT)
So, we need to generate a conversion factor for the .NET-to-SQL days. SQL minimum date is January 1, 1900 0:00, so the correction factor can be calculated by taking the number of ticks for that time (599266080000000000) and dividing by the ticks per day, giving us 693595.0
SELECT 599266080000000000/(DATEDIFF(ms,'19000101','19000102')*10000.0)
So, to calculate the DateTime of a Quartz.NET date:
take the value in the column
divide by the number of ticks per day
subtract out the correction factor
convert to a DATETIME
SELECT CAST([Column]/864000000000.0 - 693595.0 AS DATETIME)
The value stored in database is the DateTime.Ticks value. From MSDN:
A single tick represents one hundred
nanoseconds or one ten-millionth of a
second. There are 10,000 ticks in a
millisecond.
The value of this property represents
the number of 100-nanosecond intervals
that have elapsed since 12:00:00
midnight, January 1, 0001, which
represents DateTime.MinValue. It does
not include the number of ticks that
are attributable to leap seconds.
So, unless I missed something and am making this too complicated, I couldn't get the dateadd functions in Ms Sql Server 2008 to handle such large values and I kept getting overflow errors. The approach I took in Ms Sql Server was this:
a) find a date closer to now than 0001.01.01 & its ticks value
b) use a function to give me a DateTime value.
Notes:
* for my application - seconds was good enough.
* I've not tested this extensively, but so far, it has acted pretty well for me.
The function:
CREATE FUNCTION [dbo].[net_ticks_to_date_time]
(
#net_ticks BIGINT
)
RETURNS DATETIME
AS
BEGIN
DECLARE
#dt_2010_11_01 AS DATETIME = '2010-11-01'
, #bi_ticks_for_2010_11_01 AS BIGINT = 634241664000000000
, #bi_ticks_in_a_second AS BIGINT = 10000000
RETURN
(
DATEADD(SECOND , ( ( #net_ticks - #bi_ticks_for_2010_11_01 ) / #bi_ticks_in_a_second ) , #dt_2010_11_01)
);
END
GO
Here is how I came up with the # of ticks to some recent date:
DECLARE
#dt2_dot_net_min AS DATETIME2 = '01/01/0001'
, #dt2_first_date AS DATETIME2
, #dt2_next_date AS DATETIME2
, #bi_seconds_since_0101001 BIGINT = 0
SET #dt2_first_date = #dt2_dot_net_min;
SET #dt2_next_date = DATEADD ( DAY, 1, #dt2_first_date )
WHILE ( #dt2_first_date < '11/01/2010' )
BEGIN
SELECT #bi_seconds_since_0101001 = DATEDIFF(SECOND, #dt2_first_date, #dt2_next_date ) + #bi_seconds_since_0101001
PRINT 'seconds 01/01/0001 to ' + CONVERT ( VARCHAR, #dt2_next_date, 101) + ' = ' + CONVERT ( VARCHAR, CAST ( #bi_seconds_since_0101001 AS MONEY ), 1)
SET #dt2_first_date = DATEADD ( DAY, 1, #dt2_first_date );
SET #dt2_next_date = DATEADD ( DAY, 1, #dt2_first_date )
END