內容轉載自個人博客java
它是在協調世界時(UTC)中增長或減小一秒,使它與平太陽時貼近所作調整。須要閏秒的部分緣由是由於平均太陽日(mean solar day)的長度正以很是緩慢的速度增長中,另外一個緣由是原子鐘賦予秒固定的時間長度。而當二者結合時,就已經比當時的太陽時的秒短少了一點點。時間如今是以穩定的原子鐘來測量(TAI或國際原子時),由於地球自轉有着許多的變數,因此之前的秒定義(地球繞着軸自轉和繞太陽的公轉,以平均太陽日的1/86400來定義)被廢除。當要增長正閏秒時,這一秒是增長在次日的00:00:00以前,效果是延緩UTC次日的開始。當天23:59:59的下一秒被記爲23:59:60,而後纔是次日的00:00:00。若是是負閏秒的話,23:59:58的下一秒就是次日的00:00:00了,但目前尚未負閏秒調整的需求
Leap_Second.dat能夠查看每次閏秒的時間和第幾回閏秒,主要內容以下:python
# MJD Date TAI-UTC (s) # day month year # --- -------------- ------ # 41317.0 1 1 1972 10 41499.0 1 7 1972 11 41683.0 1 1 1973 12 42048.0 1 1 1974 13 42413.0 1 1 1975 14 42778.0 1 1 1976 15 43144.0 1 1 1977 16 43509.0 1 1 1978 17 43874.0 1 1 1979 18 44239.0 1 1 1980 19 44786.0 1 7 1981 20 45151.0 1 7 1982 21 45516.0 1 7 1983 22 46247.0 1 7 1985 23 47161.0 1 1 1988 24 47892.0 1 1 1990 25 48257.0 1 1 1991 26 48804.0 1 7 1992 27 49169.0 1 7 1993 28 49534.0 1 7 1994 29 50083.0 1 1 1996 30 50630.0 1 7 1997 31 51179.0 1 1 1999 32 53736.0 1 1 2006 33 54832.0 1 1 2009 34 56109.0 1 7 2012 35 57204.0 1 7 2015 36 57754.0 1 1 2017 37
根據文件Leap_Second.dat能夠得知,截止2020年08月:
TAI = UTC + 37
因爲GPST從1980年1月6日0時0分0秒開始計時,因此1980年1月1日及之前的閏秒不考慮,則:
GPST = UTC + 18
另外,leapsecond能夠查看實時的UTC、GPST、TAI時間函數
時區是指地球上的某一個區域使用同一個時間定義。GMT時間或者UT時間,都是表示地球自轉速率的一種形式。從太陽升起到太陽落下,時刻從0到24變化。這樣,不一樣經度的地方時間天然會不相同。爲了解決這個問題,人們把地球按經度劃分爲不一樣的區域,每一個區域內使用同一個時間定義,相鄰的區域時間差爲1個小時。時區又分爲理論時區和法定時區code
根據此代碼,修改最後一行fromtimestamp(timestamp, timezone(timedelta(hours=8)))
便可實現UTC轉不一樣時區orm
from datetime import datetime, timedelta, timezone # UTC時間轉本地時間(北京)時間 # 1. 把utc的str轉爲datetime(無時區信息) # 2. 添加時區信息爲utc時區 # 3. datetime轉爲時間戳 # 4. 從時間戳獲得本地時間datetime # 輸入格式爲:'2020-08-05 02:03:03.815650' # 輸出格式爲:datetime.datetime(2020, 8, 5, 10, 3, 3, 815650) def utc_to_local(utc_time): datetimeformat = "%Y-%m-%d %H:%M:%S.%f" # 獲得不包含時區的datetime dt_no_tz = datetime.strptime(utc_time, datetimeformat) # 設置時區爲UTC # timezone.utc與timezone(timedelta(hours=0))同樣 utc_datetime = dt_no_tz.replace(tzinfo=timezone(timedelta(hours=0))) t = utc_datetime.timestamp() # 根據時間戳獲得UTC時間 # datetime.utcfromtimestamp(t) # 若是要將時間戳轉化爲東八區datetime # fromtimestamp(timestamp, timezone(timedelta(hours=8))) # 根據時間戳獲得本地時間fromtimestamp(t, tz=None) return datetime.fromtimestamp(t)
根據此代碼,修改replace(tzinfo=timezone(timedelta(hours=8)))
便可實現某個時區轉UTC時間htm
from datetime import datetime, timedelta, timezone # 本地時間轉UTC時間 # 輸入格式爲:'2020-08-05 10:03:03.815650' # 輸出格式爲:datetime.datetime(2020, 8, 5, 2, 3, 3, 815650) def local_to_utc(local_time): datetimeformat = "%Y-%m-%d %H:%M:%S.%f" # 獲得不包含時區的datetime dt_no_tz = datetime.strptime(local_time, datetimeformat) # 設置時區爲本地時區(北京,東八區) # timezone.utc與timezone(timedelta(hours=0))同樣 local_datetime = dt_no_tz.replace(tzinfo=timezone(timedelta(hours=8))) t = local_datetime.timestamp() # 根據時間戳獲得UTC時間 return datetime.utcfromtimestamp(t)
將GPS時間轉換爲UTC時間blog
from datetime import datetime, timedelta # 閏秒 LEAP_SECONDS = 18 # 輸入:GPS周、GPS周內秒、閏秒(可選,gps時間不一樣,閏秒值也不一樣,由Leap_Second.dat文件決定) # 輸出:UTC時間(格林尼治時間) # 輸入示例: gps_week_seconds_to_utc(2119, 214365.000) # 輸出示例: '2020-08-18 11:32:27.000000' def gps_week_seconds_to_utc(gpsweek, gpsseconds, leapseconds=LEAP_SECONDS): datetimeformat = "%Y-%m-%d %H:%M:%S.%f" epoch = datetime.strptime("1980-01-06 00:00:00.000", datetimeformat) # timedelta函數會處理seconds爲負數的狀況 elapsed = timedelta(days=(gpsweek*7), seconds=(gpsseconds-leapseconds)) return datetime.strftime(epoch+elapsed, datetimeformat)
將UTC時間轉換爲GPS時間get
from datetime import datetime, timedelta # 閏秒 LEAP_SECONDS = 18 # 輸入:UTC時間(datetime類型) # 輸出:GPS周、周內日、周內秒、毫秒 def utc_to_gps_week_seconds(utc, leapseconds=LEAP_SECONDS): datetimeformat = "%Y-%m-%d %H:%M:%S.%f" epoch = datetime.strptime("1980-01-06 00:00:00.000", datetimeformat) tdiff = utc - epoch + timedelta(seconds=leapseconds) gpsweek = tdiff.days // 7 gpsdays = tdiff.days - 7*gpsweek gpsseconds = tdiff.seconds + 86400*(tdiff.days -7*gpsweek) return gpsweek, gpsdays, gpsseconds, tdiff.microseconds