1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        跟 “最煩用 Python 處理時間了” 說拜拜

        共 12163字,需瀏覽 25分鐘

         ·

        2021-10-11 13:53


        文 | 李曉飛

        來源:Python 技術(shù)「ID: pythonall」

        人生苦短,我用 Python!,這句話是激勵無數(shù)人,踏上了 Python 的偉大征程的座右銘。

        但是,Python 中的時間處理,搞得我懷疑人生,總是弄不清該用 time 還是 datetime,什么時間戳、時間運算、各種格式的時間轉(zhuǎn)化,概念多,操作復(fù)雜,bug 還得找半天,實在是太麻煩了,一遇到時間處理就焦慮~

        今天給大家介紹一個處理時間的神器 —— Pendulum[1],跟過去說拜拜,讓你用 Python 處理時間快步如飛,還等啥,來吧!

        神器亮相

        Python 中神器亮相的姿勢都差不多,有種熟悉的味道:

        pip install pendulum

        順利安裝后,展示一下:

        import pendulum

        d1 = pendulum.yesterday()  # 昨天
        # 2021-10-02T00:00:00+08:00

        d2 = pendulum.today() # 今天
        # 2021-10-03T00:00:00+08:00

        d3 = pendulum.tomorrow() # 明天
        # 2021-10-04T00:00:00+08:00

        d2.diff(d1).in_days() # 相差多少天
        # 1

        d2.diff(d1).in_hours() # 相差多少小時
        # 24

        pendulum.now() # 現(xiàn)在的時間

        是不是感覺很有親和力,各種操作都符合人性化。

        而且將 datetime 和 time 兩個庫合并了,再也不用糾結(jié)應(yīng)該用哪個了。

        下面瀏覽一下 Pendulum 的更大威力吧。

        搞定時區(qū)

        時區(qū)處理是比較麻煩地事情,還好我們只使用一個時區(qū),省去了很多麻煩。

        不過時區(qū)的概念需要了解,再說,誰能說得準(zhǔn),不開發(fā)國際化程序呢。

        一起困難,Pendulum 讓我們優(yōu)雅處之。

        看例子:

        import pendulum

        dt1 = pendulum.datetime(2021103)
        print(dt2.timezone.name) # UTC

        dt2 = pendulum.datetime(2021103, tz="Asia/Shanghai")

        print(dt2.timezone.name) # Asia/Shanghai
        • 不指定,就是默認的 UTC 0 時區(qū)
        • 創(chuàng)建時間對象時可以指定時區(qū),例如我們的時區(qū)名稱是 Asia/Shanghai
        • 通過 timezone.name 屬性,可查看時間對象的具體時區(qū),或者直接用 timezone_name 直接獲取,另外,屬性 timezone 可以簡寫成 tz

        時區(qū)名稱可在這里查:時區(qū)名稱[2]
        Pendulum 時區(qū)只支持用 時區(qū)名稱 設(shè)置時區(qū)

        時區(qū)運算

        不同時區(qū)的時間可以用來比較、運算和轉(zhuǎn)化,例如:

        import pendulum

        first = pendulum.datetime(2012952326110, tz='America/Toronto')
        second = pendulum.datetime(2012952026110, tz='America/Vancouver')

        first.to_datetime_string()
        # 2012-09-05 23:26:11

        first.timezone_name
        # America/Toronto
        second.to_datetime_string()
        # 2012-09-05 20:26:11
        second.timezone_name
        # America/Vancouver

        first == second
        # True
        first != second
        # False
        first > second
        # False
        first < second
        # False

        first = first.on(201211).at(000)
        second = second.on(201211).at(000)
        # tz is still America/Vancouver for second

        first == second
        # False
        first != second
        # True
        first > second
        # False
        first < second
        # True

        second.diff(first).in_hours()
        # 3
        • 時區(qū) America/TorontoAmerica/Vancouver 相差 3 小時
        • 設(shè)置相差 3 小時的時間,兩者是相等的
        • 設(shè)置完全相同的時間,比較時是不相等的,計算它們之間的差異,可以看到相差 3 小時
        • diff 方法用于與另一個時間對象比較,in_hours 方法是時間區(qū)間的方法,可以將區(qū)間轉(zhuǎn)化為小時,同理還有 in_days、in_years

        時區(qū)切換

        切換時區(qū)很方便,只要調(diào)用時間對象的 in_timezone 或者 縮寫形式 in_tz 傳入?yún)?shù) 時區(qū)名稱 就可以了:

        import pendulum
        in_perk = pendulum.now()
        in_perk
        # DateTime(2021, 10, 4, 12, 10, 59, 986047, tzinfo=Timezone('Asia/Shanghai'))

        in_perk.in_timezone("America/New_York")
        # DateTime(2021, 10, 4, 0, 7, 50, 106336, tzinfo=Timezone('America/New_York'))

        時間運算

        時間運算包括比較、計算差異增減。上面例子中已經(jīng)計算了不同時區(qū)的時間差異,下面我們詳細的說一下。

        比較

        比較很簡單,對兩個時間對象做比較就可以了,支持 ==、!=、>、>=<、<=,比較的結(jié)果是 TrueFalse

        計算差異

        前面時區(qū)的例子里已經(jīng)看到了,使用 diff 方法來計算差異,會返回一個時間區(qū)間(Period)對象

        使用 diff 時,如果不提供比較參加,就會默認和當(dāng)前時間比較。

        import pendulum

        first = pendulum.datetime(20121310)
        second = pendulum.datetime(2012210)
        first.diff(second)
        # <Period [2012-01-31T00:00:00+00:00 -> 2012-02-01T00:00:00+00:00]>

        first.diff()
        # <Period [2012-01-31T00:00:00+00:00 -> 2021-10-04T04:44:56.337989+00:00]>

        對于時間區(qū)間(period)來說,處理前面提到的 in_days 等方法,將區(qū)間轉(zhuǎn)化為一個單位的數(shù)量,還可以直接使用對應(yīng)的屬性,例如 days、years、weeks 等,效果是一樣的。

        增減

        如果要的時間增加或者減少某些時間,可以使用 addsubtract 方法:

        import pendulum

        dt = pendulum.datetime(2012131)

        dt = dt.add(years=5)
        # '2017-01-31 00:00:00'
        dt = dt.add(years=1)
        # '2018-01-31 00:00:00'
        dt = dt.subtract(years=1)
        # '2017-01-31 00:00:00'
        dt = dt.subtract(years=5)
        # '2012-01-31 00:00:00'

        dt = dt.add(months=60)
        # '2017-01-31 00:00:00'
        dt = dt.add(months=1)
        # '2017-02-28 00:00:00'
        dt = dt.subtract(months=1)
        # '2017-01-28 00:00:00'
        dt = dt.subtract(months=60)
        # '2012-01-28 00:00:00'

        dt = dt.add(days=29)
        # '2012-02-26 00:00:00'
        dt = dt.add(days=1)
        # '2012-02-27 00:00:00'
        dt = dt.subtract(days=1)
        # '2012-02-26 00:00:00'
        dt = dt.subtract(days=29)
        # '2012-01-28 00:00:00'

        dt = dt.add(weeks=3)
        # '2012-02-18 00:00:00'
        dt = dt.add(weeks=1)
        # '2012-02-25 00:00:00'
        dt = dt.subtract(weeks=1)
        # '2012-02-18 00:00:00'
        dt = dt.subtract(weeks=3)
        # '2012-01-28 00:00:00'

        dt = dt.add(hours=24)
        # '2012-01-29 00:00:00'
        dt = dt.add(hours=1)
        # '2012-02-25 01:00:00'
        dt = dt.subtract(hours=1)
        # '2012-02-29 00:00:00'
        dt = dt.subtract(hours=24)
        # '2012-01-28 00:00:00'

        dt = dt.add(minutes=61)
        # '2012-01-28 01:01:00'
        dt = dt.add(minutes=1)
        # '2012-01-28 01:02:00'
        dt = dt.subtract(minutes=1)
        # '2012-01-28 01:01:00'
        dt = dt.subtract(minutes=24)
        # '2012-01-28 00:00:00'

        dt = dt.add(seconds=61)
        # '2012-01-28 00:01:01'
        dt = dt.add(seconds=1)
        # '2012-01-28 00:01:02'
        dt = dt.subtract(seconds=1)
        # '2012-01-28 00:01:01'
        dt = dt.subtract(seconds=61)
        # '2012-01-28 00:00:00'

        dt = dt.add(years=3, months=2, days=6, hours=12, minutes=31, seconds=43)
        # '2015-04-03 12:31:43'
        dt = dt.subtract(years=3, months=2, days=6, hours=12, minutes=31, seconds=43)
        # '2012-01-28 00:00:00'
        • addsubtract 方法參數(shù)一致,支持 years、months、weeks 等多種時間單位,而且可以一起設(shè)置
        • 時間單位參數(shù)可以支持負數(shù),相當(dāng)于 addsubtract 可以相互替換
        • 時間單位參數(shù)還支持小數(shù),比如加上一天半可以寫成 dt.add(days=1.5)

        時間調(diào)整

        時間調(diào)整很有用,之前我在約馬程序 中,需要計算下一個周一,當(dāng)時只能通過日期 API 摸,當(dāng)時要是知道 Pendulum 就省事多了:

        import pendulum

        dt = pendulum.datetime(20121311200)

        dt.start_of('day')
        # '2012-01-31 00:00:00'

        dt.end_of('day')
        # '2012-01-31 23:59:59'

        dt.start_of('month')
        # '2012-01-01 00:00:00'

        dt.end_of('month')
        # '2012-01-31 23:59:59'

        dt.start_of('year')
        # '2012-01-01 00:00:00'

        dt.end_of('year')
        # '2012-12-31 23:59:59'

        dt.start_of('decade')
        # '2010-01-01 00:00:00'

        dt.end_of('decade')
        # '2019-12-31 23:59:59'

        dt.start_of('century')
        # '2000-01-01 00:00:00'

        dt.end_of('century')
        # '2099-12-31 23:59:59'

        dt.start_of('week')
        # '2012-01-30 00:00:00'
        dt.day_of_week == pendulum.MONDAY
        # True # ISO8601 week starts on Monday

        dt.end_of('week')
        # '2012-02-05 23:59:59'
        dt.day_of_week == pendulum.SUNDAY
        # True # ISO8601 week ends on SUNDAY

        dt.next(pendulum.WEDNESDAY)
        # '2012-02-01 00:00:00'
        dt.day_of_week == pendulum.WEDNESDAY
        # True

        dt = pendulum.datetime(2012111200)
        dt.next()
        # '2012-01-08 00:00:00'
        dt.next(keep_time=True)
        # '2012-01-08T12:00:00+00:00'

        dt = pendulum.datetime(20121311200)
        dt.previous(pendulum.WEDNESDAY)
        # '2012-01-25 00:00:00'
        dt.day_of_week == pendulum.WEDNESDAY
        # True

        dt = pendulum.datetime(2012111200)
        dt.previous()
        # '2011-12-25 00:00:00'
        dt.previous(keep_time=True)
        # '2011-12-25 12:00:00'

        start = pendulum.datetime(201411)
        end = pendulum.datetime(2014130)
        start.average(end)
        # '2014-01-15 12:00:00'

        # others that are defined that are similar
        # and tha accept month, quarter and year units
        # first_of(), last_of(), nth_of()

        是否看眼花了,我看到這里,興奮地都要跳起來了,簡直是只有沒想到的,沒有它沒實現(xiàn)的呀!

        • start_of 方法用于計算某個起始時間,可以是 天、年、月、周,甚至可以是世紀(jì)。end_of 是類似的,用于計算結(jié)束
        • next 方法用于計算以一個星期,不加參數(shù)就是計算下個星期的今天,也可以指定計算下一個哪天,比如下個星期一:dt.next(pendulum.MONDAY)previous 是類似的,用于計算向前的天
        • average 方法用于計算兩個時間的中間時間,簡直太方便了

        時間轉(zhuǎn)字符串

        時間對象是一個復(fù)雜的對象,對于我們來說不方便看和讀,就需要將起轉(zhuǎn)化為字符串,或者將字符串表示的時間轉(zhuǎn)化為時間對象。

        Pendulum 提供和很多方便的方式:

        import pendulum

        dt = pendulum.datetime(19751225141516)
        print(dt)
        # '1975-12-25T14:15:16+00:00'

        dt.to_date_string()
        # '1975-12-25'

        dt.to_formatted_date_string()
        # 'Dec 25, 1975'

        dt.to_time_string()
        # '14:15:16'

        dt.to_datetime_string()
        # '1975-12-25 14:15:16'

        dt.to_day_datetime_string()
        'Thu, Dec 25, 1975 2:15 PM'

        # You can also use the format() method
        dt.format('dddd Do [of] MMMM YYYY HH:mm:ss A')
        'Thursday 25th of December 1975 02:15:16 PM'

        # Of course, the strftime method is still available
        dt.strftime('%A %-d%t of %B %Y %I:%M:%S %p')
        'Thursday 25th of December 1975 02:15:16 PM'
        • to_date_string 轉(zhuǎn)化日期
        • to_datetime_string 轉(zhuǎn)化日期和時間
        • to_time_string 轉(zhuǎn)化時間
        • to_formatted_date_string 轉(zhuǎn)化為英文書寫形式
        • format 安裝指定格式轉(zhuǎn)化
        • strftimedatetime 的格式化方法

        時間轉(zhuǎn)化字符串,如何將字符串轉(zhuǎn)化為時間類型呢?

        使用 parse 方法就好了,看下例子:

        import pendulum

        dt = pendulum.parse('1975-05-21T22:00:00')
        print(dt)
        # '1975-05-21T22:00:00+00:00

        # You can pass a tz keyword to specify the timezone
        dt = pendulum.parse('1975-05-21T22:00:00', tz='Europe/Paris')
        print(dt)
        # '1975-05-21T22:00:00+01:00'

        # Not ISO 8601 compliant but common
        dt = pendulum.parse('1975-05-21 22:00:00')

        dt = pendulum.parse('31-01-01', strict=False)

        dt = pendulum.parse('31/01/01', strict=False)

        dt = pendulum.parse('31/1/1', strict=False)
        • 可以直接轉(zhuǎn)化,也可以在轉(zhuǎn)化時指定時區(qū)
        • 支持多種時間格式,如果不是標(biāo)準(zhǔn)的時間格式,需要添加參數(shù) strict=False,這樣 Pendulum 就會盡最大可能去猜
        • 更多的時間格式請參考 Pendulum Parsing 文檔[3]

        人性化

        現(xiàn)在看到 Pendulum 的強大了吧,不過還有個令人叫絕的功能,就是人性化時間。

        如果你注意搜索引擎的結(jié)果的話,就能看到,很多時間被表示為:1天前,2周后等等,如果讓我們來實現(xiàn),可得好好想想,如果需求說,搞個英文版的,我們可能有拿起鍵盤去砸的沖動。

        現(xiàn)在好了,直接看例子:

        import pendulum

        pendulum.now().subtract(days=1).diff_for_humans()
        # '1 day ago'

        pendulum.now().diff_for_humans(pendulum.now().subtract(years=1))
        # '1 year after'

        dt = pendulum.datetime(201181)
        dt.diff_for_humans(dt.add(months=1))
        # '1 month before'
        dt.diff_for_humans(dt.subtract(months=1))
        # '1 month after'

        pendulum.now().add(seconds=5).diff_for_humans()
        # '5 seconds from now'

        pendulum.now().subtract(days=24).diff_for_humans()
        # '3 weeks ago'

        pendulum.now().subtract(days=24).diff_for_humans(absolute=True)
        # '3 weeks'

        pendulum.set_locale('zh')
        pendulum.now().subtract(days=24).diff_for_humans()
        # '3周前'

        pendulum.now().add(seconds=5).diff_for_humans()
        # '5秒鐘后'

        oneday = pendulum.now().diff(pendulum.now().add(days=1))
        oneday.in_words()
        # '1天'
        • diff_for_humans 可以將時間區(qū)間直接輸出成人性化時間
        • 參數(shù) absolute 的作用是給出一個人性化的時間間隔,而不是相對于現(xiàn)在的說法
        • 默認情況下輸出的是英語寫法,如果要讓說中文,通過 pendulum.set_locale('zh') 就可以了,厲害吧
        • 對于一個時間區(qū)域來說,可以用 in_words 來輸出人性化時間

        這里注意,對于 dt.diff_for_humans(dt.subtract(months=1)) 這樣的,相對一個日期的時間差異人性化輸出,不支持中文,會報錯,所以建議先計算出兩個日期的差異,再用 in_words 做人性化輸出,如果有必要,在其后加上。
        希望這個 bug 能早日修復(fù)

        總結(jié)

        今天簡單介紹了一下 Pendulum 庫在時間上的優(yōu)秀能力,除了這些它還有更多的功能可供發(fā)掘。只要多研究,多用,一定能解決你遇到時間處理的問題。

        最好的學(xué)就是用,所以要不斷地通過練習(xí)或者實踐去用,期望通過這篇介紹,能讓你在時間處理上更高效,比心!

        參考資料

        [1]

        Pendulum 工具: https://pendulum.eustace.io/

        [2]

        時區(qū)名稱: https://docs.aws.amazon.com/zh_cn/redshift/latest/dg/time-zone-names.html

        [3]

        Pendulum Parsing 文檔: https://pendulum.eustace.io/docs/#parsing

        文章點贊超過100+

        我將在個人視頻號直播(老表Max)

        帶大家一起進行項目實戰(zhàn)復(fù)現(xiàn)


        掃碼即可加我微信

        老表朋友圈經(jīng)常有贈書/紅包福利活動

        學(xué)習(xí)更多:
        整理了我開始分享學(xué)習(xí)筆記到現(xiàn)在超過250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲、機器學(xué)習(xí)等方面,別再說不知道該從哪開始,實戰(zhàn)哪里找了
        點贊”就是對博主最大的支持 
        瀏覽 16
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            青青草福利视频 | 做爱免费视频免费网站 | 免费一区二区三区 | 婷婷五月天在线观看 | 丰满美女av | 91中文字幕网 | 东京热小视频 | 国产一级婬片A片免费播放 | 深夜福利国产 | 逼逼免费看 |