日期时间字符串与epoch的转换

请先epoch与24时区的关系 理解基本概念

日期时间字符串转换成epoch

date-parse函数可以将字符串转换成秒数,这个功能相当方便。

> (setq e (date-parse "20140720 06:29" "%Y%m%d %H:%M"))
1405837740

注意

1. 06:29也可以是6:29, 加不加0都可以, 这很方便。:)

2. date-parse 接受的时间字符串参数要小心时区

像本例中的没有指明时区的就会被默认为UTC时区

3. 获取到的秒数是epoch的值, 没有包含时区的偏移,也是UTC时间的秒数。必须明确,epoch只有一个时区,就是UTC。


将epoch转换成日期时间字符串

这时候需要使用date函数。把上面得到的epoch:1405837740再转回去看看

注意:

date函数接收的参数是UTC的epoch

但是返回的却是当前时区的日期时间字符串

> (date e)
"Sun Jul 20 14:29:00 2014"

这里14:29比06:29多个8个小时,就是因为我们处于GMT+8时区。结果是正确的,只不过转换成了不同的时区。

offset参数

date函数是先将秒数转换成本地时区的时间,然后再看有没有offset参数。offset参数可以帮助转换成其他时区。

由于GMT+8 比 UTC多8小时,所以转换到UTC需要减去8小时,因此offset参数如下

> (date 1405837740 (- (* 8 60)))
"Sun Jul 20 06:29:00 2014"


用在线站点做了对比, 结果正确.

http://www.epochconverter.com/

date-parse获得指定时区时间的epoch

前面说过时间日期字符串里也是可以表达时区的, 据说是%z或者 %Z来格式化,但是没找到具体的例子。

如果没有指定时区,date-parse会认为这个日期时间字符串表示的是UTC时区。但是如果实际上这个字符串表示的是中国时间,GMT+8呢?

比如:"Sun Jul 20 14:29:00 2014" 里面没有包含时区格式,但是我们知道这是北京时间。所以需要对转换后的epoch做额外处理。下面是处理步骤:

1. date-parse函数认为这是UTC日期时间字符串,转换成epoch,记为x

2. 实际上日期时间字符串表示的是GMT+8时区,如果转换成epoch,应该记为y, y会比x小8小时。

为什么y比x小?

解释:一个epoch对应24个时区的日期时间字符串,这是1:24的对应关系。反过来,来自24个时区的相同的值的日期时间字符串对应的是24个epoch,时间越早的时区,epoch值越小。

所以需要将x减去8小时。下面的函数提供了一个参数time-offset,内部会减去它。

;; @str-date the date time value of specific time zone
;; @time-offset the offset seconds
;; @return nil if str-date is wrong
(define (datetime-str-to-epoch str-date date-format time-offset)
  (let (epoch-seconds 0)
    (setq epoch-seconds (catch (date-parse str-date date-format)))
    (if epoch-seconds
	(- epoch-seconds time-offset)
	nil
	)
    )
  )

每次先当作UTC时间字符串转换成epoch秒数,然后减去offset对应的秒数,获得相同时间字符串的实际时区对应的epoch。


下面是一个例子,利用(date)转换回当前时区做验证。

> (datetime-str-to-epoch "20140720 7:29" "%Y%m%d %H:%M" (* 8 3600))
1405812540
> (date 1405812540)
"Sun Jul 20 07:29:00 2014"







©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值