แปลง timedelta เป็นวันชั่วโมงและนาที


243

ฉันมี timedelta ฉันต้องการวันเวลาและนาทีจากนั้น - ทั้งในฐานะ tuple หรือพจนานุกรม ... ฉันไม่รำคาญ

ฉันต้องทำสิ่งนี้หลายสิบครั้งในหลาย ๆ ภาษาในช่วงหลายปีที่ผ่านมา แต่ Python มักจะมีคำตอบง่ายๆทุกอย่างดังนั้นฉันจึงคิดว่าฉันจะถามที่นี่ก่อนที่จะเลิกคณิตศาสตร์ที่เรียบง่าย

Mr Fooz ยกประเด็นที่ดี

ฉันกำลังจัดการกับ "รายชื่อ" (เล็กน้อยเช่นรายชื่ออีเบย์) ที่แต่ละคนมีระยะเวลา ฉันพยายามหาเวลาที่เหลือโดยการทำwhen_added + duration - now

ฉันพูดถูกแล้วว่าจะไม่นับรวม DST? หากไม่เป็นเช่นนั้นวิธีที่ง่ายที่สุดในการเพิ่ม / ลบชั่วโมงคืออะไร


ถ้าเป็นเพียงเพื่อให้เป็นสตริงในรูปแบบ HH: mm: ss ให้พูดว่า"0:19:37"จากtimedeltaวัตถุ"datetime.timedelta (วินาที = 1177)" : เพียงแค่ใช้ str ()
Peter Mortensen

คำตอบ:


344

หากคุณมีdatetime.timedeltaค่าtd, td.daysแล้วจะช่วยให้คุณ "วัน" คุณต้องการ timedeltaค่าจะเก็บเศษส่วนของวันเป็นวินาที (ไม่ใช่ชั่วโมงหรือนาทีโดยตรง) ดังนั้นคุณจะต้องดำเนินการ "คณิตศาสตร์ง่าย ๆ ที่น่ารำคาญ" เช่น:

def days_hours_minutes(td):
    return td.days, td.seconds//3600, (td.seconds//60)%60

1
เก็บไว้ในใจว่าถ้าtdเป็นลบคือ-1 // 3600 -1
jcrs

4
ทำไม // แทน /
โมฮัมเหม็ด Shareef C

10
//ใช้แทน/การรับจำนวนเต็มไม่ใช่การลอย //เป็นผู้ประกอบการส่วนชั้น: "ส่วนที่ว่าผลลงในจำนวนทั้งหมดปรับไปทางซ้ายในสายหมายเลข" ให้ดูที่นี่
Eerik Sven Puudist

1
@EerikSvenPuudist ตามที่อธิบายไว้jcrsแล้ว-1//3600คือ-1ทำไมจึงไม่ใช้int(td.seconds/3600)แทนการเปลี่ยน-1วินาทีเป็น0ชั่วโมงแทนที่จะเป็น1ชั่วโมงย้อนหลัง
simpleuser

วิธีการเกี่ยวกับการเพิ่มวินาทีที่เหลือเช่นกัน? days, hours, minutes = x.days, x.seconds // 3600, x.seconds %3600//60และจากนั้น seconds = x.seconds - hours*3600 - minutes*60
ฟาเอล

73

ขนาดกะทัดรัดกว่านี้เล็กน้อยคุณจะได้รับชั่วโมงนาทีและวินาทีในสองบรรทัด

days = td.days
hours, remainder = divmod(td.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# If you want to take into account fractions of a second
seconds += td.microseconds / 1e6

7
มันไม่ถูกต้องหากtd.daysไม่ใช่ศูนย์ hours += td.days*24คุณจำเป็นต้อง หากคุณต้องการคำนึงถึงเศษส่วนของวินาที (OP ไม่ได้); seconds += td.microseconds / 1e6สามารถใช้
jfs

30
days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

สำหรับ DST ฉันคิดว่าสิ่งที่ดีที่สุดคือการแปลงdatetimeวัตถุทั้งสองเป็นวินาที วิธีนี้ระบบจะคำนวณ DST ให้คุณ

>>> m13 = datetime(2010, 3, 13, 8, 0, 0)  # 2010 March 13 8:00 AM
>>> m14 = datetime(2010, 3, 14, 8, 0, 0)  # DST starts on this day, in my time zone
>>> mktime(m14.timetuple()) - mktime(m13.timetuple())     # difference in seconds
82800.0
>>> _/3600                                                # convert to hours
23.0

1
mktime()อาจล้มเหลวหากเขตเวลาท้องถิ่นอาจมีออฟเซ็ต utc ที่แตกต่างกันในเวลาที่ต่างกัน (หลายอย่าง) - คุณสามารถใช้pytzโมดูลเพื่อเข้าถึงฐานข้อมูล tz ในรูปแบบ deteministic แบบพกพา นอกจากนี้ตามเวลาท้องถิ่นอาจจะไม่ชัดเจน (50% โอกาสของข้อผิดพลาด) - ท่านต้องการข้อมูลเพิ่มเติมบางอย่างจะกระจ่างเช่นมักจะ (ไม่เสมอไป) วันที่ในแฟ้มบันทึกเป็นน่าเบื่อ ดูฉันจะลบวันจากวันไพ ธ อนได้อย่างไร ที่อาจต้องจัดการกับปัญหาที่คล้ายกัน
jfs

7

ฉันไม่เข้าใจ

days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

แล้วเรื่องนี้ล่ะ

days, hours, minutes = td.days, td.seconds // 3600, td.seconds % 3600 / 60.0

คุณได้รับนาทีและวินาทีของนาทีเป็นลอย


0

ฉันใช้สิ่งต่อไปนี้:

delta = timedelta()
totalMinute, second = divmod(delta.seconds, 60)
hour, minute = divmod(totalMinute, 60)
print(f"{hour}h{minute:02}m{second:02}s")

-3

timedeltas มีdaysและsecondsคุณลักษณะ .. คุณสามารถแปลงด้วยตนเองได้อย่างง่ายดาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.