我在 Google 表格电子表格中使用的数学方程式在我的 JavaScript 代码中不起作用(尽管它们应该有效),我无法弄清楚为什么



注意:我尽了最大努力尽可能清楚地解释了这个问题,所以如果这有点长,我很抱歉。我只是想说清楚。

不久前,我使用Google Sheets为手机游戏《领主手机》创建了一系列工具,目前正在将这些工具转移到一个新网站上。不幸的是,我的";帮助计算器";工具

在这个游戏中;帮助;是由族人提供的帮助玩家减少升级时间的东西。所以,如果我开始一个3小时的升级,而一个族人给了我一个";"帮助";,它在一定程度上减少了我的时间。这个工具的作用是告诉用户在提供一定数量的帮助后还有多少时间。我会在最上面的一行中输入我的持续时间(3小时),然后参考该表来查看每个"3小时"之后还有多少时间;帮助;鉴于

与此问题相关的所有相关文件都链接在此处,包括原始电子表格工具、新网络工具的实时演示以及所述网络工具的代码回购:

  • 电子表格版本
  • 网络版(现场演示)
  • Web版本(完整代码回购)

在电子表格版本中,列O包含一列数字,表示每个表行的总秒数。如果要插入";1秒";则单元格O1将包含数字1(1秒)。如果你要输入一个持续时间,它在第2行显示";1分钟";,细胞O2将显示";60〃;(60秒)。等等。在web版本中,我创建了一个名为numList的对象来存储这些数字(例如,numList[0]具有单元格O1/第一行的编号,numList[1]具有单元格O2/第二行的编号等)。

我几乎已经把电子表格中使用的公式(如果你点击单元格,你可以看到)转移到我的JavaScript代码中。然而,我的代码似乎工作不一样。

如果要输入";1天0小时0分0秒";在电子表格版本的表格的第一行中,您会看到第二行显示"0天23小时45分36秒"。但是,如果您在web版本中执行此操作,第二行将显示"0天23小时1425分85536秒"。显然,这是不正确的,因为"小时"不应该超过23(如果你选择2天,就会超过23),"分钟"one_answers"秒"也不应该超过59(因为时间就是这样工作的)。

我不明白为什么会发生这种事。在电子表格中,生成"秒"数的公式如下:

O2 - ((F2 * 60 * 60 * 24) + (H2 * 60 * 60) + (J2 * 60))

分解:

  • O2:位于单元格O2中的数字,在本例中为85536
  • F2:位于当天单元格中的数字,为0
  • H2:位于小时单元格中的数字,是23
  • J2:位于分钟单元格中的数字,是45

所以当我们将这些数字插入等式时:

85536 - ((0 * 60 * 60 * 24) + (23 * 60 * 60) + (45 * 60))
= 85536 - (0 + 82800 + 2700)
= 85536 - 85500
= 36

结果是36,这是第二列中显示的数字。很简单,是吗?

然而,尽管我在JavaScript代码中应用了这种精确的逻辑,但"秒"数是85536,而不是36。如果您还记得的话,这是第2行(23 hours, 45 minutes, 36 seconds = 85536 seconds)中给定时间的总秒数。这让我相信numList[i](在电子表格版本中是O2)出于某种原因没有减去等式的其余部分。

这是我的代码中与这个问题相关的部分(但上面链接了带有完整JS代码的整个repo)有问题的主要函数是代码中的最后一个函数(numbersCalc()),但我提供了所有相关函数,以防万一:

const daysInput = document.getElementById('days-input');
const hoursInput = document.getElementById('hours-input');
const minutesInput = document.getElementById('minutes-input');
const secondsInput = document.getElementById('seconds-input');
daysInput.addEventListener('change', numbers);
hoursInput.addEventListener('change', numbers);
minutesInput.addEventListener('change', numbers);
secondsInput.addEventListener('change', numbers);

// CALCULATE BASE NUMBER (CELL O1 IN SPREADSHEET)
function calculateBase(seconds, minutes, hours, days) {
// Spreadsheet equation: = L1 + (J1 * 60) + (H1 * 60 * 60) + (F1 * 60 * 60 * 24)
// L1: seconds
// J1: minutes
// H1: hours
// F1: days
seconds = Number(secondsInput.value);
minutes = Number(minutesInput.value);
hours = Number(hoursInput.value);
days = Number(daysInput.value);
const l1 = seconds;
const j1 = minutes;
const h1 = hours;
const f1 = days;
return (l1 + (j1 * 60) + (h1 * 60 * 60) + (f1 * 60 * 60 * 24));
}

// FORMULA TO CALCULATE REST OF NUMBERS FROM COLUMN 'O' IN SPREADSHEET
function calculateNumbers(num) {
/* Spreadsheet equation: 
= IFS(
(O1 - 60) < 0, 0, 
(O1 - (O1 * 0.99)) > 60, O1 * 0.99, 
(O1 - (O1 * 0.99))<= 60, O1 - 60, 
O1 = 0, 0
)
*/
const baseNumber = num;
let number = 0;
if((baseNumber - 60) < 0) {
number = 0;
} else if ((baseNumber - (baseNumber * 0.99)) > 60) {
number = baseNumber * 0.99;
} else if ((baseNumber - (baseNumber * 0.99)) <= 60) {
number = baseNumber - 60;
} else if (baseNumber === 0) {
number = 0;
}
return number;
}

// CREATE THE NUMLIST OBJECT, WHICH HOSTS NUMBERS FROM SPREADSHEET'S 'O' COLUMN
let numList = {};
function numbers() {
numList[0] = calculateBase();
for(let i = 1; i < 31; i++) {
numList[i] = Math.round(calculateNumbers(numList[i - 1]));
}
numbersCalc();
}

// CALCULATE NUMBERS FOR TABLE'S 'DAYS', 'HOURS', 'MINUTES', & 'SECONDS' CELLS
function numbersCalc() {
const tds = document.querySelectorAll('td');
tds.forEach(td => {
let daysBox = 0;
let hoursBox = 0;
let minutesBox = 0;
let secondsBox = 0;
for(let i = 0; i < 31; i++) {
if(td.classList.contains(`days-${i}`)) {
// Spreadsheet's equation: INT(O2 / (60 * 60 * 24))
daysBox = (numList[i] / (60 * 60 * 24))
td.textContent = parseInt(daysBox);
} else if (td.classList.contains(`hours-${i}`)) {
// Spreadsheet's equation: INT(O2 - (F2 * 60 * 60 * 24)) / (60 * 60)
hoursBox = (numList[i] - (daysBox * 60 * 60 * 24)) / (60 * 60);
td.textContent = parseInt(hoursBox);
} else if (td.classList.contains(`minutes-${i}`)) {
// Spreadsheet's equation: INT((O2 - (F2 * 60 * 60 * 24) - (H2 * 60 * 60)) / 60)
minutesBox = (numList[i] - (daysBox * 60 * 60 * 24) - (hoursBox * 60 * 60)) / 60;
td.textContent = parseInt(minutesBox);
} else if (td.classList.contains(`seconds-${i}`)) {
// Spreadsheet's equation: O2 - ((F2 * 60 * 60 * 24) + (H2 * 60 * 60) + (J2 * 60))
secondsBox = numList[i] - ((daysBox * 60 * 60 * 24) + (hoursBox * 60 * 60) + (minutesBox * 60));
td.textContent = parseInt(secondsBox);
}
}
})
}

请参阅jabaa的注释。

我会更改classNames,比如";第1天";变成";天";因为1表示行号。

我可以循环每个tr,初始化daysBox,hoursBox等等

然后在tr中循环每个td,并检查classNames(没有行号)。

相关内容

最新更新