python时区运算,时区,时间戳,夏令时讲解

目录

  • 统一概念
    • 标准时间
    • 时区
    • 时间戳
    • 字符串表示
  • Python中的时间处理 - Arrow
    • 为什么使用Arrow?
    • 功能
    • 快速入门
      • 安装
      • 用法示例
      • 实例代码
      • 参考
  • 其他语言处理方式参考:
  • 外链

统一概念

首先先理解一些通用的概念。

标准时间

  • 可以理解为世界时间,不存在时区问题
  • utc:(Universal Time Coordinated),协调世界时。全世界统一的世界标准时间。需要不规则地加入闰秒。
  • GMT:(Greenwich Mean Tim),格林尼治平均时间。
    • 一般认为UTC和GMT是相等的,但是会存在0.9秒以内的误差,这是由于地球不规则自转引起的。

时区

  • 人类的生存规则日出而作日落而息,对时间的定义亦是如此;但是全世界日出日落并不在同一时刻,所以就出现了时差问题; 为了方便计算时差问题而推出的世界时区规则 UTC +/-。
  • 本地时间:,UTC+时区,东为正西为负。比如北京时间在东八区就是 UTC+(+0800)。
  • DST:,夏令时。是指夏天太阳升起比较早,将时钟拨快一个小时来提早日光的使用。欧美主要国家都引用了这个做法。如果在夏令时时区内 DST=UTC+时区+1。

时间戳

  • 由UTC世界标准时间转换而来,不带时区;同一时刻获取的时间戳在全世界都是相同的。
  • Unix时间戳: 表示从UTC1970年1月1日0时0分0秒起至现在的总秒数,不考虑闰秒
  • 时间戳: 表示从UTC1970年1月1日0时0分0秒起至现在的毫秒数。

字符串表示

为了让时间易于阅读又出现了用各种字符串来表示时间的方法。
RFC2822 官方白皮书:https://tools.ietf.org/html/rfc2822#page-14

YYYY/MM/DD HH:MM:SS ± timezone(时区用4位数字表示)
//  1992/02/12 12:23:22+0800

ISO 8601 维基百科:https://zh.wikipedia.org/wiki/ISO_8601

YYYY-MM-DDThh:mm:ss ± timezone(时区用HH:MM表示)

1997-07-16T08:20:30Z
// “Z”表示UTC标准时区,即"00:00",所以这里表示零时区的`1997年7月16日08时20分30秒`
// 日期时间合并表示时,要在时间前面加一大写字母T

// 如要表示东八区时间2004年5月3日下午5点30分8秒,可以写成
2004-05-03T17:30:08+08:00
20040503T173008+08

Python中的时间处理 - Arrow

为什么使用Arrow?

Python的标准库和其他一些底层模块具有几乎完整的日期,时间和时区功能,但是从可用性的角度来看效果并不理想:

  • 太多模块:日期时间,时间,日历,dateutil,pytz等
  • 类型太多:日期,时间,日期时间,tzinfo,timedelta,relativedelta等。
  • 时区和时间戳转换冗长且令人不快
  • 时区朴素是常态
  • 功能上的差距:ISO 8601解析,时间跨度,人性化

功能

  • 完全实现的日期时间的直接替换
  • 支持Python 2.7、3.5、3.6、3.7和3.8
  • 默认为时区感知和UTC
  • 为许多常见的输入方案提供超简单的创建选项
  • shift 支持相对偏移量(包括周)的方法-
  • 自动格式化和解析字符串
  • 广泛支持ISO 8601
  • 时区转换
  • 时间戳记可作为属性使用
  • 生成时间范围,范围,下限和上限,以显示从微秒到年的时间范围
  • 人性化并支持不断增加的贡献区域列表
  • 可扩展为您自己的箭头衍生类型
  • 只动识别夏令时

快速入门

安装

要安装Arrow,请使用pip或pipenv:

$ pip install -U arrow

用法示例

>>> import arrow 

# 获得标准时
>>> utc = arrow.utcnow()
>>> utc 
<Arrow [2018-11-13T13:34:28.469607+00:00]>

# 时区转换
>>> local = utc.to("Asia/Shanghai")
<Arrow [2018-11-13T21:36:41.001464+08:00]>

# 比较
>>> utc > utc.shift(hour=-1)
True

# 字符串转换
>>> arrow.get('2013-05-11T21:23:58.970460+00:00')
<Arrow [2013-05-11T21:23:58.970460+00:00]>

# 格式化输出
>>> local.format('YYYY-MM-DD HH:mm:ss ZZ')
'2018-11-13 21:36:41 +08:00'

# 可读性
>>> local.humanize()
'an hour ago'
>>> local.humanize(locale='zh')
'1小时前'

# 时间戳
>>> utc.timestamp
1542116201

实例代码

import arrow
from datetime import datetime
import pytz


