前端日期使用心得

662 阅读3分钟

1. el-date-picker 不同时区选择问题

问题

业务系统需要在不同的国家地区显示一样的时间. 但是el-date-picker组件默认是根据当前操作系统对应的时区显示时间

  • 当在英国,电脑默认使用英国时区,
    • 当前选择日期时间为: 2024-04-30 1:00:00 , 组件获取的日期对应时间戳为2024-04-30 1:00:00
  • 当在中国, 电脑默认使用中国时区,
    • 当前选择日期时间为: 2024-04-30 1:00:00 , 组件获取的日期对应时间戳为2024-04-30 8:00:00 所以最终不同的用户在不同的地区选择日期后,保存到后台的时间戳会不一致

时间的概念与工具

格林尼治标准时间

  • 英国伦敦郊区的皇家格林尼治天文台的标准时间,本初子午线被定义在通过那里的经线, 为零度经线
  • 地球表面按经线从左到右递增,每相隔15度划一个区域,这样一共有24个区域,每一个区域相差1小时

东8区

  • 在地图上看: 从英国->中国,左->右 , 往右东边移动了8个区,时差7小时 (由于一个15度不一定刚好等于完整的一个小时)

image.png

  • 地球自转的方向是自西向东, 从左到右. 即太阳先照到中国再照到英国, 中国的时间会比英国早7个小时 世界时间 (piliapp.com) image.png

电脑时区选择地方

image.png

image.png

时间戳

通过时间戳的统一时间,时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数

时间戳有两种单位

  • 毫秒

由于业务只关心到秒,所以保存到后台只存秒单位数据.

moment.js

Moment.js 中文网 | 开发文档 (momentjs.cn)

moment.js使用方法总结

moment工具简单好用 ,支持格式化 比较等

//转化:
//时间戳字符串(秒为单位) 转字符串格式化
 let formatStr =  moment.unix(300000).format('YYYY-MM-DD HH:mm:ss') 
//把字符串转时间戳(单位秒)
let moment('2024-04-30 8:00:00').unix()
//把字符串转时间戳(单位毫秒)
let moment('2024-04-30 8:00:00')

//比较 
let now = new Date()  
moment('2024-04-30 8:00:00').isBefore(moment(now)) //是否小于现在
moment('2024-04-30 8:00:00').isAfter(moment(now)) //是否大于现在

方案

方案1:

让所有使用后台的用户都调整系统的时间时区(该方案不现实)

方案2:

直接存字符串,不存时间戳. 缺点:字符串无法做日期的比较, 需要做转化

方案3:

前端通过选择的内容获取字符串,然后根据当前字符串转换为时间戳,再给后台

el-date-picker 支持3种格式化获取时间的方式 DateTimePicker 日期时间选择器 image.png 我们可以看到选中相同的时间,访问的信息格式都是不一样的

  • Date类型 (默认,不靠谱因为包含中国时间信息)
  • value-format (字符串格式化 靠谱)
  • 时间戳 (不靠谱,因为包含中国时间信息后再转成时间戳) 由于不同地区el-detapicker 会自动显示不同的当前日期时间,所以只能选择value-format
 <el-date-picker
        v-model="value_show"
        type="datetime"
        placeholder="Pick a Date"
        format="YYYY-MM-DD HH:mm:ss"
        value-format="YYYY-MM-DD HH:mm:ss"
 />  
<script lang="ts" setup>
import { ref } from 'vue'
const value_show = ref('')  //这里记录的是UI选择的日期
let value = moment(value_show.value).unix() //把格式化显示字符串(不带时区)转成时间戳
// todo 这时候value 就可以提交给后台了 

// 其他地方显示的时候只需要 
moment.unix(value).format("YYYY-MM-DD HH:mm:ss")

</script> 

2. ios时间处理问题

问题

ios 老一点的设备不支持 日期格式化 YYYY-MM-DD 的写法,只支持 YYYY/MM/DD

方案

通过正则把 - 替换为 / 即可

let start_time = '2024-04-20 11:30:10'
var stime = new Date(start_time.replace(/-/g, "/")).getTime();