Memformat datetime menjadi string dengan milidetik

169

Saya ingin memiliki datetimestring dari tanggal dengan milidetik. Kode ini khas untuk saya dan saya ingin belajar bagaimana mempersingkatnya.

from datetime import datetime

timeformatted= str(datetime.utcnow())
semiformatted= timeformatted.replace("-","")
almostformatted= semiformatted.replace(":","")
formatted=almostformatted.replace(".","")
withspacegoaway=formatted.replace(" ","")
formattedstripped=withspacegoaway.strip()
print formattedstripped
Jurudocs
sumber
3
Harap tulis judul yang menjelaskan masalah Anda dan usahakan agar pertanyaan Anda tetap jelas dan to the point.
agf
Perlu disebutkan di sini bahwa ketepatan ekstra sering kali baik-baik saja. Sebagai contoh, Java Instant.parsedapat mengurai representasi yang dibuat denganstrftime('%Y-%m-%dT%H:%M:%S.%fZ')
Jarek Przygódzki

Jawaban:

354

Untuk mendapatkan string tanggal dengan milidetik (3 tempat desimal di belakang detik), gunakan ini:

from datetime import datetime

print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]

>>>> OUTPUT >>>>
2020-05-04 10:18:32.926

Catatan: Untuk Python3, printmembutuhkan tanda kurung:

print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
Jeremy Moritz
sumber
1
Tepatnya, 2013-08-23 10:18:32.926adalah output dari print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] .
Jaan
3
Catatan, jika Anda ingin menggunakan import datetimesebagai gantinya from datetime import datetime, Anda harus menggunakan ini:datetime.datetime.utcnow().strftime("%H:%M:%S.%f")
Luc
17
Dalam kasus microseconds adalah 0, di windows 2.7 implementasi microseconds tidak dicetak sehingga memangkas detik :(
cabbi
8
perhatikan bahwa ini terpotong, bukan putaran ke milidetik
gens
2
Seperti yang disebutkan gen, bukankah ini salah, kalau angka tetes pertama adalah> = 5 ?. Bahkan jika bagian usec> 999500, maka Anda tidak akan pernah mendapatkan waktu yang tepat dengan mengutak-atik bagian mikrodetik
Chris
59

Dengan Python 3.6 Anda dapat menggunakan:

from datetime import datetime
datetime.utcnow().isoformat(sep=' ', timespec='milliseconds')

Keluaran:

'2019-05-10 09:08:53.155'

Info lebih lanjut di sini: https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat

Lorenzo
sumber
Berguna dengan zona waktu juga: date = datetime (2019,5,10) date_with_tz = pytz.timezone ('Eropa / Roma'). Melokalkan (tanggal) date_with_tz.isoformat (sep = 'T', timespec = 'milliseconds') output: '2019-05-10T00: 00: 00.000 + 02: 00'
Ena
Ini adalah solusi aktual yang harus diterima. Dan isoformat () adalah apa yang saya butuhkan untuk ekspor ke format GPX, terima kasih banyak!
Filipus Happy
22
print datetime.utcnow().strftime('%Y%m%d%H%M%S%f')

http://docs.python.org/library/datetime.html#strftime-strptime-behavior

rajutan
sumber
13
FYI, ini mencetak mikrodetik sebagai 6 digit terakhir. Tambahkan [:-3]ke akhir untuk menjatuhkan 3 digit terakhir sehingga hanya menampilkan milidetik.
Mark Lakata
5
mikrodetik dapat kurang dari 6 digit, jadi [: -3] mencetak milidetik yang salah
cabbi
13
bagaimana jika kita memiliki zona waktu?
ᐅ devrimbaris
1
@ ᐅ devrimbaris untuk checkout zona waktu Jawaban Lorenzo
Ena
17

@Cabbi mengangkat masalah yang pada beberapa sistem, format microseconds %fmungkin berikan "0", jadi tidak portabel untuk hanya memotong tiga karakter terakhir.

Kode berikut dengan hati-hati memformat cap waktu dengan milidetik:

from datetime import datetime
(dt, micro) = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f').split('.')
dt = "%s.%03d" % (dt, int(micro) / 1000)
print dt

Contoh Output:

2016-02-26 04:37:53.133

Untuk mendapatkan hasil persis seperti yang diinginkan OP, kita harus menghapus karakter tanda baca:

from datetime import datetime
(dt, micro) = datetime.utcnow().strftime('%Y%m%d%H%M%S.%f').split('.')
dt = "%s%03d" % (dt, int(micro) / 1000)
print dt

Contoh Output:

20160226043839901
Sam Watkins
sumber
6
Apa yang sebenarnya saya lakukan adalah ini: cetak '% s.% 03d'% (dt.strftime ("% Y-% m-% d% H:% M:% S"), int (dt.microsecond / 1000 ))
cabbi
2
setuju dengan @cabbi, tidak perlu mengonversi bolak - balik dengan string dan int
caoanan
ya saya setuju juga ... :)
Sam Watkins
1
Jawaban ini jauh lebih tepat dan aman daripada yang lain. Terima kasih!
Hunaphu
5

