Checking days which are closest - date

This is going to be a bit hard to explain but
I have 2 dates, i'm interested in the day and month unless the 2 dates have the same year
2015/12/30 and 2019/01/04
ignoring the year part (kind of) the result i'm expecting 6 days difference for the 2 dates above
if i was to use date.DayOfYear i would get 364 (2015/12/30) and 4 (2019/01/04) respectively
however if the years are same then
2019/01/04 2019/12/30 then the result i'm expecting is 359 days difference
is there a clever way of doing this without peppering the code with if statements?

If the year difference was just 0 or 1, then you could just convert both dates to an absolute value (in seconds, ms, unix time or whatever), subtract the 2 values and convert it to full days. But if you have more than 1 year diff (as 2015 and 2019), then you have to have an "if" an think about what are you actually trying to do there. You shouldn't use DayOfYear, because some years have 366 days, so you can't be sure that 364 corresponds to 1 or 2 days left in that year.

Related

How does rust chrono Duration get number of years or months?

I'm quite new to Rust and chrono library.
I checked the https://docs.rs/chrono/0.4.19/chrono/struct.Duration.html#method.num_weeks, but there's no num_years() or num_months() API in chrono::Duration.
Is there any work around solution for this ?
chrono::Duration provides date and time duration in "ISO 8601 time duration with nanosecond precision", which implies it is representing the duration internally as a number of nanoseconds, and then providing convenience methods to convert into other duration units such as days, weeks, milliseconds, etc.
This is a little at odds with the actual ISO 8601 duration standard, which is a standard of representations and formats. The standard represents durations by the format P[n]Y[n]M[n]DT[n]H[n]M[n]S - which might give you what you want. But this is not what chronos::Duration was designed to provide.
The problem is that in order to represent a duration of months or years, more information than the number of nanoseconds is needed. Durations define the amount of intervening time in a time interval: the time between two points. The start or end time is important, because months or years are not standard durations. There are months of 28, 29 30, 31 days, and years of 365 and 366 days.
If you were to write your own algorithm to format durations in terms of years, months, days, hours, minutes, seconds, etc.. you would have to know the start date. In addition, time zone is important, because daylight savings needs to be taken into account. You would also have to make decisions about how to represent parts of months or years. For example the month of January has 31 days, and February 28, say. What would it mean to represent a duration of 1.75 months from January 1? Would that mean 31 days for January then 0.75 * 28 days in February?
Or you could represent the duration from a start date in a cascading unit format: e.g., 5 years, 4 months and 3 days, 2 hours, 12 minutes and 3 seconds from 1 Jan 1970 12:00Z. Just like the ISO 8601 standard.
So, its not an easy solution, and it all depends what your requirements are. I can understand why the developers of chronos:Duration left off providing num_months() and num_years()!
The crate chronoutil provides RelativeDuration which is "extending Chrono’s Duration to add months and years".
Example from docs.rs:
let one_day = RelativeDuration::days(1);
let one_month = RelativeDuration::months(1);
let delta = one_month + one_day;
let start = NaiveDate::from_ymd(2020, 1, 30);
assert_eq!(start + delta, NaiveDate::from_ymd(2020, 3, 1));

What is the correct order for substracting from a date

I just stumbled on an interesting problem when trying to calculate birthday from age. Basically the idea is to substract a number of years, months and days from the current date. However depending on the order of subtraction eg smaller to larger units or vice versa the result is different.
For example we need to substract 55 years 3 months and 14 days from 2021-01-13
If I subtract the years first the result will be 1965-09-29
If I subtract the days first the result will be 1965-09-30
It all comes from the difference between the number of days in a month. Now I'm wondering which is the generally accepted order.

PostgreSQL: Difference between 2 timestamps in days, hours and minutes

I have two timestamps and I need to calculate the difference between them in Days:Hours:Minutes.
I have done timestamp2-timestamp1 and the result is in months, days, hours and minutes. How can I convert the months in days knowing that some months have 31 days and the rest 30 without losing precision.

Rolling Count of Values BETWEEN two dates, 12 to 24 months ago (SPOTFIRE Custom Expression)

I am struggling to create this calculation.
I need to create a rolling count of all of a columns values BETWEEN two dates. 12 to 24 months ago.
I do not want to do this by limiting data, I need it in the custom expression due to other work.
Currently I have this equation. I thought this would at least calculate all the values since two years ago but it fails to do that as well. Does anyone have a simpler way to calculate 12 to 24 months ago?
(((Count(If(((Month([DATE])>=Month(DateAdd("mm",-24,DateTimeNow())))
and (Year([DATE])>=Year(DateAdd("yy",-2,DateTimeNow())))),
[EXTRAPOLATEDPRESSURE],null)))))
Solved. I was making it to complex with the Month and Year aspects.
Count(If(([DATE]>=dateadd("mm",-24,DateTimeNow())) and ([DATE]<=dateadd("mm",-12,DateTimeNow())),
[EXTRAPOLATEDPRESSURE],null))

Cumulative Days in Overlapping Date Ranges

I use Crystal Reports 11.
What I'd like to do is get a count of the unique days a student was enrolled in one of our many programs. If a student was enrolled in 3 programs in which the dates overlapped, I'd just want to count each day once and get a number.
Example using a student:
Algebra Jan 1 to Jan 10: 10 days
Science Jan 4 to Jan 11: 8 days
English Jan 9 to Jan 13: 4 days
I'd want the answer to be 13.
Good point. If they always over lap then this will work
Create a formula that finds maximum end date and the minimum start date based on patient. Then minus each formula.
i.e.: Maximum({xxx.enddate}, {xxx.patient}) - Minimum({xxx.startdate}, {xxx.patient})
If there are gaps between program dates, this won't work because it will include them.
Grouping the field by the patient name and Using
DistinctCount()
may be helpful.