Get the Difference Between Dates in Terms of Weeks, Months, Quarters, and Years

Get the difference between dates in terms of weeks, months, quarters, and years

what about this:

# get difference between dates `"01.12.2013"` and `"31.12.2013"`

# weeks
difftime(strptime("26.03.2014", format = "%d.%m.%Y"),
strptime("14.01.2013", format = "%d.%m.%Y"),units="weeks")
Time difference of 62.28571 weeks

# months
(as.yearmon(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearmon(strptime("14.01.2013", format = "%d.%m.%Y")))*12
[1] 14

# quarters
(as.yearqtr(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearqtr(strptime("14.01.2013", format = "%d.%m.%Y")))*4
[1] 4

# years
year(strptime("26.03.2014", format = "%d.%m.%Y"))-
year(strptime("14.01.2013", format = "%d.%m.%Y"))
[1] 1

as.yearmon() and as.yearqtr() are in package zoo. year() is in package lubridate.
What do you think?

Time difference between quarters

#using zoo library to transform my dates into quarters
sample_dataframe$First_purchase_quarter <- as.yearqtr((sample_dataframe$First_Purchase_date), "%Y-%m-%d")
sample_dataframe$Recent_Purchase_quarter <- as.yearqtr((sample_dataframe$Recent_Purchase_date), "%Y-%m-%d")

sample_dataframe$diff <- (sample_dataframe[, 4] - sample_dataframe[, 3]) * 4
head(sample_dataframe$diff)
[1] 1 7 2

Difference between two dates in Months in R

We need to provide the correct format. Here, it is %m/%Y instead of %Y-%m

library(zoo)
df$Due_Date <- (as.yearmon(df$Recent_Date, format = "%m/%Y")-
as.yearmon(df$Finish_Date, format = "%m/%Y"))*12
df$Due_Date
#[1] 3 174 136

How to get difference between two dates in Year/Month/Week/Day?

This is actually quite tricky. A different total number of days can result in the same result. For example:

  • 19th June 2008 to 19th June 2010 = 2 years, but also 365 * 2 days

  • 19th June 2006 to 19th June 2008 = 2 years, but also 365 + 366 days due to leap years

You may well want to subtract years until you get to the point where you've got two dates which are less than a year apart. Then subtract months until you get to the point where you've got two dates which are less than a month apart.

Further confusion: subtracting (or adding) months is tricky when you might start with a date of "30th March" - what's a month earlier than that?

Even further confusion (may not be relevant): even a day isn't always 24 hours. Daylight saving anyone?

Even further confusion (almost certainly not relevant): even a minute isn't always 60 seconds. Leap seconds are highly confusing...

I don't have the time to work out the exact right way of doing this right now - this answer is mostly to raise the fact that it's not nearly as simple as it might sound.

EDIT: Unfortunately I'm not going to have enough time to answer this fully. I would suggest you start off by defining a struct representing a Period:

public struct Period
{
private readonly int days;
public int Days { get { return days; } }
private readonly int months;
public int Months { get { return months; } }
private readonly int years;
public int Years { get { return years; } }

public Period(int years, int months, int days)
{
this.years = years;
this.months = months;
this.days = days;
}

public Period WithDays(int newDays)
{
return new Period(years, months, newDays);
}

public Period WithMonths(int newMonths)
{
return new Period(years, newMonths, days);
}

public Period WithYears(int newYears)
{
return new Period(newYears, months, days);
}

public static DateTime operator +(DateTime date, Period period)
{
// TODO: Implement this!
}

public static Period Difference(DateTime first, DateTime second)
{
// TODO: Implement this!
}
}

I suggest you implement the + operator first, which should inform the Difference method - you should make sure that first + (Period.Difference(first, second)) == second for all first/second values.

Start with writing a whole slew of unit tests - initially "easy" cases, then move on to tricky ones involving leap years. I know the normal approach is to write one test at a time, but I'd personally brainstorm a bunch of them before you start any implementation work.

Allow yourself a day to implement this properly. It's tricky stuff.

Note that I've omitted weeks here - that value at least is easy, because it's always 7 days. So given a (positive) period, you'd have:

int years = period.Years;
int months = period.Months;
int weeks = period.Days / 7;
int daysWithinWeek = period.Days % 7;

(I suggest you avoid even thinking about negative periods - make sure everything is positive, all the time.)

How to create a list of weeks/months/quarters between a range of two dates

To make your calculations work across multiple years, you should base them not on the endDate, but on the duration between the two dates. To do so, you can make your for loops going from the startDate to the startDate + duration.

I made an example for the calculation of the weeks : https://jsbin.com/xejocusana/edit?html,js,console

dateStart = "01-01-2018";
dateEnd = "03-31-2019";

start = moment(dateStart, "MM-DD-YYYY")
end = moment(dateEnd, "MM-DD-YYYY")

lowerRange = Math.floor(moment(dateStart, "MM-DD-YYYY").dayOfYear()/7);
// calculate the number of weeks between the two dates
numberOfWeeks = end.diff(start, 'weeks');
year = moment(dateStart, "MM-DD-YYYY").year();

weekListA = []
for (var i = lowerRange; i <= lowerRange + numberOfWeeks; i++) {
weekListA.push('W' + (i%52 +1) + '_' + (year+ Math.floor(i/52)));
}
console.log(weekListA);

I added :

  • a calculation of the numberOfWeeks, needed for the limit of the loop ;
  • a modulo + (i%52 +1) in the loop, to have the number of the week (You have to write +1 to make it begin at 0. Due to this constraint, you have to use Math.floor() instead of Math.ceil() when you calculate lowerRange) ;
  • a + Math.floor(i/52) in the loop, to increment the number of the year ;

I let you check if all the cases are covered (dates across more than 2 years, dates included or excluded, etc.)

How can I calculate the number of months between two given dates ( baseline and follow-up)

Here is an option with lubridate

library(dplyr)
library(lubridate)
df1 %>%
mutate(Months_difference = (interval(mdy(Baseline),
mdy(Follow_Up))) %/% months(1))

Get months and years difference between two dates

you can create DateTime objects and invoke diff:

$date1 = new DateTime("2012-12");
$date2 = new DateTime("2014-03");
$interval = $date1->diff($date2);
echo $interval->y . " years, " . $interval->m." months, ".$interval->d." days";

spits out:

1 years, 3 months, 0 days

and if you REALLY have your heart set on using strtotime, you can get the difference in seconds like so:

$one_hour = 30*60*60;
$one_day = 24*$one_hour;
$one_month = 30*$one_day;
$one_year = 365*$one_day;

$diff = abs(strtotime('2012-12') - strtotime('2014-03'));
$years = floor($diff / $one_year);
$months = floor(($diff - $years * $one_year) / $one_month);
$days = floor(($diff - $years * $one_year - $months*$one_month)/ $one_day);


Related Topics



Leave a reply



Submit