Mungkin seperti ini:

import datetime
now = datetime.datetime.now()
now.strftime('%Y/%m/%d %H:%M:%S.%f')[:-3]  
# [:-3] => Removing the 3 last characters as %f is for microsecs.
N Fayçal
sumber
Yang kedua %mharus a %M, karena itu menit, bukan bulan.
Michael Dorner
2

Saya berasumsi Anda maksud Anda sedang mencari sesuatu yang lebih cepat daripada datetime.datetime.strftime (), dan pada dasarnya menghilangkan karakter non-alpha dari timestamp utc.

Pendekatan Anda sedikit lebih cepat, dan saya pikir Anda dapat mempercepat lebih banyak hal dengan mengiris string:

>>> import timeit
>>> t=timeit.Timer('datetime.utcnow().strftime("%Y%m%d%H%M%S%f")','''
... from datetime import datetime''')
>>> t.timeit(number=10000000)
116.15451288223267

>>> def replaceutc(s):
...     return s\
...         .replace('-','') \
...         .replace(':','') \
...         .replace('.','') \
...         .replace(' ','') \
...         .strip()
... 
>>> t=timeit.Timer('replaceutc(str(datetime.datetime.utcnow()))','''
... from __main__ import replaceutc
... import datetime''')
>>> t.timeit(number=10000000)
77.96774983406067

>>> def sliceutc(s):
...     return s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:]
... 
>>> t=timeit.Timer('sliceutc(str(datetime.utcnow()))','''
... from __main__ import sliceutc
... from datetime import datetime''')
>>> t.timeit(number=10000000)
62.378515005111694
Austin Marshall
sumber
@oxtopus Kerja bagus. Secara pribadi, saya tidak menggunakan timeit lagi untuk pengukuran waktu yang sederhana. Sungguh aneh bahwa rasio waktu berbeda dengan kode Anda: 1 - 0,67 - 0,53 dan dengan milik saya: 1 - 0,35 - 0,20, untuk metode strftime - replace - slicing
eyquem
Mungkin ada hubungannya dengan str (datetime.datetime.utcnow ()) dipanggil dalam setiap iterasi tes vs pengaturan sekali?
Austin Marshall
1
from datetime import datetime
from time import clock

t = datetime.utcnow()
print 't == %s    %s\n\n' % (t,type(t))

n = 100000

te = clock()
for i in xrange(1):
    t_stripped = t.strftime('%Y%m%d%H%M%S%f')
print clock()-te
print t_stripped," t.strftime('%Y%m%d%H%M%S%f')"

print

te = clock()
for i in xrange(1):
    t_stripped = str(t).replace('-','').replace(':','').replace('.','').replace(' ','')
print clock()-te
print t_stripped," str(t).replace('-','').replace(':','').replace('.','').replace(' ','')"

print

te = clock()
for i in xrange(n):
    t_stripped = str(t).translate(None,' -:.')
