Reputation: 1393
I have some google spreadsheet logbook where I store duration of some activities in hours format [[HH]:MM:SS]. The spreadsheet adds such cells with no issues. However when I try to add them via Google Script I get some garbage. What I found is that Date() object is implicitly created for such cells, but I cannot find API of that value type.
I know I can convert the data to "hour integers" by multiplying them by 24 but that is a nasty workaround as it demands duplication of many cells. I would rather like a solution that will allow to do that in google script itself.
Upvotes: 0
Views: 174
Reputation: 46792
here is a working function that does the trick.
I first tried to format it as a date but 36 hours is not really standard !! so I did a little bit of math :-) )
To get it working you should set a cell somewhere with value 00:00:00
that we will use as a reference date in spreadsheet standard. in my code it is cell D1
(see comment in code, reference date in SS is in 1900 and in Javascript is in 1970 ... that's why it is a negative constant of 70 years in milliseconds...)
here is the code and below a screen capture of the test sheet + the logger It would be a good idea to modify this code to make it a function that takes cell value as parameter and returns the result as an array for example ([h,m,s] or something similar), this code is only to show how it works.
function addHoursValues() {
var sh = SpreadsheetApp.getActive()
var hours1 = sh.getRange('A1').getValue();
var hours2 = sh.getRange('B1').getValue();
var ref = sh.getRange('D1').getValue().getTime();
//var ref = -2209161600000 // you could also use this but it would be less obvious what it really does ;-)
Logger.log(ref+' = ref');
var h1 = parseInt((hours1.getTime()/3600000)-ref/3600000);
var h2 = parseInt((hours2.getTime()/3600000)-ref/3600000);
Logger.log(h1+' + '+h2+' = '+(h1+h2))
var m1 = parseInt((hours1.getTime()-h1*3600000-ref)/60000);
var m2 = parseInt((hours2.getTime()-h2*3600000-ref)/60000);
Logger.log(m1+' + '+m2+' = '+(m1+m2))
var s1 = parseInt((hours1.getTime()-h1*3600000-m1*60000-ref)/1000);
var s2 = parseInt((hours2.getTime()-h2*3600000-m2*60000-ref)/1000);
Logger.log(s1+' + '+s2+' = '+(s1+s2))
var ts=s1+s2
var tm=m1+m2
var th=h1+h2
if(ts>59){ts=ts-60;tm++};
if(tm>59){tm=tm-60;th++}
Logger.log('sum = '+th+':'+tm+':'+ts)
}
EDIT : here are 2 "function" versions with corresponding test functions that show how to use it
function getHMS(hrs) {
var t = hrs.getTime()/1000;
var ref = -2209161600;
var h = parseInt((t-ref)/3600);
var m = parseInt((t-h*3600-ref)/60);
var s = parseInt(t-h*3600-m*60-ref);
return[h,m,s];// returns an array of 3 discrete values
}
function testHMS(){
var sh = SpreadsheetApp.getActive();
var hours1 = sh.getRange('A1').getValue();
var hours2 = sh.getRange('B1').getValue();
var sumS = getHMS(hours1)[2]+getHMS(hours2)[2];// add seconds
var sumM = getHMS(hours1)[1]+getHMS(hours2)[1];// add minutes
var sumH = getHMS(hours1)[0]+getHMS(hours2)[0];// add hours
if(sumS>59){sumS=sumS-60 ; sumM++}; // handles values >59
if(sumM>59){sumM=sumM-60 ; sumH++}; // handles values >59
Logger.log(sumH+':'+sumM+':'+sumS);
}
OR
function addHMS(hrs1,hrs2) {
var t1 = hrs1.getTime()/1000;
var t2 = hrs2.getTime()/1000;
var ref = -2209161600;
var h = parseInt((t1-ref)/3600)+parseInt((t2-ref)/3600);
var m = parseInt((t1-parseInt((t1-ref)/3600)*3600-ref)/60)+parseInt((t2-parseInt((t2-ref)/3600)*3600-ref)/60);
var s = parseInt(t1-parseInt((t1-ref)/3600)*3600-parseInt((t1-parseInt((t1-ref)/3600)*3600-ref)/60)*60-ref)
+parseInt(t2-parseInt((t2-ref)/3600)*3600-parseInt((t2-parseInt((t2-ref)/3600)*3600-ref)/60)*60-ref);
if(s>59){s=s-60 ; m++}; // handles values >59
if(m>59){m=m-60 ; h++}; // handles values >59
return[h,m,s];// returns sum in an array of 3 discrete values
}
function othertestHMS(){
var sh = SpreadsheetApp.getActive();
var hours1 = sh.getRange('A1').getValue();
var hours2 = sh.getRange('B1').getValue();
Logger.log(addHMS(hours1,hours2));
}
Upvotes: 2