Date对象概述
JavaScript使用Date对象处理日期和时间:
- 基于Unix时间戳(1970年1月1日以来的毫秒数)
- 支持本地时间和UTC时间
- 提供丰富的日期时间操作方法
- 月份从0开始(0=1月,11=12月)
- 星期从0开始(0=周日,6=周六)
- 时间精度为毫秒级
创建Date对象
有多种方式可以创建Date对象:
创建Date对象
// 当前日期和时间
let now = new Date();
console.log(now); // 当前时间的字符串表示
// 从时间戳创建
let timestamp = new Date(1640995200000); // 2022-01-01
// 从日期字符串创建
let dateStr = new Date("2023-12-25");
let dateStr2 = new Date("December 25, 2023");
// 从年、月、日等参数创建
let specificDate = new Date(2023, 11, 25); // 2023年12月25日 (月从0开始)
let specificTime = new Date(2023, 11, 25, 15, 30, 0); // 2023-12-25 15:30:00
// Date.now() - 当前时间戳
let currentTimestamp = Date.now();
console.log(currentTimestamp); // 当前时间的毫秒数
获取日期时间信息
获取日期时间信息
let date = new Date(2023, 11, 25, 15, 30, 45, 123);
// 获取时间戳
console.log(date.getTime()); // 时间戳 (毫秒)
console.log(date.valueOf()); // 同上
// 获取年、月、日
console.log(date.getFullYear()); // 2023 (推荐)
console.log(date.getYear()); // 123 (不推荐, 返回年份-1900)
console.log(date.getMonth()); // 11 (0-11)
console.log(date.getDate()); // 25 (1-31)
console.log(date.getDay()); // 1 (星期几, 0=周日, 6=周六)
// 获取时间
console.log(date.getHours()); // 15 (0-23)
console.log(date.getMinutes()); // 30 (0-59)
console.log(date.getSeconds()); // 45 (0-59)
console.log(date.getMilliseconds());// 123 (0-999)
// UTC时间方法 (在方法名后加UTC)
console.log(date.getUTCFullYear()); // UTC年份
console.log(date.getUTCHours()); // UTC小时
设置日期时间
设置日期时间
let date = new Date();
// 设置年、月、日
date.setFullYear(2024);
date.setMonth(5); // 6月 (0-11)
date.setDate(15);
// 设置时间
date.setHours(14);
date.setMinutes(30);
date.setSeconds(0);
date.setMilliseconds(0);
console.log(date); // 2024-06-15 14:30:00
// 使用时间戳设置
date.setTime(1640995200000); // 设置为2022-01-01
// UTC设置方法
date.setUTCFullYear(2024);
date.setUTCHours(12);
// 自动调整日期 (设置32会自动转到下个月)
let testDate = new Date(2023, 0, 32); // 2023-02-01
console.log(testDate);
日期格式化
日期格式化
let date = new Date(2023, 11, 25, 15, 30, 45);
// 内置格式化方法
console.log(date.toString()); // "Mon Dec 25 2023 15:30:45 GMT+0800 (中国标准时间)"
console.log(date.toDateString()); // "Mon Dec 25 2023"
console.log(date.toTimeString()); // "15:30:45 GMT+0800 (中国标准时间)"
console.log(date.toLocaleString());// "2023/12/25 15:30:45" (本地格式)
console.log(date.toLocaleDateString()); // "2023/12/25"
console.log(date.toLocaleTimeString()); // "15:30:45"
// ISO格式
console.log(date.toISOString()); // "2023-12-25T07:30:45.000Z" (UTC时间)
console.log(date.toJSON()); // 同上
// UTC格式
console.log(date.toUTCString()); // "Mon, 25 Dec 2023 07:30:45 GMT"
// 自定义格式化函数
function formatDate(date, format = 'YYYY-MM-DD') {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return format
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
}
console.log(formatDate(date)); // "2023-12-25"
console.log(formatDate(date, 'YYYY/MM/DD HH:mm:ss')); // "2023/12/25 15:30:45"
console.log(formatDate(date, 'DD-MM-YYYY')); // "25-12-2023"
日期计算
日期计算
// 日期比较
let date1 = new Date(2023, 0, 1);
let date2 = new Date(2023, 0, 15);
console.log(date1 < date2); // true
console.log(date1 > date2); // false
console.log(date1.getTime() === date2.getTime()); // false
// 日期差值计算 (毫秒)
let diffMs = date2 - date1;
let diffDays = diffMs / (1000 * 60 * 60 * 24);
console.log(diffDays); // 14
// 添加天数
function addDays(date, days) {
let result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
let futureDate = addDays(new Date(), 7);
console.log(futureDate); // 7天后的日期
// 计算两个日期之间的天数
function daysBetween(date1, date2) {
const oneDay = 1000 * 60 * 60 * 24;
const diffMs = Math.abs(date2 - date1);
return Math.floor(diffMs / oneDay);
}
console.log(daysBetween(new Date(2023, 0, 1), new Date(2023, 0, 15))); // 14
// 计算年龄
function calculateAge(birthDate) {
const today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
}
let birthDate = new Date(1990, 5, 15);
console.log(calculateAge(birthDate)); // 当前年龄
时间戳操作
时间戳操作
// 获取各种时间戳
let now = new Date();
console.log(now.getTime()); // 毫秒时间戳
console.log(now.valueOf()); // 同上
console.log(Date.now()); // 当前时间戳
console.log(+now); // 同上 (使用一元加运算符)
// 时间戳转换
function timestampToDate(timestamp) {
return new Date(timestamp);
}
function dateToTimestamp(date) {
return date.getTime();
}
// 性能测量
let startTime = Date.now();
// 模拟耗时操作
for (let i = 0; i < 1000000; i++) {
// 空循环
}
let endTime = Date.now();
console.log(`操作耗时: ${endTime - startTime} 毫秒`);
// 高精度时间戳 (performance.now())
let perfStart = performance.now();
// 一些操作...
let perfEnd = performance.now();
console.log(`高精度耗时: ${perfEnd - perfStart} 毫秒`);
时区处理
时区处理
let date = new Date();
// 获取时区信息
console.log(date.getTimezoneOffset()); // 时区偏移 (分钟)
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone); // 时区名称
// 本地时间 vs UTC时间
console.log(`本地时间: ${date.toString()}`);
console.log(`UTC时间: ${date.toUTCString()}`);
console.log(`ISO时间: ${date.toISOString()}`);
// 国际化日期格式
let formatter = new Intl.DateTimeFormat('zh-CN', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: 'long'
});
console.log(formatter.format(date)); // "2023年12月25日星期一 15:30:45 中国标准时间"
// 不同地区的日期格式
let usFormatter = new Intl.DateTimeFormat('en-US');
let deFormatter = new Intl.DateTimeFormat('de-DE');
console.log(usFormatter.format(date)); // "12/25/2023"
console.log(deFormatter.format(date)); // "25.12.2023"
日历功能实现
使用JavaScript实现日历功能,包括日期选择、月份切换等:
简单日历实现
// 生成一个月历
function generateCalendar(year, month) {
let firstDay = new Date(year, month, 1);
let lastDay = new Date(year, month + 1, 0);
// 获取第一天是星期几 (0=周日)
let firstDayOfWeek = firstDay.getDay();
// 日历数组
let calendar = [];
let week = [];
// 填充前面的空白
for (let i = 0; i < firstDayOfWeek; i++) {
week.push(null);
}
// 填充日期
for (let day = 1; day <= lastDay.getDate(); day++) {
week.push(day);
// 如果一周满了,开始新的一周
if (week.length === 7) {
calendar.push(week);
week = [];
}
}
// 填充后面的空白
if (week.length > 0) {
while (week.length < 7) {
week.push(null);
}
calendar.push(week);
}
return calendar;
}
// 使用示例
let calendar = generateCalendar(2023, 11); // 2023年12月
console.log(calendar);
日期验证和处理
验证日期格式和有效性:
日期验证函数
// 验证日期字符串是否有效
function isValidDate(dateString) {
let date = new Date(dateString);
return date instanceof Date && !isNaN(date);
}
// 检查是否是闰年
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
// 获取月份天数
function getDaysInMonth(year, month) {
return new Date(year, month + 1, 0).getDate();
}
// 使用示例
console.log(isValidDate("2023-02-30")); // false
console.log(isValidDate("2023-12-25")); // true
console.log(isLeapYear(2024)); // true
console.log(getDaysInMonth(2023, 1)); // 28 (2月)
常用日期库推荐
对于复杂的日期处理,推荐使用以下库:
- Moment.js - 功能强大的日期处理库
- date-fns - 轻量级、模块化的日期工具库
- Day.js - Moment.js的轻量级替代品
- Luxon - 现代化的日期和时间库
date-fns使用示例
// 使用date-fns库的示例
// 首先需要安装: npm install date-fns
// import { format, addDays, differenceInDays } from 'date-fns';
// 格式化日期
// console.log(format(new Date(), 'yyyy-MM-dd'));
// 添加天数
// console.log(addDays(new Date(), 7));
// 计算日期差
// console.log(differenceInDays(new Date(2023, 11, 25), new Date()));
实践练习
最佳实践
- 使用
Date.now()而不是new Date().getTime()获取时间戳 - 处理用户输入时总是验证日期格式
- 在存储和传输时使用ISO格式或时间戳
- 考虑使用库如moment.js或date-fns处理复杂日期操作
- 注意月份从0开始,星期从0(周日)开始
- 使用
Intl.DateTimeFormat进行国际化日期显示 - 对于性能敏感的代码,避免频繁创建Date对象
- 在服务器和客户端之间传递日期时,使用UTC时间