I'm trying to write a function in Google Apps Script to manipulate durations calculated in Google Sheets. The cells holding the durations look like:
18:40:00
26:42:01
When I pass a duration into my code it appears to come in as a date object. So I've been using Date.getHours()
et al to pull out the components of the time. But when the hours exceeds 23, it comes out mod 24.
Where did the "days" part of the duration go? Is there a method I can call on the Date object to get it?
Best Answer
Working with date, time and specifically duration is a pain in JavaScript, and Google Sheets does not make it much easier.
A JavaScript Date object (which is really a datetime object) is not suited for working with durations. A datetime is a lot more complex than it seems at first.
So when you ask
... there is really no secure way of converting a duration to a number of days, since you don't know which day, in which timezone you're talking about. In my region, daylight savings time ended October 27, 03:00:00 (this year), meaning that a period spanning from October 27 00:00:00 through October 28 00:00:00 is actually 25 hours. Different countries have different rules for daylight savings time, adding to the confusion.
See this article for more examples on how dates are difficult to calculate with.
My advise would be to ditch the entire Duration feature, and decide which unit you want to work with: Days, hours or minutes. If you choose to work with hours, and want to specify a duration of 1 hour and 30 minutes, enter
1.5
in that cell.If you need to display
1.5
hours as1 hours 30 minutes
somewhere, write a simple formula for that - but use it only for display purposes.If you really want to work with
Date
, some experimentation on a simple spreadsheet might clarify a few things. I set up this spreadsheet for experimentation - feel free to copy it to your own drive.In cell
A2
I enter a number of days, e.g.1.5
. CellB2
is formatted as Duration, with the formula=A2
, so it simply displays1.5
as a Duration:24:00:00
.For cell
C2
I have written a small script that dumps some debug information about theB2
value:This causes the
C2-C5
to displaySo a duration of 1.5 days is represented by a Date object with the value
1899-12-31T11:00:00.000Z
. Not the easiest thing to work with.Enter a value of
0
inA2
, and watchC4
change to"1899-12-31T11:00:00.000Z"
. We could use this as a base date, and compare it to the 1.5 days duration date."Subtracting" two dates is easiest done by looking at the date's
getTime()
function, which gives the number of milliseconds since the Unix Epoch, which is00:00:00 UTC on 1 January 1970
.By comparing each duration with the base date, we can write a function:
Hopefully this can be a starting point for your calculation needs.