Skip to content

Date 日期对象

日期和时间处理是开发中的常见需求。JavaScript 的 Date 对象提供了日期时间的基本操作能力。

🎯 创建日期#

当前时间#

// 创建当前日期时间
const now = new Date()
console.log(now) // Wed Jan 15 2025 10:30:00 GMT+0800
// 获取时间戳(毫秒)
console.log(Date.now()) // 1736912400000
console.log(now.getTime()) // 同上
console.log(+now) // 同上(一元加号转数字)

指定日期#

// 传入时间戳(毫秒)
const date1 = new Date(1736912400000)
// 传入日期字符串
const date2 = new Date('2025-01-15')
const date3 = new Date('2025-01-15T10:30:00')
const date4 = new Date('January 15, 2025 10:30:00')
// 传入年月日时分秒(月份从0开始!)
const date5 = new Date(2025, 0, 15) // 2025年1月15日
const date6 = new Date(2025, 0, 15, 10, 30, 0) // 带时分秒
// 🔶 注意:月份是 0-11,不是 1-12
new Date(2025, 0, 1) // 1月1日
new Date(2025, 11, 31) // 12月31日

日期字符串格式#

// ISO 8601 格式(推荐)
new Date('2025-01-15') // 解析为 UTC 时间
new Date('2025-01-15T10:30:00') // 本地时间
new Date('2025-01-15T10:30:00Z') // UTC 时间
new Date('2025-01-15T10:30:00+08:00') // 带时区
// 其他格式(兼容性可能有问题)
new Date('01/15/2025') // MM/DD/YYYY
new Date('Jan 15 2025')
new Date('15 Jan 2025')
// 🔶 不同浏览器解析结果可能不同
// 建议使用 ISO 格式或时间戳

获取日期信息#

获取各部分#

const date = new Date('2025-01-15T10:30:45.123')
// 年月日
date.getFullYear() // 2025
date.getMonth() // 0(一月,范围 0-11)
date.getDate() // 15(日期,范围 1-31)
date.getDay() // 3(星期三,0=周日,1-6=周一到周六)
// 时分秒毫秒
date.getHours() // 10
date.getMinutes() // 30
date.getSeconds() // 45
date.getMilliseconds() // 123
// 时间戳
date.getTime() // 毫秒时间戳
date.valueOf() // 同 getTime()
// 时区偏移(分钟)
date.getTimezoneOffset() // -480(东八区,即 -8 小时)

UTC 时间#

const date = new Date('2025-01-15T10:30:00+08:00')
// 获取 UTC 时间(比北京时间早8小时)
date.getUTCFullYear() // 2025
date.getUTCMonth() // 0
date.getUTCDate() // 15
date.getUTCHours() // 2(10 - 8 = 2)
date.getUTCMinutes() // 30
date.getUTCSeconds() // 0

设置日期#

设置各部分#

const date = new Date()
// 设置年月日
date.setFullYear(2025)
date.setMonth(11) // 12月
date.setDate(25)
// 设置时分秒
date.setHours(12)
date.setMinutes(0)
date.setSeconds(0)
date.setMilliseconds(0)
// 设置时间戳
date.setTime(1736912400000)
// 链式调用(每个方法返回时间戳)
const timestamp = new Date().setFullYear(2025)
// 返回的是时间戳,不是 Date 对象

日期溢出自动修正#

// 日期会自动修正
const date = new Date(2025, 0, 32) // 1月32日
console.log(date) // 2月1日
// 利用这个特性获取月末
function getLastDayOfMonth(year, month) {
// 下个月的第0天 = 这个月的最后一天
return new Date(year, month + 1, 0).getDate()
}
getLastDayOfMonth(2025, 0) // 31(1月)
getLastDayOfMonth(2025, 1) // 28(2月,非闰年)
getLastDayOfMonth(2024, 1) // 29(2月,闰年)

日期格式化#

内置方法#

