Как прочитать правильные значения времени из таблицы Google

Я пытаюсь получить из отформатированной ячейки времени (hh:mm:ss) значение часа, значения могут быть больше 24:00:00, например, 20000:00: 00 должно дать 20000:

стол:

two Google Spread Sheet

Если вы прочитали значение E1:

var total = sheet.getRange("E1").getValue();
Logger.log(total);

результат:

СБ апр 12 07:09:21 GMT+00: 09 1902

теперь я попытался преобразовать его в объект Date и получить метку времени Unix это:

  var date = new Date(total);
  var milsec = date.getTime();
  Logger.log(Utilities.formatString("%11.6f",milsec));
  var hours = milsec / 1000 / 60 / 60; 
  Logger.log(hours)

1374127872020.000000

381702.1866722222

вопрос в том, как получить правильное значение 20000 ?

4 ответов


для будущих читателей. Есть две новые функции getDisplayValue() и getDisplayValues() предоставлено App Script folks, который возвращает отображаемое значение. Ознакомьтесь с документацией здесь


расширяя то, что сделал Серж, я написал некоторые функции, которые должны быть немного легче читать и учитывать различия часовых поясов между электронной таблицей и скриптом.

function getValueAsSeconds(range) {
  var value = range.getValue();

  // Get the date value in the spreadsheet's timezone.
  var spreadsheetTimezone = range.getSheet().getParent().getSpreadsheetTimeZone();
  var dateString = Utilities.formatDate(value, spreadsheetTimezone, 
      'EEE, d MMM yyyy HH:mm:ss');
  var date = new Date(dateString);

  // Initialize the date of the epoch.
  var epoch = new Date('Dec 30, 1899 00:00:00');

  // Calculate the number of milliseconds between the epoch and the value.
  var diff = date.getTime() - epoch.getTime();

  // Convert the milliseconds to seconds and return.
  return Math.round(diff / 1000);
}

function getValueAsMinutes(range) {
  return getValueAsSeconds(range) / 60;
}

function getValueAsHours(range) {
  return getValueAsMinutes(range) / 60;
}

Вы можете использовать эти функции вот так:

var range = SpreadsheetApp.getActiveSheet().getRange('A1');
Logger.log(getValueAsHours(range));

Излишне говорить, что это много работы, чтобы получить количество часов из диапазона. Пожалуйста, звезда вопрос 402 это функция запроса, чтобы иметь возможность получить строковое значение значение из ячейки.


значение, которое вы видите (Sat Apr 12 07:09:21 GMT+00:09 1902), является эквивалентной датой в стандартном времени Javascript, которая на 20000 часов позже даты ref.

вы должны просто удалить ссылку на таблицу значение из результата, чтобы получить то, что вы хотите.

этот код делает трюк :

function getHours(){
  var sh = SpreadsheetApp.getActiveSpreadsheet();
  var cellValue = sh.getRange('E1').getValue();
  var eqDate = new Date(cellValue);// this is the date object corresponding to your cell value in JS standard 
  Logger.log('Cell Date in JS format '+eqDate)
  Logger.log('ref date in JS '+new Date(0,0,0,0,0,0));
  var testOnZero = eqDate.getTime();Logger.log('Use this with a cell value = 0 to check the value to use in the next line of code '+testOnZero);
  var hours = (eqDate.getTime()+ 2.2091616E12 )/3600000 ; // getTime retrieves the value in milliseconds, 2.2091616E12 is the difference between javascript ref and spreadsheet ref. 
  Logger.log('Value in hours with offset correction : '+hours); // show result in hours (obtained by dividing by 3600000)
}

enter image description here

Примечание: этот код получает только часы, если у вас будут минуты и / или секунды, то он должен быть разработан, чтобы справиться с этим тоже... дайте нам знать, если вам это нужно.


EDIT: слово объяснения...

электронные таблицы используют ссылочную дату 12/30/1899, в то время как Javascript использует 01/01/1970, это означает, что существует разница в 25568 дней между обеими ссылками. Все это при условии, что мы используем один и тот же часовой пояс в обеих системах. Когда мы преобразуем значение даты в электронной таблице в объект даты javascript, газовый движок автоматически добавляет разницу, чтобы сохранить согласованность между даты.

в этом случае мы не хотим знать реальную дату чего-то, а скорее абсолютное значение часов, то есть "продолжительность", поэтому нам нужно удалить смещение 25568 дней. Это делается с помощью getTime() метод, который возвращает миллисекунды, отсчитанные от даты ссылки JS, единственное, что мы должны знать, это значение в миллисекундах даты ссылки электронной таблицы и вычесть это значение из объекта фактической даты. Затем немного математики, чтобы получить часы вместо миллисекунд, и мы сделанный.

Я знаю, что это кажется немного сложным, и я не уверен, что моя попытка объяснить действительно прояснит вопрос, но всегда стоит попробовать, не так ли ?

в любом случае результат-это то, что нам нужно, пока (как указано в комментариях) можно настроить значение смещения в соответствии с настройками часового пояса электронной таблицы. Конечно, можно было бы позволить сценарию обрабатывать это автоматически, но это сделало бы сценарий более сложным, не уверен, что это действительно необходимый.


для простых электронных таблиц вы можете изменить часовой пояс электронной таблицы на GMT без перехода на летнее время и использовать эту короткую функцию преобразования:

function durationToSeconds(value) {
  var timezoneName = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
  if (timezoneName != "Etc/GMT") {
    throw new Error("Timezone must be GMT to handle time durations, found " + timezoneName);
  }
  return (Number(value) + 2209161600000) / 1000;
}
Эрик Коледа во многом общие. Я написал это, пытаясь понять, как он обрабатывает угловые случаи с часовым поясом электронной таблицы, часовым поясом браузера и изменениями часового пояса в 1900 году на Аляске и Стокгольме.