让时间戳乖乖变成我要的样子

275 阅读2分钟
  • 服务器会经常性的返回时间戳,有时是10位的秒,有时是13位的毫秒;
  • 界面上,有时需要展示成具体的表现格式; 有时呢,又希望给出倒计时
  • 有时表现上,希望给的是年月日 时:分:秒;有时又希望日 时-分-秒
  • 有时希望补0,有时不希望不0

所以我希望封装一个工具函数,只需要传入时间戳,传入希望返回的形式,就能自动返回成我想要的结果;

function parseTimestamp(timestamp, toForm) {}

因为时间基本表现无非就是年月日时分秒,因此这边就约定形式为{y}-{m}-{d} {h}:{i}:{s}

开始封装- 时间戳转换成对应的时间表现形式

/**
 * 
 * @param {timestamp} 时间戳 10位或者13位 
 * @param {*} targetForm 希望返回表现形式 默认'{y}-{m}-{d} {h}:{i}:{s}'
 * @returns '2021年05月12日 05:12:13'
 */
function parseTimestamp(timestamp = 0, targetForm = '{y}-{m}-{d} {h}:{i}:{s}', padStart0 = true) {
    if (!timestamp) return ''
    timestamp = timestamp.toString().length === 10 ? parseInt(timestamp) * 1000
    let date = new Date(timestamp)
    // console.log(date)  Wed Jan 12 2022 14:49:22 GMT+0800 (中国标准时间)
    const formObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    }
     // console.log(formObj) 
     // {"y": 2022,  "m": 1, "d": 12,"h": 14,i": 49,"s": 22, "a": 3}
     // 接下来要将该对象`formObj`妆换成我们需要的表现形式
    return dateToTargetForm(dateObj, targetForm, padStart0)
    
}

function dateToTargetForm(dateObj, targetForm, padStart0) {
    return targetForm.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
        let value = dateObj[key]
        if (key === 'a') { 
            return '星期'+['日', '一', '二', '三', '四', '五', '六'][value] 
        }
        if (padStart0 && result.length > 0 && value < 10) {
          value = '0' + value
        }
        return value || 0
  })
}

调用示范

parseTime(time,'{m}月{d}日 星期{a} {h}:{i}')

除了上述场景,我们还经常碰到,有时服务器返回截止时间/有时是剩余的秒数,产品希望我们页面上显示对应的倒计时,不足月时,显示剩余 {d}天{h}时{i}分;不足天时,显示剩余 {h}时{i}分,不足时时,显示剩余 {i}分${s}秒

因此我们需要封装一个函数,传入剩余的时间,返回对应的表现形式

传入剩余的时间,返回对应的表现形式

const MINUTE_SECONDS = 60 // 1分为60秒
const HOUR_SECONDS = 3600
const DAY_SECONDS = 86400
/**
 * @param {remainTime} 剩余时间,单位秒
 * @param {*} targetForm 希望返回表现形式 默认'{y}-{m}-{d} {h}:{i}:{s}'
 * @returns '2021年05月12日 05:12:13'
 */
funtion calcRemainTime(remainTime, targetForm, padStart0 = true) {
    const dateObj = {
        d: Math.floor(remainTime / DAY_SECONDS),
        h: Math.floor((remainTime % DAY_SECONDS) / HOUR_SECONDS),
        i: Math.floor((remainTime % HOUR_SECONDS) / MINUTE_SECONDS),
        s: Math.floor((remainTime % MINUTE_SECONDS))
    }
    // 接下来要将该对象`dateObj`妆换成我们需要的表现形式
    return dateToTargetForm(dateObj, targetForm, padStart0)
}

进一步升级如果服务器直接返回的截止时间

function deadlineTimeToCutdown(deadline) {
    const now = parseInt(Date.now() / 1000)
    let remainTime = endTime - now
    if (remainTime <= 0) return
    const targetForm = remainTime <= DAY_SECONDS ? '{h}时{i}分{s}秒' : '{d}天{h}时{i}分'
    const dateObj = {
        d: Math.floor(remainTime / DAY_SECONDS),
        h: Math.floor((remainTime % DAY_SECONDS) / HOUR_SECONDS),
        i: Math.floor((remainTime % HOUR_SECONDS) / MINUTE_SECONDS),
        s: Math.floor((remainTime % MINUTE_SECONDS))
    }
    // 接下来要将该对象`formObj`妆换成我们需要的表现形式
    return dateToTargetForm(dateObj, targetForm, padStart0)
}

再进一步升级,自动进行倒计时处理;倒计时间隔,如果出现秒,时间间隔就是1秒,或者1分钟;因为不会设计用户在一个页面停留时间超过小时的情况,所以我们暂不考虑那场景

let cutdownInterval = null
function deadlineTimeToCutdown(deadline, compareTime ) {
    compareTime = compareTime ||  parseInt(Date.now() / 1000)
    let remainTime = endTime - compareTime
    if (remainTime <= 0) return
    const targetForm = remainTime <= DAY_SECONDS ? '{h}时{i}分{s}秒' : '{d}天{h}时{i}分'
   const stepReduceSecond = remainTime <= DAY_SECONDS ? 1 : 60
   const timeout = stepReduceSecond * 1000
   const dateObj = {
        d: Math.floor(remainTime / DAY_SECONDS),
        h: Math.floor((remainTime % DAY_SECONDS) / HOUR_SECONDS),
        i: Math.floor((remainTime % HOUR_SECONDS) / MINUTE_SECONDS),
        s: Math.floor((remainTime % MINUTE_SECONDS))
    }
    
   cutdownInterval = setInterval(() => {
        if (remainTime <= 0) {
          clearInterval(cutdownInterval)
          return
        }
        remainTime -= stepReduceSecond
        const timeStr = deadlineTimeToCutdown(remainTime, compareTime)
        return timeStr
   }, timeout)
}

封装成全局指令示例

import Vue from 'vue'
import { parseTime } from '@/utils/parseTime'

const formatTime = (time) => parseTimestamp(time)

Vue.filter('$parseTimestamp', parseTimestamp)// 插入过滤器名和对应方法

ss