2011-11-26 106 views
9

如何處理PHP/MySQL中的時間和午夜後?處理時間和午夜後

使用INT存儲分鐘或使用TIME類型字段?

考慮下面的SQL查詢:

SELECT * FROM opening_hours 
     WHERE week_day = WEEKDAY(NOW()) + 1 
       AND open_hour =< date_format(now(),'%H:%i') 
       AND close_hour >= date_format(now(),'%H:%i') 

open_hour/close_hour字段TIME類型字段。

假設open_time是「18:00」,close_time是「02:00」,當前時間是「22:41」。我們有一個關於close_time的單獨數據庫記錄(因爲它在午夜之後),但是我們永遠不會在結果中得到它,因爲close_time「02:00」不會比當前時間「22:41」更大。

此外,如果當前時間爲「01:00」,我們將獲取NEXT日值,因爲週日不匹配。

那麼解決方案是什麼?

您寧願將這些值存儲在INT(分鐘)中,以便PHP能夠直接處理這些值,而無需任何轉換?

例如...

當前時間:

// w = Day of the week, H = 24-hour format, i = Minutes 
$timearr = explode(':',date("w:H:i")); 
$currenttime = ($timearr[0]) * 1440 + $timearr[1] * 60 + $timearr[2] 

在數據庫中,存儲的打開/關閉時間以分鐘爲單位的值。現在假設當前時間是「Sun,01:00」(一週中的第一天),執行上述覆蓋率,則該值爲60; (星期六)的最後一天的開啓/關閉時間被設置爲DB爲9660和10200(星期六,26:00)的「17:00」和「02:00」(實際上是星期天) 。在這種情況下,上述查詢將找不到我們需要的記錄(星期六,17:00,02:00),因爲我們可能沒有小於「02:00」(120)的open_time。爲了解決這個問題,我們將「Sun,01:00」轉換爲「Sat,25:00」,在$ currenttime中添加7 * 1440(整週),這將導致10140.然後DB查詢如下:

SELECT open_time,clos_time FROM open_hours 
    WHERE (open_time <= $currenttime 
     AND close_time >= $currenttime) 
     OR (open_time <= $currenttime +10080 
     AND close_time >= $currenttime + 10080); 

或者什麼是替代和整潔的解決方案?

+0

也許存儲一個日期和時間?午夜後成爲明天的時間。也使用DATETIME格式,而不是INT或其他 –

+0

否我不能使用DATETIME,因爲我不打算使用Date。每天開店,我不想添加全年的日期! –

+0

http://stackoverflow.com/questions/8225684/how-to-find-out-if-store-open-or-close-dealing-with-hours –

回答

1

存儲分鐘(int(4)無符號)是要走的路。
然而,而不是存儲工作日+ opening_hour,關閉小時(膠印),
你應該保存自週一上午12點分: -

Monday 18:00 = (1 - 1)*60 * 18 = 1080 
Tuesday 02:00 = (2 - 1)*60 * 24 + (2 * 60) = 1560 
... 
// please take note shop could have different operating hour for each day 

所以,當前時間是週二凌晨1:30,這就是: -

// mysql expression 
$expr = (weekday(current_timestamp)+1) * 1440 + (hour(current_timestamp)*60) + minute(current_timestamp) 

的SQL: -

select ... 
from opening_hours 
where 
open_time >= $expr and 
close_time <= $expr; 
+0

我不明白這個部分:'(1 - 1)'和'(2 - 1)'?它是什麼? –

+0

1 =星期一從週一開始,星期一= 0,星期二= 1 ..星期日= 7(這意味着星期一開始星期一) – ajreal

+0

如果你問我,似乎是一個額外的不必要的複雜層。我會在24小時內將時間存儲爲字符串,然後再執行此操作(例如0800,1200,2140等)。比較仍然有效,您可以輕鬆查看數字並瞭解發生了什麼。 – Zoidberg

1
SELECT open_time,close_time FROM open_hours 
    WHERE 
     (open_time <= close_time AND 
     open_time <= $currenttime AND 
     close_time >= $currenttime) 
     OR 
     (open_time >= close_time AND 
     ($currenttime <= close_time OR 
     $currenttime >= open_time)) 

所以我在做什麼這裏是如果OPEN_TIME比CLOSE_TIME更大,那麼它必須跨越午夜,在這種情況下,我檢查,以確保當前定時器比開放的時間比關閉時間,所以它更大,或更小確保我們的時間跨度

開放時間------ -----午夜關閉時間

下跌。如果打開時間小於關閉時間,那麼我們就知道午夜不落在之間。因此,我們可以照常檢查。

+0

阿哈,所以你更喜歡將這些值存儲在INT(分鐘)在這個情況下? –

+0

這是你想要的。我知道日期在這種情況下是不相關的,所以我認爲日期時間不會成爲現實。我認爲在MySql http://dev.mysql.com/doc/refman/5.0/en/time.html中有一個時間類型,這將是理想的。 – Zoidberg

0

我不知道你有什麼要做的,但我們在我的選擇中,unix時間戳一直是正確的答案。它更容易計算,並且無論時區如何,它總是正確的。

也許你應該看看那個

+0

時間戳記仍然存儲日期信息,在這種情況下這不是必需的,因爲關閉和打開時間將每天重新發生。 – Zoidberg

+0

是的,但你可以提取適當的時間:回聲日期(「g:我a」,$時間戳); –