python 1970年之前的時間戳和js中時間戳的統一問題


問題: 1970年之前的時間戳,python該如何處理呢? 如何與js等處理結果保持一致?

在做接口自動化時遇到如下情況,需要根據身份證號中的出生年月,自動生成出生日期時間戳:

先看下java時間的處理 以1955-05-07為列:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.Calendar;

public class timeTest {
    public static void main(String[] args) throws ParseException {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        java.util.Date date = df.parse("1955-05-07");
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        long timestamp = cal.getTimeInMillis();
        System.out.println(timestamp);   // -462528000000
    }
}

首先大家一定會想到用time模塊,簡單粗暴易上手,結果:

import time
stamp=time.mktime(time.strptime('1955-05-07', '%Y-%m-%d'))
print(int(stamp))
>>> Traceback (most recent call last):
  File "<input>", line 3, in <module>
OverflowError: mktime argument out of range

查閱資料會發現:

  • mktime()是localtime()的反函數,localtime根據秒數返回時間戳
  • 它的參數是struct_time或完整的9個元組,它返回一個浮點數,可以視為從最早時間戳開始的描述。
  • Windows中時間戳是有范圍的,參考官方文檔,只要不在這個范圍內,使用時就會報錯
  • 文檔中提到不能早於midnight, January 1, 1970,不能晚於23:59:59 January 18, 2038

於是通過datetime模塊反推,最簡單的方法:

import datetime
timestamp = -462528000000
print(datetime.datetime(1970, 1, 1) + datetime.timedelta(milliseconds=timestamp))
>>> 1955-05-06 16:00:00

結果1955-05-06 16:00:00,同樣的時間為毛反推出來差了一天,
經查閱資料發現,這個和地區時間有關,中國使用東八區時間,datetime.datetime(1970, 1, 1),只給定年月日,系統默認是1970-1-1 00:00:00
而東八區的時間戳0為:datetime.datetime(1970, 1, 1, 8)

所以將上面的零點換成datetime.datetime(1970, 1, 1, 8)

print(datetime.datetime(1970, 1, 1, 8) + datetime.timedelta(milliseconds=-462528000000))
>>> 1955-05-07 00:00:00

總結一下:windows系統下python 時間模塊time和datetime目前還無法直接處理負數時間戳(linux據說可以直接處理),所以只能反推

為了方便使用簡單的封裝了一下:

def id_card():
    """
    隨機生成1970年之前的出生日期,時間戳
    :return:
    """
    days = random.randint(0, 8000)
    timestamp = days * 24 * 60 * 60 * -1000
    date_tuple = datetime.datetime(1970, 1, 1, 8) + datetime.timedelta(milliseconds=timestamp)  # 將時間戳生成時間元組
    date_str = date_tuple.strftime('%Y-%m-%d')
    return timestamp, date_str 

if __name__ == '__main__':
    timestamp, id_no = id_card()
    print(timestamp, id_no)
>>> -557366400000 629016195205047242

如此生成的時間戳和身份證號完美匹配。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM