时间戳转换与时间处理完全指南#
时间戳是编程中经常遇到的概念,无论是日志记录、数据存储还是API接口,时间处理都是必不可少的技能。本文将深入讲解时间戳的原理、转换方法和实战技巧。
什么是时间戳#
Unix时间戳#
Unix时间戳(Unix Timestamp)是指从1970年1月1日00:00:00 UTC到指定时间的总秒数(或毫秒数)。这个时间点被称为"Unix纪元"(Unix Epoch)。
1970-01-01 00:00:00 UTC => 0
2026-01-03 12:00:00 UTC => 1735900800
时间戳的精度#
- 秒级时间戳:10位数字,如
1735900800 - 毫秒级时间戳:13位数字,如
1735900800000 - 微秒级时间戳:16位数字
- 纳秒级时间戳:19位数字
时间戳与日期的转换#
JavaScript中的转换#
1. 获取当前时间戳#
1
2
3
4
5
6
7
8
9
10
11
| // 获取毫秒级时间戳(推荐)
const timestamp = Date.now();
console.log(timestamp); // 1735900800000
// 获取秒级时间戳
const timestampSeconds = Math.floor(Date.now() / 1000);
console.log(timestampSeconds); // 1735900800
// 使用getTime方法
const timestamp2 = new Date().getTime();
console.log(timestamp2); // 1735900800000
|
2. 时间戳转日期#
1
2
3
4
5
6
7
| // 毫秒级时间戳转日期
const timestamp = 1735900800000;
const date = new Date(timestamp);
console.log(date.toString()); // "Fri Jan 03 2026 12:00:00 GMT+0800"
console.log(date.toISOString()); // "2026-01-03T04:00:00.000Z"
console.log(date.toLocaleString()); // "2026/1/3 12:00:00"
|
3. 日期转时间戳#
1
2
3
4
5
6
7
8
| // 指定日期转时间戳
const date = new Date('2026-01-03 12:00:00');
const timestamp = date.getTime();
console.log(timestamp); // 1735900800000
// 使用Date构造函数
const timestamp2 = new Date(2026, 0, 3, 12, 0, 0).getTime();
console.log(timestamp2); // 1735900800000
|
4. 时间戳格式化#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // 格式化时间戳为指定格式
function formatTimestamp(timestamp, format = 'YYYY-MM-DD HH:mm:ss') {
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');
return format
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
}
// 使用示例
console.log(formatTimestamp(1735900800000)); // "2026-01-03 12:00:00"
console.log(formatTimestamp(1735900800000, 'YYYY年MM月DD日')); // "2026年01月03日"
|
Python中的转换#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| import time
from datetime import datetime
# 获取当前时间戳
timestamp = time.time()
print(timestamp) # 1735900800.123456
# 获取秒级时间戳
timestamp_seconds = int(time.time())
print(timestamp_seconds) # 1735900800
# 时间戳转日期
date = datetime.fromtimestamp(timestamp)
print(date.strftime('%Y-%m-%d %H:%M:%S')) # "2026-01-03 12:00:00"
# 日期转时间戳
timestamp2 = int(datetime(2026, 1, 3, 12, 0, 0).timestamp())
print(timestamp2) # 1735900800
|
Java中的转换#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
// 获取当前时间戳
long timestamp = System.currentTimeMillis();
System.out.println(timestamp); // 1735900800000
// 时间戳转日期
LocalDateTime dateTime = LocalDateTime.ofInstant(
Instant.ofEpochMilli(timestamp),
ZoneId.systemDefault()
);
System.out.println(dateTime.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
)); // "2026-01-03 12:00:00"
// 日期转时间戳
long timestamp2 = LocalDateTime.of(2026, 1, 3, 12, 0, 0)
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
System.out.println(timestamp2); // 1735900800000
|
时区处理#
UTC vs 本地时间#
1
2
3
4
5
6
7
8
9
10
11
| // UTC时间
const utcString = new Date().toUTCString();
console.log(utcString); // "Fri, 03 Jan 2026 04:00:00 GMT"
// 本地时间
const localString = new Date().toString();
console.log(localString); // "Fri Jan 03 2026 12:00:00 GMT+0800"
// ISO格式(UTC)
const isoString = new Date().toISOString();
console.log(isoString); // "2026-01-03T04:00:00.000Z"
|
时区转换#
1
2
3
4
5
6
7
8
9
| // 转换到指定时区
function convertToTimezone(timestamp, timezone) {
const date = new Date(timestamp);
return date.toLocaleString('en-US', { timeZone: timezone });
}
console.log(convertToTimezone(Date.now(), 'America/New_York'));
console.log(convertToTimezone(Date.now(), 'Asia/Tokyo'));
console.log(convertToTimezone(Date.now(), 'Europe/London'));
|
常见时间操作#
1. 时间加减#
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
31
32
| // 时间加减
function addTime(timestamp, amount, unit = 'days') {
const date = new Date(timestamp);
switch (unit) {
case 'years':
date.setFullYear(date.getFullYear() + amount);
break;
case 'months':
date.setMonth(date.getMonth() + amount);
break;
case 'days':
date.setDate(date.getDate() + amount);
break;
case 'hours':
date.setHours(date.getHours() + amount);
break;
case 'minutes':
date.setMinutes(date.getMinutes() + amount);
break;
case 'seconds':
date.setSeconds(date.getSeconds() + amount);
break;
}
return date.getTime();
}
// 使用示例
const now = Date.now();
console.log(formatTimestamp(addTime(now, 7, 'days'))); // 7天后
console.log(formatTimestamp(addTime(now, -1, 'months'))); // 1个月前
|
2. 时间差计算#
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
| // 计算时间差
function timeDifference(timestamp1, timestamp2) {
const diff = Math.abs(timestamp2 - timestamp1);
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
return {
milliseconds: diff,
seconds: seconds % 60,
minutes: minutes % 60,
hours: hours % 24,
days: days,
totalSeconds: seconds,
totalMinutes: minutes,
totalHours: hours,
totalDays: days
};
}
// 使用示例
const start = new Date('2026-01-01').getTime();
const end = new Date('2026-01-03').getTime();
console.log(timeDifference(start, end));
// { days: 2, totalDays: 2, totalHours: 48, ... }
|
3. 相对时间#
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
| // 相对时间格式化(如"3分钟前")
function formatRelativeTime(timestamp) {
const now = Date.now();
const diff = now - timestamp;
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(days / 365);
if (seconds < 60) {
return '刚刚';
} else if (minutes < 60) {
return `${minutes}分钟前`;
} else if (hours < 24) {
return `${hours}小时前`;
} else if (days < 30) {
return `${days}天前`;
} else if (months < 12) {
return `${months}个月前`;
} else {
return `${years}年前`;
}
}
// 使用示例
console.log(formatRelativeTime(Date.now() - 1000 * 60 * 5)); // "5分钟前"
|
4. 倒计时#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // 倒计时
function countdown(targetTimestamp) {
const now = Date.now();
const diff = targetTimestamp - now;
if (diff <= 0) {
return '已过期';
}
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
return `${days}天 ${hours}小时 ${minutes}分钟 ${seconds}秒`;
}
// 使用示例
const targetDate = new Date('2026-12-31 23:59:59').getTime();
console.log(countdown(targetDate)); // "XXX天 XX小时 XX分钟 XX秒"
|
实用工具函数#
1. 判断闰年#
1
2
3
4
5
6
| function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
console.log(isLeapYear(2024)); // true
console.log(isLeapYear(2025)); // false
|
2. 获取月份天数#
1
2
3
4
5
6
7
| function getDaysInMonth(year, month) {
return new Date(year, month, 0).getDate();
}
console.log(getDaysInMonth(2026, 1)); // 31 (1月)
console.log(getDaysInMonth(2026, 2)); // 28 (2月)
console.log(getDaysInMonth(2024, 2)); // 29 (闰年2月)
|
3. 获取星期几#
1
2
3
4
5
6
| function getWeekday(timestamp) {
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return weekdays[new Date(timestamp).getDay()];
}
console.log(getWeekday(Date.now())); // "周五"
|
4. 季度判断#
1
2
3
4
5
6
| function getQuarter(timestamp) {
const month = new Date(timestamp).getMonth() + 1;
return Math.ceil(month / 3);
}
console.log(getQuarter(Date.now())); // 1 (第一季度)
|
5. 时间范围验证#
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
| // 判断时间是否在指定范围内
function isInRange(timestamp, start, end) {
return timestamp >= start && timestamp <= end;
}
// 判断是否是今天
function isToday(timestamp) {
const date = new Date(timestamp);
const today = new Date();
return date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear();
}
// 判断是否是本周
function isThisWeek(timestamp) {
const date = new Date(timestamp);
const today = new Date();
const firstDay = new Date(today.setDate(today.getDate() - today.getDay()));
const lastDay = new Date(today.setDate(today.getDate() - today.getDay() + 6));
return date >= firstDay && date <= lastDay;
}
|
常见问题#
Q1: 为什么时间戳不对?#
可能的原因:
- 精度混淆:秒级和毫秒级时间戳混用
- 时区问题:本地时间和UTC时间混淆
- 服务器时间:服务器时间与本地时间不一致
1
2
3
4
5
6
7
8
9
10
11
12
| // 检测时间戳精度
function detectTimestampPrecision(timestamp) {
const timestampStr = String(timestamp);
if (timestampStr.length === 10) {
return 'seconds';
} else if (timestampStr.length === 13) {
return 'milliseconds';
} else {
return 'unknown';
}
}
|
Q2: 如何处理跨时区时间?#
1
2
3
4
5
6
7
8
| // 统一使用UTC时间存储,显示时转换到本地时区
function toLocalTime(utcTimestamp) {
return new Date(utcTimestamp).toLocaleString();
}
function toUTCTimestamp(localDate) {
return new Date(localDate).getTime();
}
|
Q3: 夏令时如何处理?#
1
2
| // 使用时区库处理夏令时
// 推荐使用 moment-timezone 或 date-fns-tz
|
性能优化#
1. 避免频繁创建Date对象#
1
2
3
4
5
6
7
8
9
10
| // 不好
for (let i = 0; i < 1000; i++) {
console.log(new Date().getTime());
}
// 好
const now = Date.now();
for (let i = 0; i < 1000; i++) {
console.log(now + i * 1000);
}
|
2. 缓存格式化结果#
1
2
3
4
5
6
7
8
| const formatCache = new Map();
function formatTimestampCached(timestamp) {
if (!formatCache.has(timestamp)) {
formatCache.set(timestamp, formatTimestamp(timestamp));
}
return formatCache.get(timestamp);
}
|
时间处理是编程中常见但容易出错的领域。掌握时间戳的转换和各种时间操作,能够帮助我们更好地处理业务逻辑。
记住这些要点:
- 统一使用UTC时间进行存储和传输
- 注意时间戳的精度(秒级 vs 毫秒级)
- 正确处理时区转换
- 使用成熟的日期库处理复杂场景
- 充分测试边界情况(闰年、月末等)