使用Javascript比较PDF格式的时间范围

时间:2018-06-28 19:04:10

标签: javascript arrays pdf foxit

我有一个PDF表单,每个月的每一天都有6个不同的时间段,我需要确保用户完成这些时间段时这些时间段不重叠。并非所有时间段都可以完成,但必须是唯一的。我从之前的Use JavaScript to compare time ranges帖子中汲取了灵感,特别是@RobG的贡献。但是,由于我缺乏脚本知识,因此无法为我的特定应用程序编写该代码。除了要核实时间段外,我还必须每天在表格上重复一次,但是我想一次做到这一点,特别是在当天进行输入时。由于这是PDF表单,因此我不确定如何执行该验证。例如,是否应在每个时间段完成时执行?也就是说,有开始时间和结束时间吗?因此,它将作为该时间输入的“验证”脚本吗? 以下是表单外观的示例:

enter image description here

enter image description here

这是我尝试更新表单代码的尝试:

var TimeIn1 = this.getField("Day1Pd1TimeInRes").value;
var TimeOut1 = this.getField("Day1Pd1TimeOutRes").value;
var TimeIn2 = this.getField("Day1Pd2TimeInRes").value;
var TimeOut2 =  this.getField("Day1Pd2TimeOutRes").value;
var TimeIn3 = this.getField("Day1Pd3TimeInRes").value;
var TimeOut3 = this.getField("Day1Pd3TimeOutRes").value;
var TimeIn4 = this.getField("Day1Pd4TimeInRes").value;
var TimeOut4 = this.getField("Day1Pd4TimeOutRes").value;
var TimeIn5 = this.getField("Day1Pd5TimeInRes").value;
var TimeOut5 =  this.getField("Day1Pd5TimeOutRes").value;
var TimeIn6 = this.getField("Day1Pd6TimeInRes").value;
var TimeOut6 = this.getField("Day1Pd6TimeOutRes").value;

var timeSlots = [
  {BeginTime: new Date("10/25/2015 " + TimeIn1),
   EndTime: new Date("10/25/2015 " + TimeOut1)},
  {BeginTime: new Date("10/25/2015 " + TimeIn2),
   EndTime: new Date("10/25/2015 " + TimeOut2)},
  {BeginTime: new Date("10/25/2015 " + TimeIn3),
   EndTime: new Date("10/25/2015 " + TimeOut3)},
  {BeginTime: new Date("10/25/2015 " + TimeIn4),
   EndTime: new Date("10/25/2015 " + TimeOut4)},
  {BeginTime: new Date("10/25/2015 " + TimeIn5),
   EndTime: new Date("10/25/2015 " + TimeOut5)},
  {BeginTime: new Date("10/25/2015 " + TimeIn6),
   EndTime: new Date("10/25/2015 " + TimeOut6)}
];
function slotFits(slot) {
  if (timeSlots.length == 0) return true; // If no slots, must fit
  return timeSlots.some(function(s, i) {
    return (i == 0 && slot.EndTime <= s.BeginTime) || //slot is before all others
  (s.EndTime <= slot.BeginTime && !timeSlots[i + 1]) || //slot is after all others
  (s.EndTime <= slot.BeginTime && timeSlots[i + 1].BeginTime >= slot.EndTime) // Slot between others
  });
}

[{BeginTime: new Date("10/25/2015 " + TimeIn1),
  EndTime: new Date("10/25/2015 " + TimeOut1)},
 {BeginTime: new Date("10/25/2015 " + TimeIn2),
  EndTime: new Date("10/25/2015 " + TimeOut2)},
 {BeginTime: new Date("10/25/2015 " + TimeIn3),
  EndTime: new Date("10/25/2015 " + TimeOut3)},
 {BeginTime: new Date("10/25/2015 " + TimeIn4),
  EndTime: new Date("10/25/2015 " + TimeOut4)},
 {BeginTime: new Date("10/25/2015 " + TimeIn5),
  EndTime: new Date("10/25/2015 " + TimeOut5)},
 {BeginTime: new Date("10/25/2015 " + TimeIn6),
  EndTime: new Date("10/25/2015 " + TimeOut6)},
].forEach(function(slot, i) {
  app.alert('Slot ' + i + ': ' + slotFits(slot));
});

在此示例中,我拼写了字段名称,但是由于我一次最多重复31天,因此我想找到一种方法来创建文档脚本,并在其中放入“ TimeIn”和'TimeOut变量并每天调用一次,但是我认为我可以在没有必要的情况下摆脱困境,只需要担心表单大小在6个周期内重复这么多的代码,可能会持续31天。谢谢!

编辑:时间值为HH:mm

1 个答案:

答案 0 :(得分:0)

让我们稍微重写一下,因为“事物变得异常复杂”的典型解决方案通常是“选择更好的数据结构”,在这种情况下,这意味着使用Entry表示形式,并为您完成工作。

鉴于Foxit显然不支持现代JS,使用较旧的ES5看起来像:

 subset(cbind(A=dat[,1],stack(dat[-1])),values==1,-2)
      A ind
1   ex1  S1
4   ex4  S1
7   ex7  S1
10 ex10  S1
12  ex2  S2
14  ex4  S2
15  ex5  S2
16  ex6  S2
17  ex7  S2
18  ex8  S2
23  ex3  S3
27  ex7  S3
28  ex8  S3
29  ex9  S3
35  ex5  S4

library(tidyverse)
dat%>%
   gather(Type,j,-A)%>%
   filter(j==1)%>%
   select(-j)
      A Type
1   ex1   S1
2   ex4   S1
3   ex7   S1
4  ex10   S1
5   ex2   S2
6   ex4   S2
7   ex5   S2
8   ex6   S2
9   ex7   S2
10  ex8   S2
11  ex3   S3
12  ex7   S3
13  ex8   S3
14  ex9   S3
15  ex5   S4

然后我们可以使用类似以下代码的对象:

function Entry(pdfObject, day, pd, dateOffset) {
  this.id = day + '-' + pd;
  this.in = pdfObject.getField('Day'+day+'Pd'+pd+'TimeInRes').value;
  this.out = pdfObject.getField('Day'+day+'Pd'+pd+'TimeOutRes').value;
  this.begin = new Date(dateOffset+' '+this.in);
  this.end = new Date(dateOffset+' '+this.out);
  this.interval = this.end.getTime() - this.begin.getTime(); 
}

Entry.prototype = {
  checkFit: function checkFit(entries) {
    // 1: find out where our start fits into the list of start times
    var start = -1, l = entries.length, other, i, e;
    for (i=0; i<l; i++) {
      e = entries[i];
      if (this.begin < e.begin) {
        start = i;
        other = e;
      }
      if (this.begin > e.begin) break;
    }
    // are we the last entry? if so, we fit if we start after the last end.
    if (!other || start === l-1) return (this.begin > entries[l-1].end);
    // IF not, there is a next entry; do we end before that begins?
    return other.begin <= this.end;
  }
}

Entry.loadAll = function loadAll(pdfObject, day, dateOffset) {
  return [1,2,3,4,5,6]
         .map(function(i) { return new Entry(pdfObject, day, i, dateOffset); })
         .sort(function(a,b) { return a.end - b.end; });
}