const date = new Date('2025-01-15T10:30:00')
// 转字符串
date.toString()
// 'Wed Jan 15 2025 10:30:00 GMT+0800 (中国标准时间)'
date.toDateString() // 'Wed Jan 15 2025'
date.toTimeString() // '10:30:00 GMT+0800 (中国标准时间)'
date.toLocaleDateString() // '2025/1/15'
date.toLocaleTimeString() // '10:30:00'
date.toLocaleString() // '2025/1/15 10:30:00'
// ISO 格式
date.toISOString() // '2025-01-15T02:30:00.000Z'(UTC)
date.toJSON() // 同 toISOString()
// UTC 字符串
date.toUTCString() // 'Wed, 15 Jan 2025 02:30:00 GMT'

toLocaleString 选项#

const date = new Date('2025-01-15T10:30:00')
// 自定义格式
date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
})
// '2025年1月15日星期三'
date.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
// '10:30:00'
date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
})
// '2025/01/15 10:30'
// 不同地区
date.toLocaleDateString('en-US') // '1/15/2025'
date.toLocaleDateString('ja-JP') // '2025/1/15'
date.toLocaleDateString('de-DE') // '15.1.2025'

自定义格式化函数#

function formatDate(date, format) {
const map = {
YYYY: date.getFullYear(),
MM: String(date.getMonth() + 1).padStart(2, '0'),
DD: String(date.getDate()).padStart(2, '0'),
HH: String(date.getHours()).padStart(2, '0'),
mm: String(date.getMinutes()).padStart(2, '0'),
ss: String(date.getSeconds()).padStart(2, '0'),
}
return format.replace(/YYYY|MM|DD|HH|mm|ss/g, (matched) => map[matched])
}
const date = new Date('2025-01-15T10:30:45')
formatDate(date, 'YYYY-MM-DD') // '2025-01-15'
formatDate(date, 'YYYY/MM/DD HH:mm:ss') // '2025/01/15 10:30:45'
formatDate(date, 'MM月DD日') // '01月15日'

日期计算#

时间差#

const start = new Date('2025-01-01')
const end = new Date('2025-01-15')
// 毫秒差
const diffMs = end - start // 1209600000
// 转换为其他单位
const diffSeconds = diffMs / 1000
const diffMinutes = diffMs / (1000 * 60)
const diffHours = diffMs / (1000 * 60 * 60)
const diffDays = diffMs / (1000 * 60 * 60 * 24) // 14
// 计算年龄
function getAge(birthday) {
const today = new Date()
const birth = new Date(birthday)
let age = today.getFullYear() - birth.getFullYear()
const monthDiff = today.getMonth() - birth.getMonth()
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
age--
}
return age
}
getAge('1990-05-20') // 34(假设今天是2025年1月)

日期增减#

// 加减天数
function addDays(date, days) {
const result = new Date(date)
result.setDate(result.getDate() + days)
return result
}
const date = new Date('2025-01-15')
addDays(date, 7) // 2025-01-22
addDays(date, -7) // 2025-01-08
// 加减月份
function addMonths(date, months) {
const result = new Date(date)
result.setMonth(result.getMonth() + months)
return result
}
addMonths(date, 1) // 2025-02-15
addMonths(date, -1) // 2024-12-15
// 通用函数
function addTime(date, value, unit) {
const result = new Date(date)
switch (unit) {
case 'year':
result.setFullYear(result.getFullYear() + value)
break
case 'month':
result.setMonth(result.getMonth() + value)
break
case 'day':
result.setDate(result.getDate() + value)
break
case 'hour':
result.setHours(result.getHours() + value)
break
case 'minute':
result.setMinutes(result.getMinutes() + value)
break
}
return result
}

日期比较#

