Python datetime thành chuỗi không có thành phần microsecond


410

Tôi đang thêm các chuỗi thời gian UTC vào các phản hồi API của Bitbucket hiện chỉ chứa các chuỗi thời gian Amsterdam (!). Để thống nhất với chuỗi thời gian UTC được trả về ở nơi khác, định dạng mong muốn là 2011-11-03 11:07:04(theo sau là+00:00 , nhưng đó không phải là nguyên bản).

Cách tốt nhất để tạo một chuỗi như vậy ( không có thành phần micro giây) từ một datetimethể hiện thành phần micro giây là gì?

>>> import datetime
>>> print unicode(datetime.datetime.now())
2011-11-03 11:13:39.278026

Tôi sẽ thêm tùy chọn tốt nhất xảy ra với tôi như một câu trả lời có thể, nhưng cũng có thể có một giải pháp thanh lịch hơn.

Chỉnh sửa: Tôi nên đề cập rằng tôi không thực sự in thời gian hiện tại - tôi đã từng datetime.nowcung cấp một ví dụ nhanh. Vì vậy, giải pháp không nên cho rằng bất kỳ datetimetrường hợp nào nó nhận được sẽ bao gồm các thành phần micro giây.

Câu trả lời:


840

Nếu bạn muốn định dạng một datetimeđối tượng theo một định dạng cụ thể khác với định dạng tiêu chuẩn, tốt nhất là chỉ định rõ ràng định dạng đó:

>>> datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
'2011-11-03 18:21:26'

Xem tài liệudatetime.strftime() để được giải thích về các %chỉ thị.


10
Một đồng nghiệp chỉ đưa ra một trường hợp thuyết phục cho việc này là cách tiếp cận chính xác. Hãy xem xét tôi thuyết phục.
davidchambers

3
Trường hợp thuyết phục đó là gì - đưa giải pháp này lên trên giải pháp của bạn bằng datetime.replace?
matlehmann

13
@matlehmann: Tất nhiên tôi không biết những lập luận của đồng nghiệp của davidchambers. Tuy nhiên, tôi nghĩ rằng nếu ý định của bạn là in một ngày theo định dạng rất cụ thể, bạn nên rõ ràng về ý định này. Mã trong câu trả lời này cho biết "hãy dành thời gian hiện tại và định dạng chính xác như thế này". Mã trong câu trả lời khác nói rằng "hãy dành thời gian hiện tại, đặt micrô giây thành 0 và sau đó chuyển đổi nó thành một chuỗi bằng cách nào đó".
Sven Marnach

3
+1, rõ ràng về định dạng chuỗi sẽ tránh được các vấn đề nếu chuyển đổi chuỗi thời gian chuẩn thay đổi trong phiên bản Python trong tương lai
Alan Evangelista

2
@DylanYoung Yêu cầu của OP là in một đối tượng datetime theo định dạng khác với định dạng chuẩn được trả về .isoformat(), bao gồm các micrô giây theo mặc định. Nếu đó là những gì bạn cần, hãy rõ ràng về nó. Mọi người sẽ ngay lập tức hiểu mã này làm gì. Hầu như không ai sẽ hiểu các mã khác mà không cần nhìn vào tài liệu.
Sven Marnach

172
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07

20
Tôi nghĩ, đây là giải pháp phù hợp, bởi vì nó là hành vi có thể đọc được và được ghi lại và nhất quán: " .isoformat([sep])- Trả về một chuỗi biểu thị ngày và thời gian ở định dạng ISO 8601, YYYY-MM-DDTHH: MM: SS.mmmmmm hoặc, nếu micro giây 0, YYYY-MM-DDTHH: MM: SS "
Bengt

1
trong tình huống của tôi, ngày đã được xây dựng và tôi cần "chuyển" nó sang ngày thứ hai. Điều này là hoàn hảo, cảm ơn.
Vigrond

1
Đây là câu trả lời tốt nhất!
Havok

Tốt hơn nhiều so với định dạng hoặc phân tích chuỗi để so sánh, cảm ơn bạn.
Zach Young

69

Trong Python 3.6:

from datetime import datetime
datetime.datetime.now().isoformat(' ', 'seconds')
'2017-01-11 14:41:33'

https://docs.python.org/3.6/lvern/datetime.html#datetime.datetime.isoformat


4
Tôi nghĩ rằng bây giờ, 8 năm sau với sự ra đời của Python 3.6, đây sẽ là câu trả lời phổ biến, được chấp nhận. Điều này mang đến sự tốt hơn của cả hai thế giới được tranh luận bởi @DylanYoung và AlexanderMP trên cùng một chủ đề ở đây
pfabri


47

Đây là cách tôi làm. Định dạng ISO:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
# Returns: '2017-01-23T14:58:07'

Bạn có thể thay thế 'T' nếu bạn không muốn định dạng ISO:

datetime.datetime.now().replace(microsecond=0).isoformat(' ')
# Returns: '2017-01-23 15:05:27'