def test_demo():
    """
    arrow 实例
    :return:
    """
    # 获取当前utc时间(世界时间)
    utc = arrow.utcnow()
    print("当前世界时间:%s" % utc)  # 2020-04-19T06:31:29.595262+00:00

    # 减去一小时
    utc_h = utc.shift(hours=-1)
    print("当前世界时间减去一小时:%s" % utc_h)  # 2020-04-19T05:31:29.595262+00:00

    # 传入时区('Asia/Shanghai')北京时间,打印的时间是加8小时后的
    local = utc.to('Asia/Shanghai')
    print("北京当前时间:%s" % local)  # 2020-04-19T14:31:29.595262+08:00

    # 转换成时间戳(单位秒),此处注意只有带时区的时间信息转换后的时间戳才是正确的;
    timestamp = local.timestamp
    print("UTC 时间戳:%s" % timestamp)  # 1587278432

    # 显示格式转换
    form = local.format()  # 默认格式:"YYYY-MM-DD HH:mm:ss ZZ"
    print("带时区信息的北京时间:%s" % form)  # 2020-04-19 14:43:50+08:00
    form = local.format("YYYY-MM-DD HH:mm:ss")
    print("格式化后的北京时间:%s" % form)  # 2020-04-19 14:43:50


def test_arrow_now():
    """
    arrow.now() 使用
    :return:
    """
    # 获取当前utc时间(世界时间)
    utc = arrow.utcnow()
    print(utc)  # 2020-04-19T06:31:29.595262+00:00

    # 获取当期时间(本地时间),不指定时区时默认本机时区,自动识别本机时区;
    utc = arrow.now()
    print(utc)  # 2020-04-19T14:50:26.412411+08:00

    # 自定义时区 ‘America/St_Johns’加拿大时区
    utc = arrow.now(tz='America/St_Johns')
    print(utc)  # 2020-04-19T04:26:01.613671-02:30


def test_arrow_get():
    """
    arrow.get() 使用
    :return:
    """
    # 时间戳转换日期格式,默认转换为utc世界时间,反转请看demo02
    utc = arrow.get(1587280058)  # 秒级
    print(utc)  # 2020-04-19T06:56:01+00:00
    utc = arrow.get(1587280058.2278044)  # 毫秒级
    print(utc)  # 2020-04-19T07:07:38.227804+00:00

    # 支持传入datetime类型,arrow对datetime支持非常友好,此处不一一列举;
    utc = arrow.get(datetime.utcnow())
    print(utc)  # 2020-04-19T07:07:38.227804+00:00
    # arrow 格式转datetime
    a = arrow.utcnow()
    var = a.datetime
    print(type(var))  # 

    # 字符串格式日期,转arrow 日期格式
    arrow_time = arrow.get('2020-04-19 07:30:45', 'YYYY-MM-DD HH:mm:ss')
    print(arrow_time)  # 2020-04-19T07:30:45+00:00
    arrow_time = arrow.get('2020-04-19T07:30:45.000-07:00')
    print(arrow_time)  # 2020-04-19T07:30:45-07:00
    arrow_time = arrow.get(2020, 4, 19)
    print(arrow_time)  # 2020-04-19T00:00:00+00:00


def demo01():
    """
    北京时间转加拿大纽芬兰时区时间
    计算公式:
    北京时间 = 世界时间 + 8小时
    加拿大纽芬兰时区时间 = 世界时间 - 3:30小时
    加拿大纽芬兰时区夏令时时间 = 北京时间 - 8小时 - 3:30小时 + 1小时
    :return:
    """
    # 加拿大有很多时区,我们这里选择纽芬兰时区
    timezone = "America/St_Johns"
    # 北京时间
    timestr = "2020-04-19 16:19:48"
    # 此处重点注意:
    # 1,get()只能用来做格式转换,不能进行时区转换,转换需要使用to()方法
    # 2,北京时间不能直接进行转换,需要使用replace()指定传入时间的时区
    a_time = arrow.get(timestr, 'YYYY-MM-DD HH:mm:ss').replace(tzinfo='Asia/Shanghai')
    # arrow会自动识别时区是否进入夏令时,进入后会自动+1
    jnd_time = a_time.to(tz=timezone)
    print(jnd_time)  # 2020-04-19T05:49:48-02:30 加拿大夏令时时间
    return jnd_time


def demo02():
    """
    北京时间转时间戳
    时间戳的定义:表示当前时间到1970年1月1日00:00:00 UTC对应的毫秒数;
    重点:UTC (世界协调时)对应的秒数,不是北京时间对应的秒数;
    :return: UTC 时间戳(秒)
    """
    # 北京时间
    timestr = "2020-04-19 16:19:48"
    # 此处重点注意:北京时间不能直接进行时间戳转换,需要使用replace()指定传入时间的时区,或者timestr中带上时区
    a_time = arrow.get(timestr, 'YYYY-MM-DD HH:mm:ss').replace(tzinfo='Asia/Shanghai')
    time = a_time.timestamp
    print(time)  # 1587284388
    return time


def get_timezone():
    """
    使用python内置库pytz 获取时区库(pytz:python内置时区库)
    :return: 时区列表
    """
    # 获取指定国家的时区iso3166_code国家代码对照表,加拿大Canada:ca
    tz = pytz.country_timezones(iso3166_code='CA')
    print(tz[0])
    # 获取全部时区
    # tz = pytz.all_timezones
    return tz


if __name__ == '__main__':
    test_demo()

参考

官方地址: https://arrow.readthedocs.io/en/latest/

其他语言处理方式参考:

JavaScript: https://segmentfault.com/a/1190000007581722

外链

时间网:http://www.shijian.cc/
时差:https://www.zeitverschiebung.net/cn/
未完待续…

你可能感兴趣的:(python,时区,arrow)