Python Tạo dấu thời gian unix năm phút trong tương lai


297

Tôi phải tạo một giá trị "Hết hạn" trong 5 phút trong tương lai, nhưng tôi phải cung cấp nó ở định dạng Dấu thời gian UNIX. Tôi có điều này cho đến nay, nhưng nó có vẻ như một hack.

def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    epoch = datetime.datetime(1970, 1, 1)
    seconds_in_a_day = 60 * 60 * 24
    five_minutes = datetime.timedelta(seconds=5*60)
    five_minutes_from_now = datetime.datetime.now() + five_minutes
    since_epoch = five_minutes_from_now - epoch
    return since_epoch.days * seconds_in_a_day + since_epoch.seconds

Có mô-đun hoặc chức năng nào chuyển đổi dấu thời gian cho tôi không?


7
Tôi khuyên bạn nên thay đổi chủ đề của câu hỏi này. Câu hỏi là tốt, nhưng nó không phải là về việc chuyển đổi datetime sang dấu thời gian Unix. Đó là về cách lấy dấu thời gian Unix 5 phút trong tương lai.
DA

Tôi không đồng ý, @DA Câu hỏi về cơ bản là "Tôi cần làm X và Y. Đây là những gì tôi có bây giờ. Cách nào tốt hơn để làm Y?" Có thể có nhiều cách tốt hơn để làm X, nhưng tiêu đề và cơ thể hỏi rõ ràng về Y.
Rob Kennedy

6
Tôi hoàn toàn đồng ý với bạn về câu hỏi và tôi nghĩ đây là một câu trả lời hay. Vấn đề là "Python datetime to Unix timestamp" không phản ánh câu hỏi hoặc câu trả lời. Tôi tìm thấy bài đăng này để tìm cách thực hiện chuyển đổi và tôi đã mất thời gian vì dòng tiêu đề sai lệch. Tôi đề nghị: "Python, 5 phút trong tương lai là Dấu thời gian UNIX"
DA

3
@JimmyKane - Một câu trả lời khá toàn diện về làm thế nào để có được một dấu thời gian từ thời điểm ngày có thể được tìm thấy ở đây: stackoverflow.com/questions/8777753/...
Tim Tisdall

@TimTonomall có kể từ khi tiêu đề được thay đổi, không có ý nghĩa gì
Jimmy Kane

Câu trả lời:


349

Một cách khác là sử dụng calendar.timegm:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return calendar.timegm(future.timetuple())

Nó cũng dễ mang theo hơn %scờ strftime(không hoạt động trên Windows).


Cảm ơn D.Shawley. help (datetime.timedelta) đã không đề cập đến lối tắt đó. Nó chỉ có ngày, giây và micro giây.
Daniel Rhoden

12
Lưu ý rằng, kết hợp hai ý kiến ​​trước, giải pháp đúng là : calendar.timegm(future.utctimetuple()). Điều này đảm bảo rằng thời gian UTC được truyền vào calendar.timegm.
shadowmatter

1
Không thể upvote @ tumbleweed bình luận đủ. Nếu bạn đang cố lấy dấu thời gian UNIX (và do đó là một trong UTC), hãy sử dụng calendar.timegm.
Bialecki

