0

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.

j0k
  • 22,600
  • 28
  • 79
  • 90
Mateusz Pusz
  • 1,363
  • 1
  • 9
  • 16
  • OK, it seems that the API for Date in a JavaScript one. However I still did not manage to sum in Google Script two cells with values like 36:12:00 and 71:34:00 and get a meaningful result. Doing that in spreadsheet is working fine. – Mateusz Pusz Mar 24 '13 at 19:31
  • Sounds like a javascript question - Google Script is Javascript – eddyparkinson Mar 25 '13 at 23:57
  • After more investigation I think the problem is not in Java Script API but the fact that Google uses Date() for "Hours" format. In debugger I saw something like that `new Date(-2209045440000)` created automatically for a cell with value `33:40:00`. – Mateusz Pusz Mar 26 '13 at 08:02
  • have a look at http://stackoverflow.com/questions/1050720/adding-hours-to-javascript-date-object ... the value Date(2209045440000) is in milliseconds – eddyparkinson Mar 27 '13 at 01:25

1 Answers1

2

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)
}

enter image description here

enter image description here


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));
}
Serge insas
  • 45,904
  • 7
  • 105
  • 131