2012-07-12 43 views
5

Tôi có một danh sách các chuỗi như sau:Python: Cách hiệu quả để chuyển đổi giờ mơ hồ thành đối tượng thời gian?

4:00-5:00PM 
11:00-2:00PM 
12:00-1:00PM 
11:00-1:00AM 

và tôi đang cố gắng để tìm một cách hiệu quả để tạo ra hai đối tượng thời gian (Tôi cho rằng đây là cách duy nhất để theo dõi một loạt các thời gian, mà sau này tôi sẽ kết hợp với một đối tượng ngày tháng). Rõ ràng cho con người những gì chúng ta có nghĩa là chúng ta nói 11: 00-1: 00:00, nhưng tự hỏi một cách hiệu quả để chuyển đổi này để những gì:

datetime.time(23, 0) 
datetime.time(1, 0) 

cách tiếp cận hiện tại của tôi là để dành thời gian đầu tiên, và tạo ra một PM và phiên bản AM, hãy dùng timedelta với thời gian kết thúc (được chỉ định), và lấy ngắn hơn hai sự khác biệt để là đúng.

+0

Giúp bạn dễ dàng hơn khi bạn hiển thị cho chúng tôi (một số) mã của bạn. Ngoài ra, cách tiếp cận của bạn giải thích giá trị bên trái như cả AM và PM và chọn đồng bằng nhỏ hơn là cách tôi cũng làm như vậy. –

+0

wow đó là rất nhiều mã, bạn đang overcomplicating việc thực hiện. –

Trả lời

3

Dưới đây là triển khai đơn giản.

>>> def timeRange(timestr): 
    ...  t1, t2 = timestr.split("-") 
    ...  timeFormat = "%I:%M%p" 
    ...  t1AM = datetime.datetime.strptime(t1 + "AM", timeFormat) 
    ...  t1PM = datetime.datetime.strptime(t1 + "PM", timeFormat) 
    ...  t2 = datetime.datetime.strptime(t2, timeFormat) 
    ...  
    ...  if (t2 - t1AM).seconds < (t2-t1PM).seconds: 
    ...   return t1AM.time(), t2.time() 
    ...  else: 
    ...   return t1PM.time(), t2.time() 
    >>> timeRange("11:00-2:00PM") 
    (datetime.time(11, 0), datetime.time(14, 0)) 
    >>> timeRange("4:00-5:00PM") 
    (datetime.time(16, 0), datetime.time(17, 0)) 
    >>> timeRange("11:00-1:00AM") 
    (datetime.time(23, 0), datetime.time(1, 0)) 
    >>> timeRange("11:00-2:00PM") 
    (datetime.time(11, 0), datetime.time(14, 0)) 
    >>> timeRange("12:00-1:00PM") 
    (datetime.time(12, 0), datetime.time(13, 0)) 

Trả về đối tượng time nhưng bạn có thể cuộn đối tượng đó vào ngày giờ nếu bạn cần.

+0

Bạn có thể thêm một chỉ báo khác trong bộ trả về để chỉ ra rằng lần thứ hai là vào ngày hôm sau, ví dụ nếu lần đầu tiên là PM và thứ hai là AM. Điều này có thể hữu ích khi tính toán khoảng thời gian theo yêu cầu trong OP. Nếu không thì thời gian (23, 0) -> thời gian (1, 0) sẽ là -22 giờ ... –

+0

Tuyệt vời! Cảm ơn bạn rất nhiều, tôi đã cố gắng thực hiện của riêng tôi và nó rất giống với của bạn, mặc dù bạn là tối ưu hóa hơn. – zhuyxn

2

Có hai giả định ngầm trong câu hỏi của bạn:

  • Bạn đang tìm kiếm trong thời gian ngắn nhất có thể giữa những lần
  • Lần đầu tiên là trước đó của cả hai.

Nếu các giả định này là đúng sự thật, sau đó một tối ưu hóa nhanh chóng sẽ là:

  • Nếu lần đầu tiên là lớn hơn so với thứ hai (ví dụ 11: 00-1: 12:00 hoặc 11: 00-1: 00PM) thì thời gian trước đó là chỉ báo AM/PM 'ngược lại' của giây. Nếu không, AM/PM của lần đầu tiên là như nhau.

này hoạt động ngay cả đối với khoảng thời gian lớn nhất, ví dụ 6: 00-6: 00:00 (18:00-6:00 ngắn hơn 06:00-06:00)

Một quan sát thứ hai là bạn không thể sử dụng đối tượng thời gian đơn giản vì

  • Thời gian AM-> PM diễn ra trong một ranh giới ngày (nửa đêm). Điều này có thể làm hỏng tính toán của timedelta của bạn trong tình trạng này.

Vì vậy, tôi nghĩ bạn phải sử dụng datetime hoặc kết hợp tất cả điều này trong cấu trúc nêu rõ thời gian trong đối tượng lần đầu tiên là ngày trước đó.

Hy vọng điều này sẽ giúp ích:

+0

Bạn nói đúng, nhưng bạn phải cẩn thận để không đối xử với '6:00 AM-6:00AM' có chiều dài 0. – glglgl

+0

6:00 AM-6:00AM không phù hợp với định dạng mà OP cung cấp - lần đầu tiên có không có chỉ báo AM/PM –

+0

Đúng vậy. Nhưng '6: 00-6: 00 AM' có thể có nghĩa là' 6:00 AM-6:00AM' nếu '6:00 AM-6:00AM' có chiều dài 0 và ngắn hơn' 6:00 PM-6:00AM ', trong đó có 12 giờ trong mọi trường hợp. Tuy nhiên, nếu '6:00 AM-6:00AM' có nghĩa là có 24 giờ, '6:00 PM-6:00AM' ngắn hơn và do đó là giải pháp.(Để hoàn toàn rõ ràng, một số phần của thế giới cuối cùng có thể thực hiện việc chuyển đổi các phần khác đã được thực hiện khoảng 90 năm trước và viết '18: 00-06: 00' để mọi người biết điều gì có nghĩa. SCNR) – glglgl

Các vấn đề liên quan