Как рассчитать разницу между двумя временными метками в javascript, исключая выходные и ночи? - PullRequest
0 голосов
/ 20 февраля 2020

В настоящее время я пытаюсь найти лучший способ определить продолжительность времени (в секундах или более точно) между двумя временными метками, исключая выходные и нерабочие часы.

С выходными легче обращаться, и я смог сделать это, просто используя операторы if, используя дни / недели ISO с моментом. js, но определяя, когда удалять ночи вне установленных рабочих часов (8 -5) оказался довольно сложным. Даже если начальная или конечная отметка времени была в нерабочее время или в выходные, я все равно хочу подсчитать все рабочие часы.

Я буду выполнять это на большом запросе Google в UDF с потенциально миллионами строк данных, поэтому он также должен быть несколько эффективным. Буду признателен за любую оказанную помощь.

1 Ответ

0 голосов
/ 20 февраля 2020

Если вы открыты для использования только BQ, рассмотрите следующий фрагмент в BigQuery Standard SQL:

with data as (
  select 1 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 1 day) as ts2 union all
  select 2 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 2 day) as ts2 union all
  select 3 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 3 day) as ts2 union all
  select 4 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 4 day) as ts2 union all
  select 5 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 5 day) as ts2 union all
  select 6 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 6 day) as ts2 union all
  select 7 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 7 day) as ts2
),
temp as (
  select * 
  from data, unnest(generate_timestamp_array(timestamp_trunc(ts1,day),timestamp_trunc(ts2,day),interval 1 day)) calendar
)
select
  id, ts1, ts2,
  sum(
      case 
           -- Get # of Seconds on First Day from ts1 to 5:00PM
           when timestamp_trunc(ts1,day) = timestamp_trunc(calendar,day)
           then greatest(timestamp_diff(timestamp_add(calendar,interval 17 hour),ts1,second),0)
           -- Get # of Seconds on Last Day from 8:00AM to ts2
           when timestamp_trunc(ts2,day) = timestamp_trunc(calendar,day)
           then greatest(timestamp_diff(ts2,timestamp_add(calendar, interval 8 hour),second),0)
           -- Otherwise it is a full 8 hour day
           else 8*60*60
      end
     ) as working_seconds
from temp
where extract(dayofweek from calendar) not in (7,1) -- Exclude Saturday and Sunday
group by 1,2,3

...