@tumbleweed, đúng rồi. Nếu bạn sử dụng mktime cộng với gmtime (0) sẽ dẫn đến delta roundtrip nonzero cho bất kỳ múi giờ nào ngoài UTC: ví dụ `time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))). Timetuple () cho 21600.0giây (6 giờ) thay vì 0,0 cho TZ của máy unix của tôi
hobs

Nếu bạn muốn lấy dấu thời gian UTC, bạn nên sử dụng : calendar.timegm(datetime.datetime.utcnow().timetuple()). Phương pháp sử dụng datetime.datetime.now().utctimetuple()không hoạt động đối với tôi (Python 3.2).
Wookie88

155

Bây giờ trong Python> = 3.3 bạn chỉ có thể gọi phương thức dấu thời gian () để lấy dấu thời gian dưới dạng float.

import datetime
current_time = datetime.datetime.now(datetime.timezone.utc)
unix_timestamp = current_time.timestamp() # works if Python >= 3.3

unix_timestamp_plus_5_min = unix_timestamp + (5 * 60)  # 5 min * 60 seconds

4
+1 cho điều này. Nó nên được hiển thị cao hơn nhiều, bởi vì đó là cách rõ ràng để làm điều đó trong Python 3
Viktor Stískala

2
@ scott654 Tôi nghĩ rằng có nó ngay từ đầu bình luận đã làm cho nó đủ rõ ràng, nhưng tôi cũng đã thêm một số đậm vào nó.
Tim Tonomall

1
Tôi sẽ ghi chú dưới dạng một nhận xét trong khối mã bởi vì tất cả chúng ta chỉ quét mã trong các câu trả lời trước và chỉ đọc phần còn lại nếu mã có vẻ tốt. Câu trả lời tốt mặc dù.
Matthew Purdon

2
giờ địa phương có thể mơ hồ . Ví dụ ( datetime.now()) là xấu vì nó khuyến khích việc sử dụng các đối tượng datetime ngây thơ đại diện cho giờ địa phương và nó có thể thất bại trong quá trình chuyển đổi DST (do sự mơ hồ vốn có). Bạn có thể sử dụng ts = datetime.now(timezone.utc).timestamp()thay thế.
jfs

@JFSebastian - điểm tốt. Tuy nhiên, tôi không muốn thêm vào hàng nhập khẩu, vì vậy tôi đã đổi nó thành utcnow(). Tôi đã từng làm việc trên các máy có múi giờ được đặt thành UTC, nhưng điều đó không nên được giả sử trong đoạn mã này.
Tim Tonomall

139

Chỉ cần tìm thấy điều này, và nó thậm chí còn ngắn hơn.

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)

12
Điều này không trả lời câu hỏi.
Jesse Dhillon

22
@JesseDhillon nó trả lời câu hỏi (tạo dấu thời gian UNIX 5 phút trong tương lai), không phải là tiêu đề.
DBR

3
time.time()có thể được đặt lại. Để tạo giá trị "Hết hạn" trong 5 phút trong tương lai, bạn có thể cần time.monotonic()tương tự tùy thuộc vào trường hợp sử dụng của mình.
jfs

@ jf-sebastian time.monotonic () không trả về dấu thời gian UNIX, nó trả về dấu thời gian với điểm tham chiếu không xác định.
rspeer

@rspeer: có, như các tài liệu nói , chỉ có sự khác biệt giữa các cuộc gọi liên tiếp là hợp lệ. Việc monotoniccó thể được sử dụng hay không tùy thuộc vào trường hợp sử dụng của bạn, ví dụ, subprocessmô-đun có sử dụng nó để thực hiện timeouttùy chọn không.
jfs

57

Đây là những gì bạn cần:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())

Điều này khác biệt hoặc thêm vào một 'Cat Plus Plus' được cung cấp như thế nào?
David

3
Vì đây là câu trả lời cho câu hỏi "Python datetime to Unix timestamp" trong khi Cat Plus Plus trả lời câu hỏi "Python datetime sẽ có trong 5 phút tới Unix timestamp". Vì vậy, cái này là sạch sẽ và rõ ràng.
chạy.t

@ running.t: nó nhắc nhở tôi: "mọi vấn đề đều có giải pháp đơn giản, rõ ràng và sai lầm ". Xem các vấn đề có thể vớimktime(dt.timetuple()) . datetime.now(timezone.utc).timestamp()được cung cấp bởi @Tim Tonomall là giải pháp trong Python 3.3+. Nếu không (dt - epoch).total_seconds()có thể được sử dụng .
jfs

@JFSebastian nếu tôi thực sự muốn tất cả các tính toán diễn ra trong giờ địa phương thì sao? Có phải là trường hợp khi ví dụ. để phân tích một chuỗi ngây thơ mà người ta biết là giờ địa phương và quyết định liệu có DST có hiệu lực trong thời gian cụ thể đó không?
n611x007

1
@naxa: vâng, một số thời gian địa phương là mơ hồ hoặc không tồn tại. Ngoài ra bù thời gian có thể khác nhau vì các lý do khác với DST (bạn cần cơ sở dữ liệu tz như pytz, để tìm ra bù chính xác). Giờ địa phương có nghĩa là bất cứ điều gì chính trị gia địa phương nghĩ là một ý tưởng tốt để đo thời gian, nó có thể rất bất thường.
JFS

48

Bạn có thể sử dụng datetime.strftimeđể lấy thời gian ở dạng Epoch, sử dụng %schuỗi định dạng:

def expires():
    future = datetime.datetime.now() + datetime.timedelta(seconds=5*60)
    return int(future.strftime("%s"))

Lưu ý: Điều này chỉ hoạt động trong linux và phương pháp này không hoạt động với các múi giờ.


32
Đây là một hành vi hơi không có giấy tờ ( python.org/doc/civerse/l Library / datetime.html ). Có vẻ như đang làm việc dưới linux và không hoạt động dưới win32 (tạo ValueError: Invalid format string).
Antony Hatchkins

3
Phương pháp này không hoạt động với múi giờ. Thay đổi múi giờ sẽ cho cùng một thời gian kết quả (2013,12,7, tzinfo = múi giờ ("America / Chicago")). Strftime ("% s") Riga ")). Strftime ("% s ") 1386385200
Martins Balodis


6
def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()

4

Điều quan trọng là đảm bảo tất cả các ngày bạn đang sử dụng đều nằm trong múi giờ utc trước khi bạn bắt đầu chuyển đổi. Xem http://pytz.sourceforge.net/ để tìm hiểu cách thực hiện đúng. Bằng cách bình thường hóa thành utc, bạn loại bỏ sự mơ hồ của các chuyển đổi tiết kiệm ánh sáng ban ngày. Sau đó, bạn có thể sử dụng timedelta một cách an toàn để tính khoảng cách từ kỷ nguyên unix, sau đó chuyển đổi thành giây hoặc mili giây.

Lưu ý rằng dấu thời gian unix kết quả là chính nó trong múi giờ UTC. Nếu bạn muốn xem dấu thời gian trong múi giờ địa phương hóa, bạn sẽ cần thực hiện một chuyển đổi khác.

Cũng lưu ý rằng điều này sẽ chỉ hoạt động cho ngày sau năm 1970.

   import datetime
   import pytz

   UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc)
   def EPOCH(utc_datetime):
      delta = utc_datetime - UNIX_EPOCH
      seconds = delta.total_seconds()
      ms = seconds * 1000
      return ms

3
lưu ý: Tôi không hiểu "dấu thời gian [unix] trong múi giờ địa phương hóa". Dấu thời gian là như nhau (kể từ giây trôi qua 1970-01-01 00:00:00+00:00). Để có được một đối tượng datetime ngây thơ trong múi giờ địa phương:datetime.fromtimestamp(ts)
jfs

4

Sau đây là dựa trên các câu trả lời ở trên (cộng với hiệu chỉnh cho mili giây) và mô phỏng datetime.timestamp() cho Python 3 trước 3.3 khi sử dụng múi giờ.

def datetime_timestamp(datetime):
    '''
    Equivalent to datetime.timestamp() for pre-3.3
    '''
    try:
        return datetime.timestamp()
    except AttributeError:
        utc_datetime = datetime.astimezone(utc)
        return timegm(utc_datetime.timetuple()) + utc_datetime.microsecond / 1e6

Để trả lời đúng câu hỏi khi được hỏi, bạn muốn:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestamplà một phần của ngày đơn giản . Nhưng nếu bạn đang sử dụng gói đó, bạn có thể gõ:

SimpleDate(my_datetime).timestamp + 5 * 60

xử lý nhiều định dạng / loại hơn cho my_datetime.


bạn không nên thêm (5 * 60) để thêm 5 phút? Tôi nghĩ rằng chỉ cần thêm 5 chỉ thêm 5 giây vào dấu thời gian.
Tim Tonomall

1
def expiration_time():
    import datetime,calendar
    timestamp = calendar.timegm(datetime.datetime.now().timetuple())
    returnValue = datetime.timedelta(minutes=5).total_seconds() + timestamp
    return returnValue

1

Lưu ý rằng các giải pháp với timedelta.total_seconds()công việc trên python-2.7 +. Sử dụng calendar.timegm(future.utctimetuple())cho các phiên bản thấp hơn của Python.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.