print clock()-te
print t_stripped," str(t).translate(None,' -:.')"

print

te = clock()
for i in xrange(n):
    s = str(t)
    t_stripped = s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:] 
print clock()-te
print t_stripped," s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:] "

hasil

t == 2011-09-28 21:31:45.562000    <type 'datetime.datetime'>


3.33410112179
20110928212155046000  t.strftime('%Y%m%d%H%M%S%f')

1.17067364707
20110928212130453000 str(t).replace('-','').replace(':','').replace('.','').replace(' ','')

0.658806915404
20110928212130453000 str(t).translate(None,' -:.')

0.645189262881
20110928212130453000 s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:]

Penggunaan metode translate () dan slicing berjalan dalam waktu yang sama
translate () menyajikan keuntungan untuk dapat digunakan dalam satu baris

Membandingkan waktu berdasarkan yang pertama:

1.000 * t.jalan waktu ('% Y% m% d% H% M% S% f')

0,351 * str (t) .replace ('-', ''). Replace (':', ''). Replace ('.', ''). Replace ('', '')

0.198 * str (t) .translate (Tidak ada, '- :.')

0,194 * s [: 4] + s [5: 7] + s [8:10] + s [11:13] + s [14:16] + s [17:19] + s [20:]

eyquem
sumber
1
Bagus! Itu memang lebih bersih tanpa mengorbankan kinerja. str.translate () sebenarnya lebih cepat dalam pengujian saya.
Austin Marshall
1

Saya berurusan dengan masalah yang sama tetapi dalam kasus saya adalah penting bahwa milidetik itu bulat dan tidak terpotong

from datetime import datetime, timedelta

def strftime_ms(datetime_obj):
    y,m,d,H,M,S = datetime_obj.timetuple()[:6]
    ms = timedelta(microseconds = round(datetime_obj.microsecond/1000.0)*1000)
    ms_date = datetime(y,m,d,H,M,S) + ms
    return ms_date.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
omdaniel
sumber
1
import datetime

# convert string into date time format.

str_date = '2016-10-06 15:14:54.322989'
d_date = datetime.datetime.strptime(str_date , '%Y-%m-%d %H:%M:%S.%f')
print(d_date)
print(type(d_date)) # check d_date type.


# convert date time to regular format.

reg_format_date = d_date.strftime("%d %B %Y %I:%M:%S %p")
print(reg_format_date)

# some other date formats.
reg_format_date = d_date.strftime("%Y-%m-%d %I:%M:%S %p")
print(reg_format_date)
reg_format_date = d_date.strftime("%Y-%m-%d %H:%M:%S")
print(reg_format_date)

<<<<<< OUTPUT >>>>>>>

2016-10-06 15:14:54.322989    
<class 'datetime.datetime'>    
06 October 2016 03:14:54 PM    
2016-10-06 03:14:54 PM    
2016-10-06 15:14:54
Waqas Ali
sumber
1
python -c "from datetime import datetime; print str(datetime.now())[:-3]"
2017-02-09 10:06:37.006
arntg
sumber
0
datetime
t = datetime.datetime.now()
ms = '%s.%i' % (t.strftime('%H:%M:%S'), t.microsecond/1000)
print(ms)
14:44:37.134
Hunaphu
sumber
0

Masalah dengan datetime.utcnow()dan solusi lainnya adalah lambat.

Solusi yang lebih efisien mungkin terlihat seperti ini:

def _timestamp(prec=0):
    t = time.time()
    s = time.strftime("%H:%M:%S", time.localtime(t))
    if prec > 0:
        s += ("%.9f" % (t % 1,))[1:2+prec]
    return s

Dimana precakan 3dalam kasus Anda (milidetik).

Fungsi ini berfungsi hingga 9 tempat desimal (harap perhatikan nomor 9dalam string pemformatan ke-2).

Jika Anda ingin membulatkan bagian pecahan, saya sarankan membangun "%.9f"secara dinamis dengan jumlah tempat desimal yang diinginkan.

mato
sumber