Invoiced API 时间戳数字如何转换为日期?
数据小许
结论
这些数字是 Unix 时间戳,单位是秒。它们记录的是从 1970-01-01 00:00:00 UTC 起经过的秒数,并非毫秒数。
例如:
1493732122
对应的 UTC 时间为:
2017-05-02 12:15:22 UTC
如果转换失败,通常是因为应用将它误当成了毫秒时间戳。日期 API 要求传入毫秒时,需要先乘以 1000:
1493732122 × 1000 = 1493732122000
JavaScript 转换
JavaScript 的 Date 构造函数接收毫秒时间戳,所以需要乘以 1000:
const timestamp = 1493732122;
const date = new Date(timestamp * 1000);
console.log(date.toISOString());
// 2017-05-02T12:15:22.000Z
console.log(date.toLocaleString());
三个字段可以统一转换:
const subscription = {
renewed_last: 1493732122,
renews_next: 1496410522,
start_date: 1493732122
};
const dates = {
renewed_last: new Date(subscription.renewed_last * 1000),
renews_next: new Date(subscription.renews_next * 1000),
start_date: new Date(subscription.start_date * 1000)
};
console.log(dates.renewed_last.toISOString());
console.log(dates.renews_next.toISOString());
console.log(dates.start_date.toISOString());
其他常见语言
PHP
PHP 的日期函数通常可以直接接收秒级 Unix 时间戳:
<?php
$timestamp = 1493732122;
echo gmdate('Y-m-d H:i:s', $timestamp);
// 2017-05-02 12:15:22
如果要按服务器配置的本地时区显示:
echo date('Y-m-d H:i:s', $timestamp);
Python
from datetime import datetime, timezone
timestamp = 1493732122
utc_date = datetime.fromtimestamp(timestamp, tz=timezone.utc)
print(utc_date.isoformat())
# 2017-05-02T12:15:22+00:00
转换为本地时区:
local_date = datetime.fromtimestamp(timestamp)
print(local_date)
Java
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
long timestamp = 1493732122L;
Instant instant = Instant.ofEpochSecond(timestamp);
System.out.println(instant);
// 2017-05-02T12:15:22Z
ZonedDateTime localDate =
instant.atZone(ZoneId.systemDefault());
System.out.println(localDate);
为什么容易误判
Unix 时间戳常见的单位有两种:
- 秒级时间戳通常是 10 位,例如
1493732122 - 毫秒级时间戳通常是 13 位,例如
1493732122000
这里的数据是 10 位,应该按秒处理。不同语言的日期 API 对单位的要求并不相同。JavaScript 的 Date 使用毫秒,而 PHP 的 date()、Python 的 datetime.fromtimestamp() 和 Java 的 Instant.ofEpochSecond() 都可以直接处理秒级时间戳。
时区注意事项
Unix 时间戳表示一个确定的时间点,本身不包含时区。转换后显示的日期和时间,取决于转换时使用的时区。
存储、传输或排查数据时,建议先转换为 UTC:
new Date(1493732122 * 1000).toISOString()
向用户展示时,再转换成用户所在时区。不要通过给时间戳加减固定小时数来修正显示时间,否则在实行夏令时的地区可能出错。
备注:内容仅供参考。
