在 Python 中是沒有原生數據類型支持時間的,日期與時間的操作需要借助三個模塊,分別是 time、datetime、calendar。
在學習之前,還有一些術語要補充一下,這些術語你當成慣例即可。這里在 Python 官方文檔中也有相關說明,不過信息比較多,橡皮擦為你摘錄必須知道的一部分。
epoch(紀元) 是時間開始的點,其值取決于平臺。
對于 Unix, epoch(紀元) 是 1970年1月1日00:00:00(UTC)。要找出給定平臺上的 epoch ,請使用 time.gmtime(0) 進行查看,例如橡皮擦電腦顯示:
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
術語 紀元秒數 是指自 epoch (紀元)時間點以來經過的總秒數,通常不包括閏秒。 在所有符合 POSIX 標準的平臺上,閏秒都不會記錄在總秒數中。
程序員中常把 紀元秒數 稱為 時間戳。
該模塊核心為控制時鐘時間。
該函數獲取時鐘的基本信息,得到的值因不同系統存在差異,函數原型比較簡單:
time.get_clock_info(name)
其中 name 可以取下述值:
該函數的返回值具有以下屬性:
import time
available_clocks = [
('clock', time.clock),
('monotonic', time.monotonic),
('perf_counter', time.perf_counter),
('process_time', time.process_time),
('time', time.time),
]
for clock_name, func in available_clocks:
print('''
{name}:
adjustable : {info.adjustable}
implementation: {info.implementation}
monotonic : {info.monotonic}
resolution : {info.resolution}
current : {current}
'''.format(
name=clock_name,
info=time.get_clock_info(clock_name),
current=func()))
運行結果如下圖所示。
上圖顯示橡皮擦的計算機在 clock 與 perf_counter 中,調用底層 C 函數是一致的。
在 Python 中通過 time.time() 函數獲取紀元秒數,它可以把從 epoch 開始之后的秒數以浮點數格式返回。
import time
print(time.time())
# 輸出結果 1615257195.558105
時間戳大量用于計算時間相關程序,屬于必須掌握內容。
時間戳主要用于時間上的方便計算,對于人們閱讀是比較難理解的,如果希望獲取可讀時間,使用 ctime() 函數獲取。
import time
print(time.ctime())
# 輸出內容:Tue Mar 9 10:35:51 2021
如何將時間戳轉換為可讀時間,使用 localtime 函數即可。
localtime = time.localtime(time.time())
print("本地時間為 :", localtime)
輸出結果為 <class 'time.struct_time'> 類型數據,后文將對其進行格式化操作:
本地時間為 : time.struct_time(tm_year=2021, tm_mon=3, tm_mday=9, tm_hour=10, tm_min=37, tm_sec=27, tm_wday=1, tm_yday=68, tm_isdst=0)
上述代碼中的時間戳最小值是 0,最大值由于 Python 環境和操作系統決定,我本地 64 位操作系統進行測試的時候,得到的數據如下:
import time
localtime = time.localtime(0)
print("時間為 :", localtime)
# 時間為 : time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
localtime = time.localtime(32536799999)
print("時間為 :", localtime)
# 時間為 : time.struct_time(tm_year=3001, tm_mon=1, tm_mday=19, tm_hour=15, tm_min=59, tm_sec=59, tm_wday=0, tm_yday=19, tm_isdst=0)
localtime = time.localtime(99999999999)
print("時間為 :", localtime)
# OSError: [Errno 22] Invalid argument
print(type(localtime))
monotonic time 從系統啟動開始計時,從 0 開始單調遞增。
操作系統的時間可能不是從 0 開始,而且會因為時間出錯而回調。
該函數原型如下,不需要任何參數,返回一個浮點數,表示小數秒內的單調時鐘的值:
time.monotonic()
測試代碼如下:
print("單調時間",time.monotonic())
# 輸出:單調時間 12279.244
time() 函數返回的是紀元秒數(時間戳), clock() 函數返回的是處理器時鐘時間。
該函數函數的返回值:
需要注意的是 Python 3.8 已移除 clock() 函數,用 time.perf_counter() 或 time.process_time() 方法替代。
t0 = time.clock()
# 運行一段代碼
print(time.clock() - t0, "程序運行時間")
我使用的 Python 版本較高,提示異常如下:
time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead t0 = time.clock()
perf_counter() 函數的 epoch (紀元)是未定義的。一般使用該函數都是為了比較和計算,不是為了用作絕對時間,該點需要注意下。
該函數用于測量較短持續時間的具有最高有效精度的時鐘,包括睡眠狀態消耗的時間,使用兩次調用才會有效。
測試代碼如下:
t0 = time.perf_counter()
# 運行一段代碼
for i in range(100000):
pass
print("程序運行時間", time.perf_counter() - t0)
與其類似的函數有 perf_counter_ns()、process_time()、process_time_ns(),具體可以查詢手冊進行學習,先掌握 perf_counter() 函數即可。
上文已經涉及了時間組件相關的知識,通過 localtime 得到的 struct_time 類型的數據。
這里涉及到的函數有 gmtime() 返回 UTC 中的當前時間,localtime() 返回當前時區對應的時間,mktime() 接收 struce_time 類型數據并將其轉換成浮點型數值,即時間戳。
print("*"*10)
print(time.gmtime())
print("*"*10)
print(time.localtime())
print("*"*10)
print(time.mktime(time.localtime()))
struct_time 類型包含的內容
上述代碼返回的數據格式為:
time.struct_time(tm_year=2021, tm_mon=3, tm_mday=9, tm_hour=12, tm_min=50, tm_sec=35, tm_wday=1, tm_yday=68, tm_isdst=0)
其中各值可以根據英文含義進行理解 :tm_year 年份(range[1,12]),tm_mon 月份(range[1,12]),tm_mday 天數(range[1,31]),tm_hour 天數(range[0,23]),tm_min 分鐘 (range[0,59]), tm_sec 秒數 (range[0,61]), tm_wday 星期 (range[0,6],0 是星期日), tm_yday 一年中的一天(range[1,366] ),tm_isdst 在夏令時生效時設置為 1,而在夏令時不生效時設置為 0,值-1 表示這是未知的。
strptime() 和 strftime() 函數可以使時間值在 struct_time 表示和字符串表示之間相互轉換。
對于 strftime 函數,其中的參數參考官方即可。
x = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(x)
這里的學習,沒有什么難度大的點,孰能生巧的知識。
strptime 函數的應用
x = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(x)
# 方向操作,字符串格式化成 time.struct_time
struct_time = time.strptime(x, "%Y-%m-%d %H:%M:%S")
print(struct_time)
需要記憶的就是 strftime 與 strptime 函數只有中間的字符不同,一個是 f ,另一個是 p。
對于 time 模塊,sleep 函數屬于必備知識點,但是太常用了,你肯定已經很熟悉了。
對于模塊的學習,最權威的就是官方手冊了——time 模塊。
該模塊比 time 模塊高級了很多,并且對 time 模塊進行了封裝,提供的功能更加強大了。
在 datetime 模塊中,Python 提供了 5 個主要的對象類,分別如下:
優先展示部分該類的屬性和方法,都是記憶層面的知識。
測試代碼如下:
from datetime import date
import time
print('date.min:', date.min)
print('date.max:', date.max)
print('date.resolution:', date.resolution)
print('date.today():', date.today())
print('date.fromtimestamp():', date.fromtimestamp(time.time()))
輸出結果:
date.min: 0001-01-01
date.max: 9999-12-31
date.resolution: 1 day, 0:00:00
date.today(): 2021-03-09
date.fromtimestamp(): 2021-03-09
date 對象的屬性和方法
通過下述代碼創建一個 date 對象:
d = date(year=2021,month=3,day=9)
print(d)
該對象具備下述屬性和方法:
time 類定義的類屬性:
通過其構造函數可以創建一個 time 對象。
t = time(hour=20, minute=20, second=40)
print(t)
time 類提供的實例方法和屬性:
該類是 date 類與 time 類的結合體,很多屬性和方法前文已經介紹,再補充一些比較常用的屬性和方法。
獲取當前的日期與時間:
from datetime import datetime
dt = datetime.now()
print(dt)
獲取時間戳:
dt = datetime.now()
# 使用 datetime 的內置函數 timestamp()
stamp = datetime.timestamp(dt)
print(stamp)
通過 timedelta 函數返回一個 timedelta 時間間隔對象,該函數沒有必填參數,如果寫入一個整數就是間隔多少天的的意思。
# 間隔 10 天
timedelta(10)
# 跨度為1 周
timedelta(weeks=1)
兩個時間間隔對象可以彼此之間相加或相減,返回的仍是一個時間間隔對象。
一個 datetime 對象如果減去一個時間間隔對象,那么返回的對應減去之后的 datetime 對象,然后兩個 datetime 對象如果相減,返回的是一個時間間隔對象。
更多關于 datetime 類使用的知識,可以參考官方手冊。
此模塊的函數都是日歷相關的,例如打印某月的字符月歷。
calendar 模塊定義了 Calendar 類,它封裝了值的計算, 例如給定月份或年份中周的日期。通過 TextCalendar 和 HTMLCalendar 類可以生成預格式化的輸出。
基本代碼:
import calendar
c = calendar.TextCalendar(calendar.SUNDAY)
c.prmonth(2021, 3)
上述代碼,默認是從周日開始的,輸出結果:
March 2021
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
該模塊使用頻率較低,詳細使用參考地址 進行學習。
本篇博客為大家補充了一下時間和日期庫的相關知識,希望能進入你的收藏夾。
作者:夢想橡皮擦
原文鏈接:https://blog.csdn.net/hihell/article/details/114413866
秒 在1967年的第13屆國際度量衡會議上決定以原子時定義的秒作為時間的國際標準單位:銫133原子基態的兩個超精細能階間躍遷對應輻射的9,192,631,770個周期的持續時間, 起始歷元定在1958年1月1日0時。
原子鐘是一種時鐘,它以原子共振頻率標準來計算及保持時間的準確。原子鐘是世界上已知最準確的時間測量和頻率標準。
GMT 格林威治標準時間(Greenwich Mean Time),是指位于倫敦郊區的皇家格林威治天文臺的標準時間,因為本初子午線(Prime meridian)被定義為通過那里的經線。GMT也叫世界時UT。
UTC 協調世界時間(Coordinated Universal Time), 又稱世界標準時間,基于國際原子鐘,誤差為每日數納秒。協調世界時的秒長與原子時的秒長一致,在時刻上則要求盡量與世界時接近(規定二者的差值保持在 0.9秒以內)。
閏秒 不只有閏年,還有閏秒。閏秒是指為保持協調世界時接近于世界時時刻,由國際計量局統一規定在年底或年中(也可能在季末)對協調世界時增加或減少1秒的調整。由于地球自轉的不均勻性和長期變慢性(主要由潮汐摩擦引起的),會使世界時(民用時)和原子時之間相差超過到±0.9秒時,就把世界時向前撥1秒(負閏秒,最后一分鐘為59秒)或向后撥1秒(正閏秒,最后一分鐘為61秒);閏秒一般加在公歷年末或公歷六月末。
時區 是地球上的區域使用同一個時間定義。有關國際會議決定將地球表面按經線從南到北,劃分成24個時區,并且規定相鄰區域的時間相差1小時。當人們跨過一個區域,就將自己的時鐘校正1小時(向西減1小時,向東加1小時),跨過幾個區域就加或減幾小時。比如我大中國處于東八區,表示為GMT+8。
夏令時 (Daylight Saving Time:DST),又稱日光節約時制、日光節約時間或夏令時間。這是一種為節約能源而人為規定地方時間的制度,在夏天的時候,白天的時間會比較長,所以為了節約用電,因此在夏天的時候某些地區會將他們的時間定早一小時,也就是說,原本時區是8點好了,但是因為夏天太陽比較早出現,因此把時間向前挪,在原本8點的時候,訂定為該天的9點(時間提早一小時)~如此一來,我們就可以利用陽光照明,省去了花費電力的時間,因此才會稱之為夏季節約時間!
Unix時間戳 指的是從協調世界時(UTC)1970年1月1日0時0分0秒開始到現在的總秒數,不考慮閏秒。
在 Python 文檔里,time是歸類在Generic Operating System Services中,換句話說, 它提供的功能是更加接近于操作系統層面的。通讀文檔可知,time 模塊是圍繞著 Unix Timestamp 進行的。
該模塊主要包括一個類 struct_time,另外其他幾個函數及相關常量。需要注意的是在該模塊中的大多數函數是調用了所在平臺C library的同名函數, 所以要特別注意有些函數是平臺相關的,可能會在不同的平臺有不同的效果。另外一點是,由于是基于Unix Timestamp,所以其所能表述的日期范圍被限定在 1970 – 2038 之間,如果你寫的代碼需要處理在前面所述范圍之外的日期,那可能需要考慮使用datetime模塊更好。
獲取當前時間和轉化時間格式
>>> import time
>>> time.time()
1473386416.954
>>> time.ctime()
'Fri Sep 09 10:00:25 2016'
>>> time.ctime(time.time())
'Fri Sep 09 10:28:08 2016'
>>> time.asctime()
'Fri Sep 09 10:22:40 2016'
>>> time.asctime(time.localtime())
'Fri Sep 09 10:33:00 2016'
>>> time.localtime()
time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=10, tm_min=1, tm_sec=19, tm_wday=4, tm_yday=253, tm_isdst=0)
>>> time.localtime(time.time())
time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=10, tm_min=19, tm_sec=11, tm_wday=4, tm_yday=253, tm_isdst=0)
>>> time.gmtime()
time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=2, tm_min=13, tm_sec=10, tm_wday=4, tm_yday=253, tm_isdst=0)
>>> time.gmtime(time.time())
time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=2, tm_min=15, tm_sec=35, tm_wday=4, tm_yday=253, tm_isdst=0)
struct_time共有9個元素,其中前面6個為年月日時分秒,后面三個分別代表的含義為:
time.mktime()
將一個以struct_time格式轉換為時間戳
>>> time.mktime(time.localtime())
1473388585.0
time.strftime(format[,t]) 把一個struct_time時間轉化為格式化的時間字符串。如果t未指定,將傳入time.localtime()。如果元組中任何一個元素越界,ValueError的錯誤將會被拋出。
>>> time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
'2016-09-09 10:54:21'
time.strptime(string[,format])
把一個格式化時間字符串轉化為struct_time。實際上它和strftime()是逆操作。
>>> time.strptime(time.ctime())
time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=11, tm_min=0, tm_sec=4, tm_wday=4, tm_yday=253, tm_isdst=-1)
time.sleep(secs)
線程推遲指定的時間運行。單位為秒。
time.clock()
這個需要注意,在不同的系統上含義不同。在UNIX系統上,它返回的是“進程時間”,它是用秒表示的浮點數(時間戳)。而在WINDOWS中,第一次調用,返回的是進程運行的實際時間。而第二次之后的調用是自第一次調用以后到現在的運行時間。(實際上是以WIN32上QueryPerformanceCounter()為基礎,它比毫秒表示更為精確)
import time
time.sleep(1)
print("clock1:%s" % time.clock())
time.sleep(1)
print("clock2:%s" % time.clock())
time.sleep(1)
print("clock3:%s" % time.clock())
運行結果為:
clock1:1.57895443216e-06
clock2:1.00064381867
clock3:2.00158724394
其中第一個clock()輸出的是程序運行時間,第二、三個clock()輸出的都是與第一個clock的時間間隔
import time
print(time.timezone)
print(time.tzname)
print(time.tzname[0].decode("GBK"))
print(time.tzname[1].decode("GBK"))
運行結果
-28800
('\xd6\xd0\xb9\xfa\xb1\xea\xd7\xbc\xca\xb1\xbc\xe4', '\xd6\xd0\xb9\xfa\xcf\xc4\xc1\xee\xca\xb1')
中國標準時間
中國夏令時
datetime 比 time 高級了不少,可以理解為 datetime 基于 time 進行了封裝,提供了更多實用的函數。
datetime模塊定義了下面這幾個類:
注:上面這些類型的對象都是不可變(immutable)的。
date類定義了一些常用的類方法與類屬性:
from datetime import date
import time
print('date.max:', date.max)
print('date.min:', date.min)
print('date.resolution:', date.resolution)
print('date.today():', date.today())
print('date.fromtimestamp():', date.fromtimestamp(time.time()))
執行結果:
date.max: 9999-12-31
date.min: 0001-01-01
date.resolution: 1 day, 0:00:00
date.today(): 2016-09-12
date.fromtimestamp(): 2016-09-12
date提供的實例方法和屬性:
from datetime import date
today = date.today()
print('today:', today)
print('.year:', today.year)
print('.month:', today.month)
print('.replace():', today.replace(year=2017) )
print('.weekday():', today.weekday())
print('.isoweekday():', today.isoweekday())
print('.isocalendar():', today.isocalendar())
print('.isoformat():', today.isoformat())
print('.strftime():', today.strftime('%Y-%m-%d') )
print('.toordinal():', today.toordinal())
執行結果:
today: 2016-09-12
.year: 2016
.month: 9
.replace(): 2017-09-12
.weekday(): 0
.isoweekday(): 1
.isocalendar(): (2016, 37, 1)
.isoformat(): 2016-09-12
.strftime(): 2016-09-12
.toordinal(): 736219
date還對某些操作進行了重載,它允許我們對日期進行如下一些操作:
time類的構造函數如下:(其中參數tzinfo,它表示時區信息。)
class datetime.time(hour[, minute[, second[, microsecond[, tzinfo]]]])
time類定義的類屬性:
time類提供的實例方法和屬性:
像date一樣,也可以對兩個time對象進行比較,或者相減返回一個時間間隔對象。這里就不提供例子了。
datetime是date與time的結合體,包括date與time的所有信息。它的構造函數如下:datetime.datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]),各參數的含義與date、time的構造函數中的一樣,要注意參數值的范圍。
datetime類定義的類屬性與方法:
from datetime import datetime
import time
print('datetime.max:', datetime.max)
print('datetime.min:', datetime.min)
print('datetime.resolution:', datetime.resolution)
print('today():', datetime.today())
print('now():', datetime.now())
print('utcnow():', datetime.utcnow())
print('fromtimestamp(tmstmp):', datetime.fromtimestamp(time.time()))
print('utcfromtimestamp(tmstmp):', datetime.utcfromtimestamp(time.time()))
運行結果:
datetime.max: 9999-12-31 23:59:59.999999
datetime.min: 0001-01-01 00:00:00
datetime.resolution: 0:00:00.000001
today(): 2016-09-12 19:57:00.761000
now(): 2016-09-12 19:57:00.761000
utcnow(): 2016-09-12 11:57:00.761000
fromtimestamp(tmstmp): 2016-09-12 19:57:00.761000
utcfromtimestamp(tmstmp): 2016-09-12 11:57:00.761000
datetime類提供的實例方法與屬性(很多屬性或方法在date和time中已經出現過,在此有類似的意義,這里只羅列這些方法名,具體含義不再逐個展開介紹,可以參考上文對date與time類的講解。):
year、month、day、hour、minute、second、microsecond、tzinfo:
像date一樣,也可以對兩個datetime對象進行比較,或者相減返回一個時間間隔對象,或者日期時間加上一個間隔返回一個新的日期時間對象。
通過timedelta函數返回一個timedelta對象,也就是一個表示時間間隔的對象。函數參數情況如下所示:
class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
其沒有必填參數,簡單控制的話第一個整數就是多少天的間隔的意思:
datetime.timedelta(10)
兩個時間間隔對象可以彼此之間相加或相減,返回的仍是一個時間間隔對象。而更方便的是一個datetime對象如果減去一個時間間隔對象,那么返回的對應減去之后的datetime對象,然后兩個datetime對象如果相減返回的是一個時間間隔對象。這很是方便。
tzinfo是一個抽象類,不能被直接實例化。需要派生子類,提供相應的標準方法。datetime模塊并不提供tzinfo的任何子類。最簡單的方式是使用pytz模塊。
pytz是Python的一個時區處理模塊(同時也包括夏令時),在理解時區處理模塊之前,需要先要了解一些時區的概念。
要知道時區之間的轉換關系,其實這很簡單:把當地時間減去當地時區,剩下的就是格林威治時間了。例如北京時間的18:00就是18:00+08:00,相減以后就是10:00+00:00,因此就是格林威治時間的10:00。
Python的datetime可以處理2種類型的時間,分別為offset-naive和offset-aware。前者是指沒有包含時區信息的時間,后者是指包含時區信息的時間,只有同類型的時間才能進行減法運算和比較。
datetime模塊的函數在默認情況下都只生成offset-naive類型的datetime對象,例如now()、utcnow()、fromtimestamp()、utcfromtimestamp()和strftime()。其中now()和fromtimestamp()可以接受一個tzinfo對象來生成offset-aware類型的datetime對象,但是標準庫并不提供任何已實現的tzinfo類,只能自己實現。
下面就是實現格林威治時間和北京時間的tzinfo類的例子:
ZERO_TIME_DELTA = timedelta(0)
LOCAL_TIME_DELTA = timedelta(hours=8) # 本地時區偏差
class UTC(tzinfo):
def utcoffset(self, dt):
return ZERO_TIME_DELTA
def dst(self, dt):
return ZERO_TIME_DELTA
class LocalTimezone(tzinfo):
def utcoffset(self, dt):
return LOCAL_TIME_DELTA
def dst(self, dt):
return ZERO_TIME_DELTA
def tzname(self, dt):
return '+08:00'
一個tzinfo類需要實現utcoffset、dst和tzname這3個方法。其中utcoffset需要返回夏時令的時差調整;tzname需要返回時區名,如果你不需要用到的話,也可以不實現。
一旦生成了一個offset-aware類型的datetime對象,我們就能調用它的astimezone()方法,生成其他時區的時間(會根據時差來計算)。而如果拿到的是offset-naive類型的datetime對象,也是可以調用它的replace()方法來替換tzinfo的,只不過這種替換不會根據時差來調整其他時間屬性。因此,如果拿到一個格林威治時間的offset-naive類型的datetime對象,直接調用replace(tzinfo=UTC())即可轉換成offset-aware類型,然后再調用astimezone()生成其他時區的datetime對象。
看上去一切都很簡單,但不知道你還是否記得上文所述的夏時令。提起夏時令這個玩意,真是讓我頭疼,因為它沒有規則可循:有的國家實行夏時令,有的國家不實行,有的國家只在部分地區實行夏時令,有的地區只在某些年實行夏時令,每個地區實行夏時令的起止時間都不一定相同,而且有的地方TMD還不是用幾月幾日來指定夏時令的起止時間的,而是用某月的第幾個星期幾這種形式。
pytz模塊,使用Olson TZ Database解決了跨平臺的時區計算一致性問題,解決了夏令時帶來的計算問題。由于國家和地區可以自己選擇時區以及是否使用夏令時,所以pytz模塊在有需要的情況下得更新自己的時區以及夏令時相關的信息。
pytz提供了全部的timezone信息,如:
import pytz
print(len(pytz.all_timezones))
print(len(pytz.common_timezones))
運行結果:
588
436
如果需要獲取某個國家的時區,可以使用如下方式:
import pytz
print(pytz.country_timezones('cn'))
執行結果:
[u'Asia/Shanghai', u'Asia/Urumqi']
中國一個有兩個時區,一個為上海,一個為烏魯木齊,我們來看下我們有什么區別:
from datetime import datetime
import pytz
print(pytz.country_timezones('cn'))
tz1 = pytz.timezone(pytz.country_timezones('cn')[0])
print(tz1)
print(datetime.now(tz1))
tz2 = pytz.timezone(pytz.country_timezones('cn')[1])
print(tz2)
print(datetime.now(tz2))
執行結果:
[u'Asia/Shanghai', u'Asia/Urumqi']
Asia/Shanghai
2016-09-14 09:55:39.384000+08:00
Asia/Urumqi
2016-09-14 07:55:39.385000+06:00
可以看到上海是東八區,而烏魯木齊是東六區。
操作起來有而比較簡單,本地時區與UTC的互轉:
from datetime import datetime
import pytz
now = datetime.now()
tz = pytz.timezone('Asia/Shanghai')
print(tz.localize(now))
print(pytz.utc.normalize(tz.localize(now)))
執行結果:
2016-09-14 10:25:44.633000+08:00
2016-09-14 02:25:44.633000+00:00
使用astimezone()可以進行時區與時區之間的轉換。
from datetime import datetime
import pytz
utc = pytz.utc
beijing_time = pytz.timezone('Asia/Shanghai')
japan_time = pytz.timezone('Asia/Tokyo')
now = datetime.now(beijing_time)
print("Beijing Time:",now)
print("UTC:",now.astimezone(utc))
print("JAPAN TIME:",now.astimezone(japan_time))
執行結果:
Beijing Time: 2016-09-14 10:19:22.671000+08:00
UTC: 2016-09-14 02:19:22.671000+00:00
JAPAN TIME: 2016-09-14 11:19:22.671000+09:00
另外可以采用 replace來修改時區,時區多出6分鐘(不要使用)。具體原因為:
民國17年(1928年),國民政府統一中國,原中央觀象臺的業務由南京政府中央研究院的天文研究所和氣象研究所分別接收。天文研究所編寫的曆書基本上沿襲中央觀象臺的做法,仍將全國劃分為5個標準時區,只是在有關交氣、合朔、太陽出沒時刻等處,不再使用北平的地方平時,而改以南京所在的標準時區的區時即東經120°標準時替代。從北平地方平時改為東經120°標準時,兩者相差了352秒。
from datetime import datetime
import pytz
now = datetime.now()
print(now)
tz = pytz.timezone('Asia/Shanghai')
print(now.replace(tzinfo=tz))
執行結果:
2016-09-14 10:29:20.200000
2016-09-14 10:29:20.200000+08:06
由于用到的場景比較少,不做細化學習。
安裝模塊:pip install Python-dateutil
解析時間到datetime格式,支持大部分時間字符串。沒指定時間默認是0點,沒指定日期默認是今天,沒指定年份默認是今年。
from dateutil import parser
print(parser.parse("8th March,2004"))
print(parser.parse("8 March,2004"))
print(parser.parse("March 8th,2004"))
print(parser.parse("March 8,2004"))
print(parser.parse("2016-09-14"))
print(parser.parse("20160914"))
print(parser.parse("2016/09/14"))
print(parser.parse("09/14/2016"))
print(parser.parse("09,14"))
print(parser.parse("12:00:00"))
print(parser.parse("Wed, Nov 12"))
執行結果:
2004-03-08 00:00:00
2004-03-08 00:00:00
2004-03-08 00:00:00
2004-03-08 00:00:00
2016-09-14 00:00:00
2016-09-14 00:00:00
2016-09-14 00:00:00
2016-09-14 00:00:00
2016-09-09 00:00:00
2016-09-14 12:00:00
2016-11-12 00:00:00
函數主要功能:按照規則生成日期和時間。函數原型如下。
rrule(self, freq, dtstart=None, interval=1, wkst=None, count=None, until=None, bysetpos=None, bymonth=None, bymonthday=None, byyearday=None, byeaster=None, byweekno=None, byweekday=None, byhour=None, byminute=None, bysecond=None, cache=False)
其中:
更多參考:http://dateutil.readthedocs.io/en/stable/index.html
Arrow 提供了一個友好而且非常易懂的方法,用于創建時間、計算時間、格式化時間,還可以對時間做轉化、提取、兼容 python datetime 類型。它包括dateutil模塊,根據其文檔描述Arrow旨在“幫助你使用更少的代碼來處理日期和時間”。
使用utcnow()功能創建 UTC 時間。
使用to()方法,我們將 UTC 時間轉換為本地時間。
import arrow
utc = arrow.utcnow()
print(utc)
print(utc.to('local'))
本地時間是特定區域或時區中的時間。
import arrow
now = arrow.now()
print(now)
print(now.to('UTC'))
使用now()功能創建本地時間。to()方法用于將本地時間轉換為 UTC 時間。
get()方法用于解析時間。
import arrow
d1 = arrow.get('2012-06-05 16:20:03', 'YYYY-MM-DD HH:mm:ss')
print(d1)
d2 = arrow.get(1504384602)
print(d2)
該示例從日期和時間字符串以及時間戳解析時間。
import arrow
utc = arrow.utcnow()
print(utc)
unix_time = utc.timestamp
print(unix_time)
date = arrow.Arrow.fromtimestamp(unix_time)
print(date)
該示例顯示本地時間和 Unix 時間。然后,它將 Unix 時間轉換回 date 對象。
使用fromtimestamp()方法,我們將 Unix 時間轉換回 Arrow 日期對象。
也可以將日期格式化為 Unix 時間。
import arrow
utc = arrow.utcnow()
print(utc.format('X'))
通過將’X’說明符傳遞給format()方法,我們將當前本地日期打印為 Unix 時間。
日期和時間可以用format()方法格式化。
import arrow
now = arrow.now()
year = now.format('YYYY')
print("Year: {0}".format(year))
date = now.format('YYYY-MM-DD')
print("Date: {0}".format(date))
date_time = now.format('YYYY-MM-DD HH:mm:ss')
print("Date and time: {0}".format(date_time))
date_time_zone = now.format('YYYY-MM-DD HH:mm:ss ZZ')
print("Date and time and zone: {0}".format(date_time_zone))
格式說明:
import arrow
utc = arrow.utcnow()
print(utc.to('US/Pacific').format('HH:mm:ss'))
print(utc.to('Europe/Bratislava').format('HH:mm:ss'))
print(utc.to('Europe/Moscow').format('HH:mm:ss'))
可以使用weekday()或format()方法找到日期的工作日。
import arrow
d1 = arrow.get('1948-12-13')
print(d1.weekday())
print(d1.format('dddd'))
shift()方法用于移動時間。
import arrow
now = arrow.now()
print(now.shift(hours=5).time())
print(now.shift(days=5).date())
print(now.shift(years=-8).date())
import arrow
now = arrow.now()
print(now.format("YYYY-MM-DD HH:mm:ss ZZ"))
print(now.dst())
該示例使用dst()顯示夏令時。
在社交網站上,我們經常可以看到諸如“一個小時前”或“ 5 分鐘前”之類的術語,這些術語可以為人們提供有關帖子創建或修改時間的快速信息。Arrow 包含humanize()方法來創建此類術語。
import arrow
now = arrow.now()
d1 = now.shift(minutes=-15).humanize()
print(d1)
d2 = now.shift(hours=5).humanize()
print(d2)
國際標準ISO 8601,是國際標準化組織的日期和時間的表示方法,全稱為《數據存儲和交換形式·信息交換·日期和時間的表示方法》,在API接口開發中涉及的比較多。
>>> import dateutil.parser
>>> dateutil.parser.parse('2008-09-03T20:56:35.450686Z') # RFC 3339 format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())
>>> dateutil.parser.parse('2008-09-03T20:56:35.450686') # ISO 8601 extended format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.parse('20080903T205635.450686') # ISO 8601 basic format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.parse('20080903') # ISO 8601 basic format, date only
datetime.datetime(2008, 9, 3, 0, 0)
或者使用如下方式解析:
>>> datetime.datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
另外還可以使用iso8601模塊:http://pyiso8601.readthedocs.io/en/latest/
其他日期與時間工具:
atejs 是一個開源的JavaScript庫,用來解析、格式化和處理日期數據,支持多種語言的日期格式處理;官網:www.datejs.com/
Moment.js 是一個簡單易用的輕量級JavaScript日期處理類庫,提供了日期格式化、日期解析等功能。它支持在瀏覽器和NodeJS兩種環境中運行;
date-fns庫:
現代 JavaScript 日期實用程序庫。date-fns 提供了最全面,最簡單和一致的工具集,用于在瀏覽器和 Node.js 中操作 JavaScript 日期;官網:date-fns.org
Prettydate 是一個 jQuery 用來顯示一些用戶友好的日期格式的插件,例如Posted 2 days ago by John Resig;
Countdown是jQuery的一個用于顯示倒計時的插件;
XDate是一個對Javascirpt本地Date對象的輕度包裝,它提供對日期的解析、格式化以及其他操作的較強功能;
DP_DateExtensions庫繼承了JavaScript的Date對象,并添加了一些新特性和功能。
組件類:
layDate 日期與時間組件,layDate 是 layui 獨立維護的三大組件之一;官網:www.layui.com/laydate/
Datejs 日期庫:是一個開源的JavaScript庫,用來解析、格式化和處理日期數據,支持多種語言的日期格式處理;
官網:www.datejs.com/
基本用法:
// 返回今天的日期,時間設置為00:00(一天的開始)
console.log(Date.today().toString("yyyy-MM-d HH:m:s"));
//返回下一個星期五的日期
console.log(Date.today().next().friday().toString("yyyy-MM-d HH:m:s"));
Date.today().last().monday() //返回上一個星期一的日期
new Date().next().march() //返回下一個三月的日期。
new Date().last().week() //返回一周前的日期。
Date.today().is().friday() //如果星期幾匹配,則返回true | false.
Date.today().is().fri() //縮寫的日期名稱.
Date.today().is().november() //月名稱
Date.today().is().nov() //月份的縮寫.
Date.today().is().weekday() //今天是工作日嗎?
Date.today().addDays(1); //添加一天(+1)
Date.today().addMonths(-3); //減去三個月內(-3)
//添加一(+1)天。支持所有日期部分(年,月,日,時,分,秒,毫秒和周)
Date.today().add(1).day();
Date.today().add(-3).months(); //減去三(-3)個月
// (1).day().fromNow() //從現在起一(1)天。
// (3).months().ago() //三(3)個月前。
var n = 6;
console.log(n.months().fromNow().toString('d')); //從現在起六(6)個月。
Date.monday(); //返回當前星期的星期一。
Date.mon(); // Date.monday()的縮寫版本
Date.march(); //返回今年3月1日。
Date.mar(); // Date.march()的縮寫版本
Date.today().first().thursday(); //返回當年3月的第一個星期四。
Date.today().second().thursday();//返回當前月份的第二個星期四。
Date.march().third().thursday(); //返回當年3月的第三個星期四。
Date.october().fourth().sunday();//返回十月的第四個星期日。
//返回當前月份的第五個星期日,如果當前月份沒有5個星期日,則拋出RangeError異常。
// Date.today().fifth().sunday();
Date.october().final().sunday(); //返回十月的最后一個星期日。
Date.january().first().monday(); //返回當年的第一個星期一。
Date.december().final().friday();//返回當年的最后一個星期五。
Date.today().at("6:15pm"); //返回今天的日期為6:15 pm。
var time = {hour:18, minute:15};
Date.today().at(time); //使用配置對象設置時間。
var birthDayParty = {month: 1, day: 20, hour: 20, minute: 30};
Date.today().set(birthDayParty);//使用配置對象設置日期和時間。
日期解析轉換:
Date.parse("t"); //返回今天的日期
Date.parse("today"); //返回今天的日期。
Date.parse("tomorrow"); //返回明天的日期
Date.parse("yesterday"); //返回昨天的日期
Date.parse("next friday"); //返回下一個星期五的日期
Date.parse("last monday"); //返回上一個星期一的日期。
Date.parse("July 8th, 2004"); // 2004年7月8日星期四
Date.parse("15-Jan-2004"); // 2004年1月15日星期四
Date.parse("7/1/2004"); // 2004年7月1日星期四
Date.parse("7.1.2004"); // 2004年7月1日星期四
Date.parse("07.15.04"); // 2004年7月15日星期四
Date.parse("July 23rd 2004"); //周五2004年7月23日
Date.parse("Sat July 3, 2004"); // 2004年7月3日星期六
Date.parse("10:30 PM EST"); // 2007年10月31日星期三20:30:00
Date.parse("10PM"); // 2007年10月31日星期三22:00:00
Date.parse("t + 5d"); //將5天加到今天
Date.parse("today - 1 month"); //從今天開始減去1個月
Date.parse("+"); //將1天添加到今天=明天
Date.parse("- 3months"); //減去3個月
Date.parse("+1year"); //在今天加上一年
Date.parse("-12 months"); //從今天起減去12個月(1年)
Date.parse("July 4th"); //今年7月4日
Date.parse("15"); //當前月份/年份的第15天
Date.parse("July 8th, 2004, 10:30 PM");// 2004年7月8日,星期四
Date.parse("2004-07-15T06:45:00"); // 2004年7月15日星期四
Date.parse("Thu, 1 July 2004 22:30:00 GMT");//星期四,2004年7月1日16:30:00
Date.parse("1997-07-16T19:20:15"); // ISO 8601格式
Date.parse("1997-07-16T19:20:30+01:00");//具有時區偏移
Date.parse("1985-04-12T23:20:50Z"); // RFC 3339格式
鏈接操作:
//添加1個月零5天,然后檢查該日期是否為星期五
Date.today().add({ months: 1, days: 5 }).is().fri();
//輸入日期,然后移至下一個星期五,減去一個月
Date.parse("10-July-2004").next().friday().add(-1).month();
日期比較:
Date.today().equals( Date.parse("today")); // true|false
Date.parse("last Tues").equals(Date.today()); // true|false
Date.equals(Date.today(), Date.parse("today")); // true|false
Date.compare(Date.today(), Date.parse("today")); // 1 = greater, -1 = less than,
Date.today().compareTo(Date.parse("yesterday")); // 1 = greater, -1 = less than, 0 = equal
Date.today().between(startDate, endDate); // true|false
轉換為字符串:
注意該format參數對于該.toString()功能是可選的。如果未提供format,.toString()則將調用本地JavaScript Date 函數。
標準日期和時間格式說明符
自定義日期和時間格式說明符
分隔符:
/ 正斜杠、空格、- 連字號、逗號
new Date().toString(); //星期三2007年10月31日格林尼治標準時間0700(太平洋夏令時間)
new Date().toString("M/d/yyyy"); //2007年10月31日
Date.today().toString("d-MMM-yyyy"); //2007年10月31日
new Date().toString("HH:mm"); // 16:18
Date.today().toString("MMMM dS, yyyy"); // April 12th, 2008
Date.today().toShortDateString();// "10/31/2007". 根據Date.CultureInfo.shortDatePattern特定于區域性
Date.today().toLongDateString();// "Wednesday, October 31, 2007". 根據Date.CultureInfo.longDatePattern特定于區域性
new Date().toShortTimeString();// "4:18 PM". 根據Date.CultureInfo.shortTimePattern特定于區域性
new Date().toLongTimeString();// "4:18:34 PM". 根據Date.CultureInfo.longTimePattern特定于區域性
核心用法:
//將日期設置為當前月份和年份的15號;
//其他對象值包括year|month|day|hour|minute|second。
Date.today().set({ day: 15 });
Date.today().set({ year: 2007, month: 1, day: 20 });
//將Date添加2天。其他對象值包括 year|month|day|hour|minute|second.
Date.today().add({ days: 2 });
Date.today().add({ years: -1, months: 6, hours: 3 });
Date.today().addYears(1); //增加1年
Date.today().addMonths(-2); //相減2個月
Date.today().addWeeks(1); //增加1周
Date.today().addDays(4); //增加4天
Date.today().addHours(6); //增加6小時
Date.today().addMinutes(-30); //相減30分鐘
Date.today().addSeconds(15); //增加15秒
Date.today().addMilliseconds(200); //增加200毫秒
Date.today().moveToFirstDayOfMonth();//返回當前月份的第一天
Date.today().moveToLastDayOfMonth();//返回當前月份的最后一天
new Date().clearTime(); //將時間設置為00:00(一天的開始)
Date.today().setTimeToNow();//將時間重置為當前時間;與clearTime()的功能相反
ISO 8601:
其他用法:
Date.getMonthNumberFromName("March");// 2-特定于CultureInfo。<static>
Date.getDayNumberFromName("sat");// 6-特定于CultureInfo。<靜態>
Date.isLeapYear(2008) // true|false. <static>
Date.getDaysInMonth(2007, 9) // 31 <static>
Date.today().getWeek();//返回一年中的第幾周。根據年份Date 返回1到(52 | 53)
Date.today().setWeek(1); //將一年中的星期幾設置為星期幾
var test = new Date(); // Do something... like run a test...
test.getElapsed(); //返回距現在的毫秒數
Date.today().isDaylightSavingTime();// true|false. 在夏令時之內
Date.today().hasDaylightSavingTime();// true|false. 是否遵守夏令時
Web前端開發之Javascript-零點程序員-王唯
*請認真填寫需求信息,我們會在24小時內與您取得聯系。