【问题标题】:Converting Excel Time to moment.js将 Excel 时间转换为 moment.js
【发布时间】:2018-09-29 05:47:21
【问题描述】:

我有一个 Electron 应用程序,其中需要导入包含几列包含时间值的 Excel 表。在我的应用程序中,这些值在循环中转换为 momentjs 对象以供进一步操作:

x['Time'] = moment(x['Time'], ['HH:mm','HH:mm:ss']).format('HH:mm:ss');

只要 Excel 包含格式为文本的时间值,此方法就可以正常工作。但是,如果 Excel 按预期方式设置,则 Cell 的值是介于 0 和 1 之间的数字(Excel 在内部将时间计算为浮点数 - 例如,0,5 转换为 12:00:00)。

有谁知道我如何将它翻译回momentjs的可读时间值?

【问题讨论】:

  • 如何从 Excel 导出数据?你在用VBA吗?还是您使用电子表格解析器?
  • 我使用社区版的sheetjs进行导入和导出功能。

标签: javascript excel time momentjs


【解决方案1】:
export const parseDateExcel = (excelTimestamp) => {
    const secondsInDay = 24 * 60 * 60;
    const excelEpoch = new Date(1899, 11, 31);
    const excelEpochAsUnixTimestamp = excelEpoch.getTime();
    const missingLeapYearDay = secondsInDay * 1000;
    const delta = excelEpochAsUnixTimestamp - missingLeapYearDay;
    const excelTimestampAsUnixTimestamp = excelTimestamp * secondsInDay * 1000;
    const parsed = excelTimestampAsUnixTimestamp + delta;
    return isNaN(parsed) ? null : parsed;
};

用法:

new Date(parseDateExcel(36902.49097)) //=> Thu Jan 11 2001 11:46:59 GMT+0000 (Greenwich Mean Time)

Source

【讨论】:

  • 但是,据我所知,这段代码是从 Unix 时间戳解析的。在我的 Excel 中没有日期字段。这只是一个简单的时间,它包含一个介于 0 和 1 之间的数字。所以 17:30:00 是 0,729166666666667 或 12:50:00 是 0,534722222222222
  • 没有。它根本不会从 Unix Timestamp 解析。它将 Excel DateTime 数据类型解析为 JavaScript 时间(基于 Unix 纪元)。所有 Excel 日期时间都从 1899 年 12 月 30 日星期六开始。您不能在 Excel 中表示该日期之前的日期。因此,要单独使用 toTimeString() 方法和正则表达式? /\d\d:\d\d:\d\d/.exec((new Date(parseDateExcel(0.5))).toTimeString())[0] //=> "12:00:00"
  • 对不起。我花了一些时间来弄清楚这一点,但你当然是对的。 Excel 中的时间的行为就像一个日期时间字段,只是 . 左侧的值始终设置为 0,所以它只代表一天。
【解决方案2】:

据我所知,这是使用 Excel 时间十进制值。 所以根据Excel,时间文本用0到1的十进制数表示。

function excelDateToJSDate(excel_date, time = false) {
  let day_time = excel_date % 1
  let meridiem = "AMPM"
  let hour = Math.floor(day_time * 24)
  let minute = Math.floor(Math.abs(day_time * 24 * 60) % 60)
  let second = Math.floor(Math.abs(day_time * 24 * 60 * 60) % 60)
  hour >= 12 ? meridiem = meridiem.slice(2, 4) : meridiem = meridiem.slice(0, 2)
  hour > 12 ? hour = hour - 12 : hour = hour
  hour = hour < 10 ? "0" + hour : hour
  minute = minute < 10 ? "0" + minute : minute
  second = second < 10 ? "0" + second : second
  let daytime = "" + hour + ":" + minute + ":" + second + " " + meridiem
  return time ? daytime : (new Date(0, 0, excel_date, 0, -new Date(0).getTimezoneOffset(), 0)).toLocaleDateString(navigator.language, {}) + " " + daytime
};

首先我们定义正午,然后处理小时、分钟和秒,然后验证给定小时是上午还是下午,作为格式化时尚偏好,我们将 24 小时约定更改为 12 小时,并在任何时间添加填充零值小于 10,最后以字符串形式返回时间或日期。

示例

function excelDateToJSDate(excel_date, time = false) {
  let day_time = excel_date % 1
  let meridiem = "AMPM"
  let hour = Math.floor(day_time * 24)
  let minute = Math.floor(Math.abs(day_time * 24 * 60) % 60)
  let second = Math.floor(Math.abs(day_time * 24 * 60 * 60) % 60)
  hour >= 12 ? meridiem = meridiem.slice(2, 4) : meridiem = meridiem.slice(0, 2)
  hour > 12 ? hour = hour - 12 : hour = hour
  hour = hour < 10 ? "0" + hour : hour
  minute = minute < 10 ? "0" + minute : minute
  second = second < 10 ? "0" + second : second
  let daytime = "" + hour + ":" + minute + ":" + second + " " + meridiem
  return time ? daytime : (new Date(0, 0, excel_date, 0, -new Date(0).getTimezoneOffset(), 0)).toLocaleDateString(navigator.language, {}) + " " + daytime
};

console.log(excelDateToJSDate(0.125, true));
console.log(excelDateToJSDate(43556));

【讨论】:

    【解决方案3】:

    由于我找不到真正的答案,这里有一个对我有用的答案:

    let fromExcel = 0,709722222222222; //translates to 17:02:00
    let basenumber = (fromExcel*24)
    let hour = Math.floor(basenumber).toString();
    if (hour.length < 2) {
        hour = '0'+hour;
    }
    
    var minute = Math.round((basenumber % 1)*60).toString();
    if (minute.length < 2) {
     minute = '0'+minute;
    }
    let Timestring = (hour+':'+minute+':00');
    

    所以我有一个字符串momentjs可以翻译。我不将此标记为答案的原因是肯定有更好的转换方式,我找不到计算秒数的解决方案(在我的特殊情况下这无关紧要,因为我不使用它们)。

    【讨论】:

      猜你喜欢
      • 2016-05-24
      • 2016-02-19
      • 1970-01-01
      • 1970-01-01
      • 2017-09-10
      • 1970-01-01
      • 2015-05-20
      • 2017-08-24
      • 1970-01-01
      相关资源
      最近更新 更多