const date1 = new Date('2025-01-15')
const date2 = new Date('2025-01-20')
// 比较(转为时间戳)
date1 < date2 // true
date1 > date2 // false
date1.getTime() === date2.getTime() // false
// 判断是否同一天
function isSameDay(d1, d2) {
return (
d1.getFullYear() === d2.getFullYear() &&
d1.getMonth() === d2.getMonth() &&
d1.getDate() === d2.getDate()
)
}
// 判断是否今天
function isToday(date) {
return isSameDay(date, new Date())
}
// 判断是否闰年
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
}
isLeapYear(2024) // true
isLeapYear(2025) // false

实用函数#

获取特定日期#

// 获取今天的开始和结束
function getStartOfDay(date = new Date()) {
const result = new Date(date)
result.setHours(0, 0, 0, 0)
return result
}
function getEndOfDay(date = new Date()) {
const result = new Date(date)
result.setHours(23, 59, 59, 999)
return result
}
// 获取本周一
function getMonday(date = new Date()) {
const result = new Date(date)
const day = result.getDay()
const diff = day === 0 ? -6 : 1 - day
result.setDate(result.getDate() + diff)
return getStartOfDay(result)
}
// 获取本月第一天和最后一天
function getFirstDayOfMonth(date = new Date()) {
return new Date(date.getFullYear(), date.getMonth(), 1)
}
function getLastDayOfMonth(date = new Date()) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0)
}
// 获取某月的天数
function getDaysInMonth(year, month) {
return new Date(year, month + 1, 0).getDate()
}

相对时间#

function timeAgo(date) {
const now = new Date()
const past = new Date(date)
const diffMs = now - past
const diffSeconds = Math.floor(diffMs / 1000)
const diffMinutes = Math.floor(diffSeconds / 60)
const diffHours = Math.floor(diffMinutes / 60)
const diffDays = Math.floor(diffHours / 24)
const diffMonths = Math.floor(diffDays / 30)
const diffYears = Math.floor(diffDays / 365)
if (diffSeconds < 60) return '刚刚'
if (diffMinutes < 60) return `${diffMinutes}分钟前`
if (diffHours < 24) return `${diffHours}小时前`
if (diffDays < 30) return `${diffDays}天前`
if (diffMonths < 12) return `${diffMonths}个月前`
return `${diffYears}年前`
}
timeAgo(new Date(Date.now() - 1000 * 60 * 5)) // '5分钟前'
timeAgo(new Date(Date.now() - 1000 * 60 * 60 * 3)) // '3小时前'

倒计时#

function countdown(targetDate) {
const now = new Date()
const target = new Date(targetDate)
const diff = target - now
if (diff <= 0) {
return { days: 0, hours: 0, minutes: 0, seconds: 0 }
}
return {
days: Math.floor(diff / (1000 * 60 * 60 * 24)),
hours: Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),
minutes: Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)),
seconds: Math.floor((diff % (1000 * 60)) / 1000),
}
}
countdown('2025-02-01')
// { days: 17, hours: 13, minutes: 29, seconds: 15 }

注意事项#

月份从 0 开始#

// 🔶 最常见的错误
new Date(2025, 1, 15) // 2月15日,不是1月15日!
// ✅ 正确写法
new Date(2025, 0, 15) // 1月15日
new Date('2025-01-15') // 使用字符串避免混淆

时区问题#

// 字符串解析的时区差异
new Date('2025-01-15') // UTC 时间
new Date('2025-01-15T00:00:00') // 本地时间
// 建议:明确指定时区
new Date('2025-01-15T00:00:00+08:00') // 明确北京时间

Date 对象是可变的#

const date = new Date('2025-01-15')
const copy = date // 🔶 这只是引用,不是复制!
copy.setDate(20)
console.log(date.getDate()) // 20,原对象也被修改了
// ✅ 正确复制
const realCopy = new Date(date)
const realCopy2 = new Date(date.getTime())

总结#

方法说明
new Date()当前时间
Date.now()当前时间戳
getFullYear/Month/Date获取年/月/日
getHours/Minutes/Seconds获取时/分/秒
setFullYear/Month/Date设置年/月/日
toLocaleDateString本地化日期字符串
toISOStringISO 格式字符串
getTime获取时间戳

核心要点