时间的操作
ECMAScript 中的 Date 类型是在早期 Java 中的 java.util.Date 类基础上构建的。为此,Date 类型使用自 UTC (Coordinated Universal Time,国际协调时间)1970 年 1 月 1 日午夜(零时)开始经过的毫秒数来保存日期。在使用这种数据存储格式的条件下,Date 类型保存的日期能够精确到 1970 年 1 月 1 日之前或之后的 285 616 年。
判断时间是否在今天以前
通过传入一个时间的字符串,返回该时间相对于当前时间的对比。
试一试
示例代码
js
/**
*
* @param {String} time '2023-06-06 12:00:00'
*/
const timeCompare = (time) => {
const date1 = new Date(time.replace(/\-/g, '/'))
const date2 = new Date()
const num = 24 * 60 * 60 * 1000
const cha = date2.getTime() - date1.getTime()
if (cha > 0) {
if (cha > num) {
alert('不是今天的过去时间')
} else if (date1.getDate() !== date2.getDate()) {
alert('不是今天的过去时间')
} else {
alert('是今天里的过去时间')
}
} else if (cha < 0) {
alert('是未来时间')
} else {
alert('是现在')
}
}
日期格式化important
传入一个指定格式的字符串,和需要格式化的时间new Date()
或者是时间字符串2023-06-06 18:00:00
,返回对应的格式化后的时间字符串。
试一试
选择格式:
或者
输入格式:选择/输入的格式:fmt = yyyy-MM-dd
格式化的结果:2025-04-21
示例代码
js
/**
*
* @param {String | Date} time '2023-06-06' | new Date()
* @param {String} fmt 'yyyy-MM-dd hh:mm:ss'
*/
const format = function (time, fmt) {
time = time || new Date()
fmt = fmt || 'yyyy-MM-dd hh:mm:ss'
const typeOfTime = Object.prototype.toString.call(time).slice(8, -1)
let finalTime = time
if (typeOfTime !== 'Date') {
const transformT = new Date(time.replace(/\-/g, '/'))
const strT = transformT.toString()
if (strT.indexOf('Invalid Date') !== -1) {
alert('请输入正确格式的时间')
return
}
finalTime = transformT
}
const o = {
'M+': finalTime.getMonth() + 1, // 月
'd+': finalTime.getDate(), // 日
'h+': finalTime.getHours(), // 时
'm+': finalTime.getMinutes(), // 分
's+': finalTime.getSeconds(), // 秒
'q+': Math.floor((finalTime.getMonth() + 3) / 3), // 季度
S: finalTime.getMilliseconds(), // 毫秒
}
const a = /(y+)/.exec(fmt)
if (a && a[0]) {
fmt = fmt.replace(a[0], (finalTime.getFullYear() + '').substring(4 - a[0].length))
}
for (let k in o) {
const b = new RegExp('(' + k + ')').exec(fmt)
if (b && b[0]) {
fmt = fmt.replace(b[0], b[0].length === 1 ? o[k] : ('00' + o[k]).substring(('' + o[k]).length))
}
}
return fmt
}
获取不同时区的时间
getTimezoneOffset()
返回本地时间与 UTC 时间相差的分钟数。列如,中国标准时间返回-480。
试一试
选中时区的时间:2025-04-21 11:04:46
示例代码
js
/**
*
* @param {Number} i 时区,例如东八区 i = 8;西八区 i = -8
*/
const getLocalTime = (i) => {
const now = new Date()
const time = now.getTime()
const offset = now.getTimezoneOffset() * 60 * 1000 // 本地时间与UTC时间的偏移差(单位:ms)
const utcTime = time + offset // 得到现在的UTC时间,各时区UTC时间相同
return new Date(utcTime + 60 * 60 * 1000 * i) // 得到时区标准时间
}
获取指定结束时间的倒计时
给定一个结束时间的字符串,例如:2023-06-07 12:00:00
。开启当前时间到结束时间的倒计时。
试一试
选择的结束日期:
倒计时:
示例代码
js
/**
*
* @param {String} endTime 结束日期:2023-06-07 12:00:00
*/
const getEndTime = (endTime) => {
let startDate = new Date() //开始时间,当前时间
let endDate = new Date(endTime.replace(/\-/g, '/')) //结束时间,需传入时间参数
let t = endDate.getTime() - startDate.getTime() //时间差的毫秒数
let d = 0,
h = 0,
m = 0,
s = 0
if (t >= 0) {
d = Math.floor(t / 1000 / 3600 / 24)
h = Math.floor((t / 1000 / 60 / 60) % 24)
m = Math.floor((t / 1000 / 60) % 60)
s = Math.floor((t / 1000) % 60)
}
return `${d}天${h}小时${m}分钟${s}秒`
}
验证码倒计时
试一试
获取验证码
示例代码
js
const sendCode = () => {
if (sendStatus.disable) return
let times = 60
let timer = null
timer = setInterval(() => {
times--
if (times <= 0) {
sendStatus.text = '发送验证码'
clearInterval(timer)
sendStatus.disable = false
times = 60
} else {
sendStatus.text = times + '秒后重试'
sendStatus.disable = true
}
}, 1000)
}
实现一个日历
根据选择的年份和月份,显示出该月份的日历。
试一试
日
一
二
三
四
五
六
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
选择的日期:2025年4月21日
示例代码
- 定义 select 选择器,选择年份和月份。以及日历元素。
html
<div class="content">
<div class="selectWrap">
<div class="selectItem">
<label class="label">选择年份:</label>
<select class="year" v-model="selectYear">
<option v-for="option in years" :value="option">
<p>{{ option }}</p>
</option>
</select>
</div>
<div class="selectItem">
<label class="label">选择月份:</label>
<select class="month" v-model="selectMonth">
<option v-for="option in months" :value="option">
<p>{{ option }}</p>
</option>
</select>
</div>
</div>
<div class="calendarWrap">
<div class="calendarCell title" v-for="week in weeks">{{ week }}</div>
<div class="calendarCell" :class="[item.select ? 'select' : '', item.text === '' ? 'cannotSelect' : '', item.isToday ? item.select ? 'todaySelect' : 'isToday' : '']" v-for="item in calendar" @click="chooseCalendar(item)">{{ item.text }}</div>
</div>
<p><span>选择的日期是:</span>{{ choosedDate }}</p>
<span class="today" v-show="showToday" @click="backToToday">今</span>
</div>
- 编写逻辑
核心 getMothDays() 方法返回一个数组,包含选中月份的所有天数以及占位符。
days 获取的是选中月份总共有多少天。
week 获取的是选中月份第一天是周几,用于确定第一天之前有几个占位符。
js
import { ref, reactive, watch } from 'vue'
const now = new Date()
const nowYear = now.getFullYear()
const nowMonth = now.getMonth() + 1
const day = now.getDate()
const years = reactive([2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025])
const months = reactive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
const weeks = reactive(['日', '一', '二', '三', '四', '五', '六'])
const selectYear = ref(nowYear)
const selectMonth = ref(nowMonth)
const calendar = ref([])
const choosedDate = ref(`${selectYear.value}年${selectMonth.value}月${day}日`)
const showToday = ref(true)
const getMothDays = (year, month) => {
let result = []
const days = new Date(year, month, 0).getDate()
const week = new Date(`${year}/${month}/1`).getDay()
for (let i = 0; i < week; i++) {
result.push({
text: '',
select: false,
})
}
for (let i = 1; i <= days; i++) {
result.push({
text: i,
select: i === day,
isToday: i === day && selectYear.value === nowYear && selectMonth.value === nowMonth,
})
}
calendar.value = result
choosedDate.value = `${selectYear.value}年${selectMonth.value}月${day}日`
}
const chooseCalendar = (item) => {
if (item.text === '') return
calendar.value.forEach((i) => {
i.select = false
})
item.select = !item.select
choosedDate.value = `${selectYear.value}年${selectMonth.value}月${item.text}日`
}
const backToToday = () => {
selectYear.value = nowYear
selectMonth.value = nowMonth
getMothDays(nowYear, nowMonth)
}
watch(
[selectYear, selectMonth],
([year, month]) => {
getMothDays(year, month)
},
{
immediate: true,
}
)
watch(
choosedDate,
(val) => {
const str = val.replace(/[\u4E00-\u9FA5]+/g, '-')
const arr = str.split('-')
const year = nowYear
const month = nowMonth
console.log(year, month, day)
if (year === +arr[0] && month === +arr[1] && day === +arr[2]) {
showToday.value = false
} else {
showToday.value = true
}
},
{
immediate: true,
}
)
- 应用样式
scss
.content {
position: relative;
.selectWrap {
display: flex;
align-items: center;
font-size: 14px;
.selectItem {
margin-right: 20px;
.label {
margin-right: 5px;
}
.year {
width: 100px;
}
.month {
width: 50px;
}
}
}
.calendarWrap {
width: 400px;
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 0 5px;
border: 1px solid #ccc;
border-radius: 8px;
margin: 10px 0;
padding: 10px;
background: #fff;
.calendarCell {
width: 50px;
height: 50px;
border-radius: 50%;
line-height: 50px;
text-align: center;
cursor: pointer;
&.title {
cursor: auto;
}
&.select {
background: rgba(0, 0, 0, 0.1);
}
&.todaySelect {
background: #10b981;
color: #fff;
}
&.isToday {
background: #fff;
color: #10b981;
}
&.cannotSelect {
cursor: not-allowed;
}
}
}
.today {
position: absolute;
top: -25px;
left: 330px;
display: inline-block;
width: 50px;
height: 50px;
line-height: 50px;
text-align: center;
border-radius: 50%;
background: #10b981;
color: #fff;
cursor: pointer;
}
}