如何在JavaScript的forEach循环中处理CSV生成的Unix时间戳
解决JavaScript CSV生成中Unix时间戳的转换问题
我有一个生成CSV报告的JavaScript程序,当前问题是其中的时间戳为Unix Timestamp格式,需要在forEach循环中访问该字段并修改格式。我刚接触JavaScript,用Python处理这类问题毫无压力,但JS这边卡壳了。
原始处理记录的代码如下:
for (let electronicRecord of result.Values) { fields.forEach((f, i) => csvData += electronicRecord[f] + (i == fields.length -1 ? "\n" : delimiter)); }
我知道要修改的是electronicRecord["TimeStamp"],但不知道怎么在forEach循环里正确处理。尝试了下面的代码,但无法正常运行:
for (let i in fields) { if (i == "TimeStamp") { csvData += electronicRecord[i] } else if (fields.indexOf(i) == fields.length - 1) { csvData += electronicRecord[i] + "\n"; } else { csvData += electronicRecord[i] + delimiter; } }
fields是CSV的表头数组,以下是完整的原始函数:
// 注意:文件路径格式取决于设备和操作系统 // 你需要根据环境调整路径 // Unified Comfort设备(Linux系统)示例:/home/user1/data.dat // Unified PC设备(Windows系统)示例:C:\Users\Public\data.dat const startDate = "2020-09-01 08:00:00.000"; const endDate = "2020-10-01 08:00:00.000"; let moreFollows = false; let page = 0; let fields = ["TimeStamp", "AuditProviderType", "AuditProvider", "ObjectReference","ObjectName", "OperationType", "OperatorStation", "User", "OldValue", "NewValue", "Reason", "Language", "Signature", "Integrity"]; let delimiter = ","; let csvData = ""; fields.forEach((f, i) => csvData += f + (i == fields.length - 1 ? "\n" : delimiter)); do { try { const result = await HMIRuntime.Audit.SysFct.ReadElectronicRecord(startDate, endDate, page); moreFollows = result.More; for (let electronicRecord of result.Values) { fields.forEach((f, i) => csvData += electronicRecord[f] + (i == fields.length -1 ? "\n" : delimiter)); } page++; } catch(ex) { HMIRuntime.Trace("Error reading electronic record. Error: " + ex.message); return; } } while (moreFollows); try { let fileName = "C:\Users\Public\AuditFile.csv"; await HMIRuntime.FileSystem.WriteFile(fileName, csvData, "utf8"); HMIRuntime.Trace("Write file finished successfully"); } catch(ex) { HMIRuntime.Trace("Error writing file. Error: " + ex.message); }
问题分析与修复
你用for...in遍历数组的方式有误,for...in遍历的是数组的索引(数字字符串),而非数组元素值,所以i == "TimeStamp"永远不会成立,这是代码失效的核心原因。
正确的做法是继续使用forEach遍历fields数组,在遍历过程中判断当前字段是否为TimeStamp,如果是就先转换Unix时间戳为可读格式,再拼接到csvData中。
修改后的代码
替换原始循环部分的代码为:
for (let electronicRecord of result.Values) { fields.forEach((f, i) => { // 处理TimeStamp字段:转换Unix时间戳为日期字符串 let value = electronicRecord[f]; if (f === "TimeStamp") { // 假设TimeStamp是毫秒级Unix时间戳,转为系统可读格式 value = new Date(parseInt(value)).toLocaleString(); // 如果是秒级时间戳,需要乘以1000:new Date(parseInt(value)*1000).toLocaleString(); } // 拼接内容,处理分隔符和换行 csvData += value + (i === fields.length - 1 ? "\n" : delimiter); }); }
关键说明
forEach的第一个参数f是当前遍历的字段名(比如"TimeStamp"),直接判断f === "TimeStamp"即可定位目标字段。- 转换时间戳时,要确认你的Unix时间戳是秒级还是毫秒级:如果是秒级,需要乘以1000再传入
Date构造函数。 toLocaleString()会根据系统区域设置生成可读日期,也可以用toISOString()获取标准ISO格式,或者自定义格式化函数输出特定格式。
内容的提问来源于stack exchange,提问作者numberonegunner
相关产品推荐
相关产品推荐

