无需切片ISOString,如何正确提取UTC日期时间并解决时区偏差?
解决UTC日期时间的正确提取问题
首先,你的问题根源在于日期字符串的解析时区不匹配:原JSON里的date是UTC时间,但直接用new Date(datetime)时,浏览器/JS引擎会把它当成本地时区的时间来解析,之后调用toISOString()转成UTC时就会出现时间偏移,导致你拿到的时间和预期不符。另外,字符串切片的方式确实不够优雅,我们可以用更规范的日期格式化方法来解决。
方案1:先正确解析UTC时间,再用UTC方法构建日期时间
首先,我们需要把原始的日期字符串标记为UTC时间(因为原JSON里明确说明时区是UTC),然后用Date的UTC相关方法来获取正确的年、月、日、时、分、秒,避免时区转换:
<tr v-for="(cabinet, i) in cabinets" :key="i"> <td>{{ cabinet.kitchen.id }}</td> <td>{{ cabinet.productCategory }}</td> <td>{{ formatDate(cabinet.time.date) }}</td> <td>{{ formatTime(cabinet.time.date) }}</td> </tr> <script> const axios = require('axios'); export default { name: "Cabinets", data() { return { bedroom : this.$session.get('bedroom').id, cabinets: [] } }, mounted() { axios({ method: 'GET', url: `/bedroom/${this.bedroom}/cabinets` }) .then(response => { this.cabinets = response.data }) }, methods: { parseUTCDate(datetimeStr) { // 给原始字符串加上Z,标记为UTC时间,避免被解析为本地时间 const utcDatetimeStr = datetimeStr.replace(' ', 'T') + 'Z'; return new Date(utcDatetimeStr); }, formatDate(datetimeStr) { const date = this.parseUTCDate(datetimeStr); // 使用UTC方法获取年、月、日,注意月份是0开始,要+1 const year = date.getUTCFullYear(); const month = String(date.getUTCMonth() + 1).padStart(2, '0'); const day = String(date.getUTCDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }, formatTime(datetimeStr) { const date = this.parseUTCDate(datetimeStr); const hours = String(date.getUTCHours()).padStart(2, '0'); const minutes = String(date.getUTCMinutes()).padStart(2, '0'); const seconds = String(date.getUTCSeconds()).padStart(2, '0'); return `${hours}:${minutes}:${seconds}`; } } } </script>
方案2:使用Intl.DateTimeFormat进行更简洁的格式化
ES6的Intl.DateTimeFormat可以直接指定时区进行格式化,代码更简洁,也不需要手动拼接字符串:
<tr v-for="(cabinet, i) in cabinets" :key="i"> <td>{{ cabinet.kitchen.id }}</td> <td>{{ cabinet.productCategory }}</td> <td>{{ formatDate(cabinet.time.date) }}</td> <td>{{ formatTime(cabinet.time.date) }}</td> </tr> <script> const axios = require('axios'); export default { name: "Cabinets", data() { return { bedroom : this.$session.get('bedroom').id, cabinets: [] } }, mounted() { axios({ method: 'GET', url: `/bedroom/${this.bedroom}/cabinets` }) .then(response => { this.cabinets = response.data }) }, methods: { parseUTCDate(datetimeStr) { const utcDatetimeStr = datetimeStr.replace(' ', 'T') + 'Z'; return new Date(utcDatetimeStr); }, formatDate(datetimeStr) { const date = this.parseUTCDate(datetimeStr); return new Intl.DateTimeFormat('en-US', { timeZone: 'UTC', year: 'numeric', month: '2-digit', day: '2-digit' }).format(date); }, formatTime(datetimeStr) { const date = this.parseUTCDate(datetimeStr); return new Intl.DateTimeFormat('en-US', { timeZone: 'UTC', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).format(date); } } } </script>
关键说明
- 为什么要加Z后缀?:原始日期字符串是
"2019-06-12 11:51:22.000000",没有时区标识,JS的new Date会默认按本地时区解析。加上Z后,字符串变成符合ISO 8601的UTC时间格式,new Date会正确解析为UTC时间。 - 避免字符串切片:用
getUTC*方法或Intl.DateTimeFormat可以更安全地格式化日期时间,不需要依赖字符串的固定长度,兼容性和可读性更好。 - 关于Time()错误:JS里没有
Time()构造函数,只有Date(),所以之前调用Time()会报错,这是你遇到另一个问题的原因。
内容的提问来源于stack exchange,提问作者user8678484
相关产品推荐
相关产品推荐

