Date Convert - GUN、BSD时间戳转换

AI 摘要: 本文将介绍在Mac和Linux系统中的date命令的用法区别和解决方式,帮助程序员进行时间戳和字符串日期的转换。

引言

很多编程语言中,都可以将时间戳和字符串类型的日期进行转换,同样,在不同操作系统下(Mac 下的 date 命令是 BSD 系的,Linux 下 date 命令是 GNU 系的),两者的 date 用法有一些区别。

解决方式有两种,一种是熟悉两者差异,另一个办法是在 Mac 下安装 coreutils 包(GNU File, Shell, and Text utilities)

1. date 在 Mac 和 Linux 的输出

1.1. 时间格式的缩写相同

  • %Y 表示四位数形式的年份, 比如 2017
  • %m 表示带前导 0 的月份,比如 02,12
  • %d 表示带前导 0 的日子, 比如 02,28
  • %H 表示带前导 0 的 24 小时, 比如 01, 23
  • %M 表示带前导 0 的分钟数, 比如 05, 22
  • %S 表示带前导 0 的秒数, 比如 06,45
  • %s 表示距离格林威治时间(1970 年 1 月 1 日 0 点)的秒数

1.2. 当前时间输出

1
2
3
4
5
6
// 当前UTC时间格式输出
date
// 当前格式化时间输出
date +"%Y-%m-%d %H:%M:%S"
// 当前时间戳
date +%s

2. 时间格式转换

2.1. Mac,BSD 下 Mac 解析时间输入有差异(-jf..+和-r..+)

  • -j 需要与-f 指定格式配合一起,将一个输入的格式时间转成另一个
  • +指定输出格式,但需要通过-r 指定时间戳(另外注意-r 需要在格式化时间定义之前)
1
2
3
4
5
6
7
// [字符串时间=>时间戳]
$ date -jf "%Y-%m-%d %H:%M:%S" "2006-01-02 15:04:05" "+%s"
1136185445

// [时间戳=>字符串时间]
$ date -r 1136185445 +"%Y-%m-%d %H:%M:%S"
2006-01-02 15:04:05

2.2. linux,GUN 的 linux 下的时间格式转换语义较好(-d..+)

  • -d 指定时间格式描述@timestamp,或者字符串格式时间(-d 指定时间戳,在格式化定义前后均可)
  • +指定输出格式,比如+%s:时间戳,+"%Y-%m-%d %H:%M:%S"
1
2
3
4
5
6
// [字符串时间=>时间戳]
date -d "2006-01-02 15:04:05" "+%s"

// [时间戳=>字符串时间]
$ date -d @1136185445 +"%Y-%m-%d %H:%M:%S"
2006-01-02 15:04:05

3. 时间偏移格式输出,一个是基于-v,另一个是基于-d

1
2
3
4
// mac
$ date -v+1d -v+10m +"%Y-%m-%d %H:%M:%`S`"
// linux
$ date -d='-1 day -1 year' +%Y-%m-%d

4. 基于 coretuils,同等操作

基于 coreutils,可以直接加入 PATH 中,或者基于前缀gdate操作,相关参数和 GUN 一致

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ brew info coreutils
$ brew install coreutils

Commands also provided by macOS have been installed with the prefix "g".
If you need to use these commands with their normal names, you
can add a "gnubin" directory to your PATH from your bashrc like:
  PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"

// Mac下的gdate
$ gdate -d @1436781720 +"%Y-%m-%d %H:%M:%S"

4.1. Mac 下的 gate

1
2
// 操作通Linux下一致
$ gdate -d @1136185445 +"%Y-%m-%d %H:%M:%S"

5. Mysql 中时间戳转换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// [时间戳=>字符串时间]
select FROM_UNIXTIME(1136185445);
+---------------------------+
| FROM_UNIXTIME(1136185445) |
+---------------------------+
| 2006-01-02 07:04:05       |
+---------------------------+

// [时间戳=>字符串时间]
Select UNIX_TIMESTAMP("2006-01-02 15:04:05");
+---------------------------------------+
| UNIX_TIMESTAMP("2006-01-02 15:04:05") |
+---------------------------------------+
|                            1136214245 |
+---------------------------------------+