Điều này tương tự như câu trả lời của tôi. Có một lý do để ủng hộ .isoformat()hơn unicode()?
davidchambers

1
Phụ thuộc vào những gì bạn muốn, nếu bạn muốn sử dụng biểu diễn chuỗi python unicode()và nếu bạn muốn ISO-8601, hãy sử dụngisoformat()
radtek

Tôi hiểu rồi. unicode()là thuận tiện hơn .isoformat().replace('T', ' '), chắc chắn. ;)
davidchambers

Tôi sẽ chỉ sử dụng giải pháp của Sven cho định dạng không phải là iso, rõ ràng hơn: datetime.now (). Strftime ("% Y-% m-% d% H:% M"), nhưng thay thế 'T' chỉ là một cách khác đường. Có thể là giải pháp tốt nhất nếu bạn cần cả ISO và ngày unicode.
radtek

isoformatchấp nhận bộ phân tách, do đó không nên thay thế. chỉ cần làm:datetime.datetime.now().replace(microsecond=0).isoformat(' ')
coya

17

Một lựa chọn khác:

>>> import time
>>> time.strftime("%Y-%m-%d %H:%M:%S")
'2011-11-03 11:31:28'

Theo mặc định, điều này sử dụng giờ địa phương, nếu bạn cần UTC, bạn có thể sử dụng như sau:

>>> time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
'2011-11-03 18:32:20'

Downvote vì OP hỏi về datetime chứ không phải thời gian.
Jürgen A. Erhard

15

Giữ 19 ký tự đầu tiên mà bạn muốn thông qua cắt:

>>> str(datetime.datetime.now())[:19]
'2011-11-03 14:37:50'

5
Điều này chỉ không chính xác vì các chuỗi thời gian có thể có thêm đặc tả múi giờ, ví dụ +05:30. Đúng sẽ là str(now())[:19].
K3 --- rnc

1
@ K3 --- rnc: Cảm ơn. Cập nhật theo đề nghị của bạn.
Steven Rumbalski

sau năm 10000, một giây sẽ bị bỏ lỡ
diti

thời gian sẽ trả lời @diti;)
ysʞǝla

8

Tôi thường làm:

import datetime
now = datetime.datetime.now()
now = now.replace(microsecond=0)  # To print now without microsecond.

# To print now:
print(now)

đầu ra:

2019-01-13 14:40:28

7

Vì không phải tất cả các datetime.datetimetrường hợp đều có thành phần microsecond (tức là khi nó bằng 0), bạn có thể phân vùng chuỗi trên "." và chỉ lấy mục đầu tiên, sẽ luôn hoạt động:

unicode(datetime.datetime.now()).partition('.')[0]

3

Chúng ta có thể thử một cái gì đó như dưới đây

import datetime

date_generated = datetime.datetime.now()
date_generated.replace(microsecond=0).isoformat(' ').partition('+')[0]

Điều này là kém hơn .isoformat(' ', 'seconds'), được đề xuất trong một câu trả lời trước đó.
davidchambers

1
Khi tôi đang thử ở trên câu trả lời được đề xuất trước đó, tôi gặp lỗi bên dưới >>> datetime.datetime.now (). Isoformat ('', 'giây') TracBack (cuộc gọi gần đây nhất cuối cùng): Tệp "<stdin>", dòng 1, trong <module> TypeError: isoformat () mất tối đa 1 đối số (2 đã cho)
Abhishek Bajaj

Ah tôi thấy. Nó hoạt động với tôi trong Python 3 nhưng không phải trong Python 2.
davidchambers

Tôi đang sử dụng phiên bản python 3.4.3, trong đó tôi thấy lỗi đó. >>> datetime.datetime.now (). isoformat ('', 'giây') TracBack (cuộc gọi gần đây nhất cuối cùng): Tệp "<stdin>", dòng 1, trong <module> TypeError: isoformat () mất nhiều nhất 1 đối số (2 cho)
Abhishek Bajaj

1

Tôi thấy đây là cách đơn giản nhất.

>>> t = datetime.datetime.now()
>>> t
datetime.datetime(2018, 11, 30, 17, 21, 26, 606191)
>>> t = str(t).split('.')
>>> t
['2018-11-30 17:21:26', '606191']
>>> t = t[0]
>>> t
'2018-11-30 17:21:26'
>>> 

datetime.datetime.now (). strftime ("% Y-% m-% d% H:% M:% S") '2011-11-03 18:21:26' imo dễ dàng hơn nhiều. Nhưng dễ dàng không phải là tốt nhất
An0n

1

Cái này tôi sử dụng vì tôi có thể hiểu và do đó nhớ nó tốt hơn (và định dạng ngày giờ cũng có thể được tùy chỉnh dựa trên sự lựa chọn của bạn): -

import datetime
moment = datetime.datetime.now()
print("{}/{}/{} {}:{}:{}".format(moment.day, moment.month, moment.year,
                                 moment.hour, moment.minute, moment.second))

Xuất sắc. Đơn giản, linh hoạt và độc lập với nền tảng (không giống như strftime).
Endre Cả
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.