Last active
July 19, 2018 13:51
-
-
Save nicholaskajoh/5528a626dd9bf1472bf3a61a97034a89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* calculate the difference in minutes between 2 date times | |
given that only the minutes within a specified time range | |
every day should be counted | |
e.g: say the time range is 6AM to 6PM | |
if datetime1 = 4AM and datetime2 = 5AM, difference = 0 minutes | |
this is because 4AM to 5AM doesn't fall within the range of | |
6AM to 6PM so the 60 minutes isn't counted | |
e.g 2: say we have same time range and, | |
datetime1 = 5AM today and datetime2 = 7PM tomorrow, | |
difference = 1440 minutes | |
this is because, between 5AM today and 7PM tomorrow, there are | |
24 x 60 minutes within the range of 6AM and 6PM | |
In this function, we call this range "working hours", or WH | |
So we have a WH_START and WH_END | |
NB: We assume all datetimes are in UTC i.e 2011-04-11T10:20:30Z | |
Also, datetime1 < datetime2 | |
*/ | |
function datetimeDiff(datetime1, datetime2) { | |
const WH_START = '06:00:00'; | |
const WH_END = '18:00:00'; | |
const maxDatetime = (x, y) => x > y ? x: y; | |
const minDatetime = (x, y) => x < y ? x: y; | |
let totalMinutesDifference = 0; | |
let todaysDate = new Date(`${datetime1.toISOString().split('T')[0]}T00:00:00Z`); | |
const endDate = new Date(`${datetime2.toISOString().split('T')[0]}T00:00:00Z`); | |
let WHTodayStart = new Date(`${datetime1.toISOString().split('T')[0]}T${WH_START}Z`); | |
let WHTodayEnd = new Date(`${datetime1.toISOString().split('T')[0]}T${WH_END}Z`); | |
let todayStarts = datetime1; | |
let todayEnds = datetime2 < WHTodayEnd ? datetime2: WHTodayEnd; | |
while (todaysDate <= endDate) { | |
let p = maxDatetime(todayStarts, WHTodayStart); | |
let q = minDatetime(todayEnds, WHTodayEnd); | |
let minutesDifference = (q - p) / (60 * 1000); | |
minutesDifference = minutesDifference > 0 ? minutesDifference: 0; | |
totalMinutesDifference += minutesDifference; | |
WHTodayStart.setHours(WHTodayStart.getHours() + 24); | |
WHTodayEnd.setHours(WHTodayEnd.getHours() + 24); | |
todaysDate.setHours(todaysDate.getHours() + 24); | |
todayStarts = WHTodayStart; | |
todayEnds = datetime2 < WHTodayEnd ? datetime2: WHTodayEnd; | |
} | |
return totalMinutesDifference; | |
} | |
// TEST | |
testCases = [ | |
{ dt1: new Date('2012-12-12T04:00:00Z'), dt2: new Date('2012-12-12T05:00:00Z'), diff: 0 }, | |
{ dt1: new Date('2012-12-12T18:00:00Z'), dt2: new Date('2012-12-12T20:00:00Z'), diff: 0 }, | |
{ dt1: new Date('2012-12-12T04:00:00Z'), dt2: new Date('2012-12-12T07:00:00Z'), diff: 60 }, | |
{ dt1: new Date('2012-12-12T12:00:00Z'), dt2: new Date('2012-12-12T14:00:00Z'), diff: 120 }, | |
{ dt1: new Date('2012-12-12T15:00:00Z'), dt2: new Date('2012-12-12T19:00:00Z'), diff: 180 }, | |
{ dt1: new Date('2012-12-12T05:00:00Z'), dt2: new Date('2012-12-13T19:00:00Z'), diff: 1440 }, | |
{ dt1: new Date('2012-12-12T10:00:00Z'), dt2: new Date('2012-12-13T19:00:00Z'), diff: 1200 }, | |
{ dt1: new Date('2012-12-12T08:00:00Z'), dt2: new Date('2012-12-15T15:00:00Z'), diff: 2580 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 7, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 10, 7, 39, 33)), diff: 0 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 7, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 10, 17, 39, 33)), diff: 600 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 7, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 7, 39, 33)), diff: 720 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 7, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 7, 40, 33)), diff: 721 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 5, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 10, 8, 39, 33)), diff: 159.55 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 8, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 8, 39, 33)), diff: 720 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 7, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 8, 39, 33)), diff: 780 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 7, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 6, 39, 33)), diff: 660 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 9, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 8, 39, 33)), diff: 660 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 16, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 10, 23, 39, 33)), diff: 80.45 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 16, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 23, 39, 33)), diff: 800.45 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 16, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 7, 39, 33)), diff: 180 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 16, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 8, 39, 33)), diff: 240 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 20, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 8, 39, 33)), diff: 159.55 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 19, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 10, 21, 39, 33)), diff: 0 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 19, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 2, 39, 33)), diff: 0 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 3, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 20, 2, 39, 33)), diff: 720 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 3, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 20, 4, 39, 33)), diff: 720 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 2, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 20, 3, 39, 33)), diff: 720 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 4, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 20, 3, 39, 33)), diff: 720 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 20, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 21, 20, 39, 33)), diff: 1440 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 21, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 21, 20, 39, 33)), diff: 1440 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 19, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 21, 20, 39, 33)), diff: 1440 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 20, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 21, 21, 39, 33)), diff: 1440 }, | |
{ dt1: new Date(Date.UTC(2018, 10, 19, 20, 39, 33)), dt2: new Date(Date.UTC(2018, 10, 21, 19, 39, 33)), diff: 1440 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 19, 18, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 20, 17, 39, 33)), diff: 699.55 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 19, 20, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 20, 1, 39, 33)), diff: 0 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 20, 6, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 22, 0, 39, 33)), diff: 1400.45 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 6, 0, 0)), dt2: new Date(Date.UTC(2018, 9, 10, 8, 0, 0)), diff: 120 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 6, 0, 0)), dt2: new Date(Date.UTC(2018, 9, 10, 6, 0, 0)), diff: 0 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 6, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 12, 6, 39, 33)), diff: 1440 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 6, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 6, 39, 33)), diff: 720 }, | |
{ dt1: new Date(Date.UTC(2018, 9, 10, 6, 39, 33)), dt2: new Date(Date.UTC(2018, 9, 11, 7, 39, 33)), diff: 780 }, | |
]; | |
for(let testCase of testCases) { | |
let diff = datetimeDiff(testCase.dt1, testCase.dt2); | |
let status = diff === testCase.diff ? 'PASS': 'FAIL'; | |
console.log(`Expected: ${testCase.diff} minutes, Output: ${diff} minutes, Status: ${status}`); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment