javascript - 转换日期 JavaScript
问题描述
我目前正在使用来自肥皂网络服务的数据填充表格,日期以字符串形式出现(例如 44250)。我创建了一个函数将其格式化为 yyyy/mm/dd 格式。
在循环之外我有这个功能:
Date.prototype.addDays = function (days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
};
在循环内我有:
else if (detailsItem == details[i].children[1].innerHTML) {
const dbDays = days[i].innerHTML;
const daysInt = parseInt(dbDays, 0);
const newDate = firstDate.addDays(daysInt);
// Format the date to a readable value
const partsDate = {
date: newDate.getDate(),
month: newDate.getMonth() + 1,
year: newDate.getYear() + 1900,
};
finalDate = `${partsDate.date}/${partsDate.month}/${partsDate.year}`;
const td = document.createElement("td");
td.textContent = finalDate;
tr.appendChild(td);
}
else if 只是在填充时检查何时将日期添加到表中。
我现在需要再次使用日期向服务发送请求,但使用以前的格式,但日期必须与按钮单击在同一行,服务只接受日期的字符串格式,我目前卡住并不确定如何格式化它。
这是按钮单击功能,它必须将日期格式化回诸如 44250 之类的格式。
btn.onclick = function () {
// Loops through the table to find the slot and date when clicking the button on the same row
var tableRow = document.getElementById("booking-table"),
rIndex;
for (var i = 0; i < tableRow.rows.length; i++) {
tableRow.rows[i].onclick = function () {
rIndex = this.rowIndex;
bookingDay = this.cells[1].innerHTML;
bookingSlot = this.cells[2].innerHTML;
console.log(bookingSlot, bookingDay);
};
}
任何有关如何实现此目的的帮助将不胜感激。
解决方案
值“44250”看起来像自 1899 年 12 月 31 日(纪元)以来的天数,这意味着值“1”转换为 1900 年 1 月 1 日。如果这是正确的,您可以使用它创建一个日期:
let dbDays = '44250';
let date = new Date(1900, 0, dbDays); // 24 Feb 2021
在这个算法中,1 是 1900 年 1 月 1 日,0 是 1899 年 12 月 31 日。
您可以使用反向算法将其转换回纪元偏移量:
let dbDays = Math.round((date.getTime() - new Date(1899, 11, 31) / 8.64e7);
它得到自日期和纪元以来的毫秒差异,然后在一天内除以毫秒并四舍五入以考虑可能的夏令时影响,其中天数不完全是 24 小时。此方法仅适用于全天,不适用于部分天。
如果 1900 年 1 月 1 日应该是 0 而不是 1,那么该算法可能会提前一天失效,只需调整函数中使用的基准日期即可。
从dbDate到Date实例并返回的简单函数是:
// Convert epoch days to Date
function toDate(dbDays) {
return new Date(1900, 0, +dbDays);
}
// Convert Date to epoch days
function toDBDays(date) {
return Math.round((date - new Date(1899,11,31)) / 8.64e7);
}
// Format date as dd/mm/yyyy
function formatDate(d) {
let z = n => ('0'+n).slice(-2);
return z(d.getDate()) + '/' + z(d.getMonth()+1) + '/' + d.getFullYear();
}
// Parse date in d/m/y format, any non-digit separator
function parseDate(s) {
let [d,m,y] = s.split(/\D/);
return new Date(y, m - 1, d)
}
// Example
let dbDays = '44250';
let d1 = toDate(dbDays); // 24 Feb 2021
let ts = formatDate(d1); // 24/02/2021
let d2 = parseDate(ts); // date object
console.log(dbDays + ' to Date: ' + ts);
console.log(ts + ' to dbDays: ' + toDBDays(d2));
PS 鉴于纪元不会改变,而不是创建 1899 年 12 月 31 日的日期并获取其时间值,可以使用常量 -2209111200000。
关于您的代码的注释:
const daysInt = parseInt(dbDays, 0);
parseInt的第二个参数是用于转换为数字的基数或基数。值 0 被替换为 10(默认基数),所以上面的等价于:
const daysInt = parseInt(dbDays, 10);
然后是:
const partsDate = {
date: newDate.getDate(),
month: newDate.getMonth() + 1,
year: newDate.getYear() + 1900,
};
getYear方法返回一个 2 位数的年份,不建议这样做,并且主要出于历史原因支持,请改用getFullYear。
使用对象进行临时存储并不是最佳选择,只需使用变量即可:
let date = newDate.getDate(),
month = newDate.getMonth() + 1,
year = newDate.getFullYear();
请注意,这不会用前导零填充个位数的日期或月份,因此会产生像 2021 年 1 月 1 日而不是 2021 年 1 月 1 日这样的时间戳。
推荐阅读
- c# - .NET MVC 类对象用于 linq
- php - 如何修复 Laravel 中未定义的变量错误?
- flutter - 为什么 Dart 不能定义依赖于另一个实例属性的实例属性
- weblogic12c - Weblogic Server 在会话 ID 生成期间包含 NONE 值
- python - 如何使用 pip 安装 gspread?
- xslt - Xpath3 表达式或 XSLT 代码以获取具有特定属性的所有节点名称,以便它们出现
- python - Pygame 如何制作斜坡?
- java - 如何使用 Camel Jms 事务回滚回滚 OracleDB 提交
- excel - Excel VBA || 在过滤范围内填充值
- f# - 如何在 Elmish.WPF 中完成子/子模型到父/主模型的消息传递?