Tutorial
JavaScript时间戳转换完全教程:详细示例和最佳实践
简介
在JavaScript中转换时间戳是Web开发人员的基本技能。无论您是在处理API、数据库还是用户界面,您都会经常需要在Unix时间戳和人类可读日期之间进行转换。本教程将指导您了解需要知道的一切。
您将学到什么
- ✅ 获取当前时间戳
- ✅ 将时间戳转换为Date对象
- ✅ 将Date对象转换为时间戳
- ✅ 格式化时间戳以供显示
- ✅ 处理不同的时间戳精度
- ✅ 处理时区
- ✅ 常见陷阱及避免方法
前提条件
只需要基本的JavaScript知识。本教程不需要外部库(虽然我们会在最后提到一些流行的库)。
步骤1:获取当前时间戳
最简单的操作 - 将当前时间作为时间戳获取。
方法1:Date.now()(推荐)
// 获取毫秒级当前时间戳
const timestamp = Date.now();
console.log(timestamp);
// 输出:1704067200000(13位)
为什么使用这个?
- ✅ 最快的方法
- ✅ 无需创建Date对象
- ✅ 最常用
方法2:new Date().getTime()
// 创建Date对象并获取时间戳
const timestamp = new Date().getTime();
console.log(timestamp);
// 输出:1704067200000(13位)
何时使用?
- 当您已经有Date对象时
- 当您需要链式调用方法时
方法3:一元加号运算符
// 使用一元加号的简写
const timestamp = +new Date();
console.log(timestamp);
// 输出:1704067200000(13位)
何时使用?
- 代码高尔夫或简洁性很重要时
- 不推荐初学者使用(可读性较差)
获取秒级时间戳
JavaScript默认使用毫秒,但许多API使用秒:
// 获取秒级时间戳(10位)
const timestampInSeconds = Math.floor(Date.now() / 1000);
console.log(timestampInSeconds);
// 输出:1704067200(10位)
// 替代方法:使用parseInt
const timestampSec = parseInt(Date.now() / 1000);
console.log(timestampSec);
// 输出:1704067200
步骤2:将时间戳转换为Date对象
将Unix时间戳转换为JavaScript Date对象。
基本转换
// 毫秒时间戳(13位)
const timestamp = 1704067200000;
const date = new Date(timestamp);
console.log(date);
// 输出:Mon Jan 01 2024 00:00:00 GMT+0000 (UTC)
console.log(date.toISOString());
// 输出:2024-01-01T00:00:00.000Z
转换秒级时间戳
许多API返回秒级时间戳(10位),而不是毫秒:
// 秒级时间戳(10位)- 必须乘以1000!
const timestampInSeconds = 1704067200;
const date = new Date(timestampInSeconds * 1000);
console.log(date.toISOString());
// 输出:2024-01-01T00:00:00.000Z
⚠️ 常见错误:
// ❌ 错误:直接使用秒级时间戳
const wrongDate = new Date(1704067200);
console.log(wrongDate.toISOString());
// 输出:1970-01-20T17:27:47.200Z(错误!)
// ✅ 正确:乘以1000
const correctDate = new Date(1704067200 * 1000);
console.log(correctDate.toISOString());
// 输出:2024-01-01T00:00:00.000Z(正确!)
检测时间戳精度
自动检测时间戳是秒还是毫秒的辅助函数:
function createDateFromTimestamp(timestamp) {
// 如果时间戳有10位,则为秒
// 如果时间戳有13位,则为毫秒
const digitCount = timestamp.toString().length;
if (digitCount === 10) {
// 秒 - 乘以1000
return new Date(timestamp * 1000);
} else if (digitCount === 13) {
// 毫秒 - 直接使用
return new Date(timestamp);
} else {
throw new Error(`无效的时间戳:${timestamp}`);
}
}
// 使用方法
const date1 = createDateFromTimestamp(1704067200); // 10位(秒)
const date2 = createDateFromTimestamp(1704067200000); // 13位(毫秒)
console.log(date1.toISOString()); // 2024-01-01T00:00:00.000Z
console.log(date2.toISOString()); // 2024-01-01T00:00:00.000Z
步骤3:将Date对象转换为时间戳
将JavaScript Date对象转换回Unix时间戳。
从当前日期
const now = new Date();
// 获取毫秒时间戳
const timestampMs = now.getTime();
console.log(timestampMs); // 1704067200000
// 获取秒级时间戳
const timestampSec = Math.floor(now.getTime() / 1000);
console.log(timestampSec); // 1704067200
从特定日期字符串
// ISO 8601格式(推荐)
const date1 = new Date('2024-01-01T00:00:00Z');
console.log(date1.getTime()); // 1704067200000
// 不同的日期格式
const date2 = new Date('January 1, 2024');
const date3 = new Date('01/01/2024');
const date4 = new Date('2024-01-01');
console.log(date2.getTime()); // 取决于本地时区
console.log(date3.getTime()); // 取决于本地时区
console.log(date4.getTime()); // 通常为本地时区的00:00:00
⚠️ 重要: 不同的日期字符串格式在时区方面表现不同!
从日期组件
// 从年、月、日等创建日期
// 注意:月份从0开始索引(0 = 一月,11 = 十二月)
const date = new Date(2024, 0, 1, 0, 0, 0); // 2024年1月1日 00:00:00
const timestamp = date.getTime();
console.log(timestamp); // 本地时区时间戳
// 对于UTC,使用Date.UTC()
const utcTimestamp = Date.UTC(2024, 0, 1, 0, 0, 0);
console.log(utcTimestamp); // 1704067200000(UTC)
步骤4:格式化时间戳
将时间戳转换为人类可读格式。
JavaScript内置方法
const date = new Date(1704067200000);
// ISO 8601格式(最适合API)
console.log(date.toISOString());
// 输出:"2024-01-01T00:00:00.000Z"
// 特定区域设置的日期字符串
console.log(date.toLocaleDateString());
// 输出:"1/1/2024"(美国)或"01/01/2024"(英国)
// 特定区域设置的日期和时间
console.log(date.toLocaleString());
// 输出:"1/1/2024, 12:00:00 AM"
// 特定区域设置的时间
console.log(date.toLocaleTimeString());
// 输出:"12:00:00 AM"
// 完整日期字符串
console.log(date.toDateString());
// 输出:"Mon Jan 01 2024"
// UTC字符串
console.log(date.toUTCString());
// 输出:"Mon, 01 Jan 2024 00:00:00 GMT"
自定义格式化
function formatTimestamp(timestamp, format = 'full') {
const date = new Date(timestamp);
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');
const formats = {
'full': `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`,
'date': `${year}-${month}-${day}`,
'time': `${hours}:${minutes}:${seconds}`,
'short': `${month}/${day}/${year}`,
'iso': date.toISOString()
};
return formats[format] || formats.full;
}
// 使用方法
const timestamp = 1704067200000;
console.log(formatTimestamp(timestamp, 'full')); // "2024-01-01 00:00:00"
console.log(formatTimestamp(timestamp, 'date')); // "2024-01-01"
console.log(formatTimestamp(timestamp, 'time')); // "00:00:00"
console.log(formatTimestamp(timestamp, 'short')); // "01/01/2024"
使用Intl.DateTimeFormat(现代方法)
const timestamp = 1704067200000;
const date = new Date(timestamp);
// 美式英语格式
const usFormatter = new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
console.log(usFormatter.format(date));
// 输出:"2024年1月1日 00:00"
// 自定义格式
const customFormatter = new Intl.DateTimeFormat('zh-CN', {
weekday: 'long',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: 'short'
});
console.log(customFormatter.format(date));
// 输出:"2024年1月1日星期一 00:00:00 UTC"
步骤5:处理时区
处理不同的时区对于准确的时间戳转换至关重要。
UTC与本地时间
const timestamp = 1704067200000; // 2024年1月1日 00:00:00 UTC
const date = new Date(timestamp);
// 获取UTC组件
console.log('UTC年份:', date.getUTCFullYear()); // 2024
console.log('UTC月份:', date.getUTCMonth() + 1); // 1
console.log('UTC日期:', date.getUTCDate()); // 1
console.log('UTC小时:', date.getUTCHours()); // 0
// 获取本地组件(取决于您的时区)
console.log('本地年份:', date.getFullYear()); // 2024
console.log('本地月份:', date.getMonth() + 1); // 1(或不同)
console.log('本地日期:', date.getDate()); // 1(或不同)
console.log('本地小时:', date.getHours()); // 0(或不同)
转换到特定时区
const timestamp = 1704067200000;
const date = new Date(timestamp);
// 使用Intl.DateTimeFormat在不同时区显示
const timezones = ['America/New_York', 'Europe/London', 'Asia/Shanghai'];
timezones.forEach(tz => {
const formatter = new Intl.DateTimeFormat('zh-CN', {
timeZone: tz,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: 'short'
});
console.log(`${tz}:`, formatter.format(date));
});
// 输出:
// America/New_York: 2023/12/31 19:00:00 EST
// Europe/London: 2024/01/01 00:00:00 GMT
// Asia/Shanghai: 2024/01/01 08:00:00 GMT+8
时区偏移
const date = new Date();
// 获取时区偏移(分钟)
const offsetMinutes = date.getTimezoneOffset();
console.log('偏移(分钟):', offsetMinutes); // 例如,-480表示UTC+8
// 转换为小时
const offsetHours = -offsetMinutes / 60;
console.log('偏移(小时):', offsetHours); // 例如,8表示UTC+8
// 格式化偏移为字符串
const sign = offsetHours >= 0 ? '+' : '-';
const hours = String(Math.abs(Math.floor(offsetHours))).padStart(2, '0');
const minutes = String(Math.abs((offsetHours % 1) * 60)).padStart(2, '0');
console.log(`UTC${sign}${hours}:${minutes}`); // 例如,"UTC+08:00"
步骤6:常见陷阱和解决方案
陷阱1:秒vs毫秒
// ❌ 错误:假设所有时间戳都是毫秒
const wrongDate = new Date(1704067200); // 当作毫秒处理
console.log(wrongDate.toISOString()); // 1970-01-20T17:27:47.200Z(错误!)
// ✅ 正确:正确检查和转换
const secondsTimestamp = 1704067200;
const correctDate = new Date(secondsTimestamp * 1000);
console.log(correctDate.toISOString()); // 2024-01-01T00:00:00.000Z(正确!)
陷阱2:月份从零开始索引
// ❌ 错误:对月份使用1-12
const wrongDate = new Date(2024, 1, 1); // 创建2月1日,而不是1月1日
console.log(wrongDate.toDateString()); // Thu Feb 01 2024
// ✅ 正确:对月份使用0-11
const correctDate = new Date(2024, 0, 1); // 创建1月1日
console.log(correctDate.toDateString()); // Mon Jan 01 2024
陷阱3:日期字符串的时区问题
// 不同的字符串格式表现不同!
// 带'Z'的ISO 8601 - 始终为UTC
const utcDate = new Date('2024-01-01T00:00:00Z');
console.log(utcDate.toISOString()); // 2024-01-01T00:00:00.000Z
// 不带'Z'的ISO 8601 - 当作本地时区处理
const localDate = new Date('2024-01-01T00:00:00');
console.log(localDate.toISOString()); // 取决于您的时区
// 仅日期格式 - 当作本地时区午夜处理
const dateOnly = new Date('2024-01-01');
console.log(dateOnly.toISOString()); // 通常为本地午夜
// ✅ 最佳实践:始终使用带'Z'的ISO 8601表示UTC
const safeDate = new Date('2024-01-01T00:00:00.000Z');
陷阱4:无效日期
// 无效日期可能导致静默错误
const invalidDate = new Date('不是日期');
console.log(invalidDate); // Invalid Date
console.log(invalidDate.getTime()); // NaN
// ✅ 最佳实践:始终验证
function isValidDate(date) {
return date instanceof Date && !isNaN(date.getTime());
}
const date1 = new Date('2024-01-01');
const date2 = new Date('invalid');
console.log(isValidDate(date1)); // true
console.log(isValidDate(date2)); // false
步骤7:实际示例
示例1:显示"多久以前"格式
function timeAgo(timestamp) {
const now = Date.now();
const secondsAgo = Math.floor((now - timestamp) / 1000);
if (secondsAgo < 60) {
return `${secondsAgo}秒前`;
} else if (secondsAgo < 3600) {
const minutes = Math.floor(secondsAgo / 60);
return `${minutes}分钟前`;
} else if (secondsAgo < 86400) {
const hours = Math.floor(secondsAgo / 3600);
return `${hours}小时前`;
} else {
const days = Math.floor(secondsAgo / 86400);
return `${days}天前`;
}
}
// 使用方法
console.log(timeAgo(Date.now() - 30000)); // "30秒前"
console.log(timeAgo(Date.now() - 300000)); // "5分钟前"
console.log(timeAgo(Date.now() - 7200000)); // "2小时前"
console.log(timeAgo(Date.now() - 172800000)); // "2天前"
示例2:API响应处理器
// 典型的带时间戳的API响应
const apiResponse = {
created_at: 1704067200, // 秒
updated_at: 1704153600000, // 毫秒(混合精度!)
expires_at: "2024-01-10T00:00:00Z" // ISO 8601字符串
};
// 将所有转换为Date对象
function parseApiTimestamps(response) {
return {
created: new Date(response.created_at * 1000), // 转换秒
updated: new Date(response.updated_at), // 已经是毫秒
expires: new Date(response.expires_at) // 解析ISO字符串
};
}
const dates = parseApiTimestamps(apiResponse);
console.log('创建:', dates.created.toLocaleDateString());
console.log('更新:', dates.updated.toLocaleDateString());
console.log('过期:', dates.expires.toLocaleDateString());
示例3:日期范围验证器
function isWithinRange(timestamp, startDate, endDate) {
const date = new Date(timestamp);
const start = new Date(startDate);
const end = new Date(endDate);
return date >= start && date <= end;
}
// 使用方法
const eventTimestamp = 1704067200000; // 2024年1月1日
const rangeStart = '2024-01-01';
const rangeEnd = '2024-12-31';
console.log(isWithinRange(eventTimestamp, rangeStart, rangeEnd)); // true
用于高级用例的流行库
对于生产应用,请考虑这些库:
date-fns(推荐)
import { format, parseISO, formatDistance } from 'date-fns';
import { zhCN } from 'date-fns/locale';
// 格式化时间戳
const timestamp = 1704067200000;
const formatted = format(timestamp, 'PPP', { locale: zhCN });
console.log(formatted); // "2024年1月1日"
// 多久以前
const distance = formatDistance(timestamp, Date.now(), {
addSuffix: true,
locale: zhCN
});
console.log(distance); // "2天前"
Luxon(现代、时区感知)
import { DateTime } from 'luxon';
// 从时间戳
const dt = DateTime.fromMillis(1704067200000);
console.log(dt.toISO()); // "2024-01-01T00:00:00.000Z"
// 时区转换
const shanghai = dt.setZone('Asia/Shanghai');
console.log(shanghai.toFormat('yyyy-MM-dd HH:mm:ss'));
总结
您已经学会了如何:
- ✅ 使用
Date.now()获取当前时间戳 - ✅ 将时间戳转换为Date对象
- ✅ 将Date对象转换回时间戳
- ✅ 格式化日期以供显示
- ✅ 处理不同的时间戳精度
- ✅ 处理时区
- ✅ 避免常见陷阱
相关工具
使用我们的免费工具练习所学内容:
- Unix时间戳转换器 - 交互式时间戳转换
- 当前时间戳 - 获取各种格式的当前时间
- JavaScript时间戳助手 - JavaScript特定工具
- 批量时间戳转换器 - 转换多个时间戳
下一步
最后更新:2025年1月