2012-04-17 40 views
52

Tôi có một dấu thời gian Unix như thế này:Với dấu thời gian Unix, cách bắt đầu và kết thúc ngày hôm đó?

$timestamp=1330581600 

Làm thế nào để có được sự khởi đầu trong ngày và kết thúc trong ngày hôm nay timestamp đó?

e.g. 
$beginOfDay = Start of Timestamp's Day 
$endOfDay = End of Timestamp's Day 

Tôi cố gắng này:

$endOfDay = $timestamp + (60 * 60 * 23); 

Nhưng tôi không nghĩ rằng nó sẽ làm việc vì các dấu thời gian tự nó không phải là sự khởi đầu chính xác nhất trong ngày.

+0

Nếu GMT, có thể là: $ boundary = floor/ceil ($ timestamp/(60 * 60 * 24)) * (60 * 60 * 24); – hakre

+0

Nếu đầu ra mong đợi của bạn là dấu thời gian dưới dạng số nguyên thì có một lớp lót đơn giản: $ beginOfDay = mktime (0, 0, 0, ngày ('n'), ngày ('j') - 1); $ endOfDay = mktime (0, 0, 0, ngày ('n'), ngày ('j')); – jarederaj

Trả lời

117

strtotime có thể được sử dụng để nhanh chóng chặt giờ/phút/giây

$beginOfDay = strtotime("midnight", $timestamp); 
$endOfDay = strtotime("tomorrow", $beginOfDay) - 1; 

DateTime cũng có thể được sử dụng, mặc dù đòi hỏi một vài bước mở rộng để có được từ một dấu thời gian dài

$dtNow = new DateTime(); 
// Set a non-default timezone if needed 
$dtNow->setTimezone(new DateTimeZone('Pacific/Chatham')); 
$dtNow->setTimestamp($timestamp); 

$beginOfDay = clone $dtNow; 

// Go to midnight. ->modify('midnight') does not do this for some reason 
$beginOfDay->modify('today'); 

$endOfDay = clone $beginOfDay; 
$endOfDay->modify('tomorrow'); 
// adjust from the next day to the end of the day, per original question 
$endOfDay->modify('1 second ago'); 

var_dump(
    array(
     'time ' => $dtNow->format('Y-m-d H:i:s e'), 
     'start' => $beginOfDay->format('Y-m-d H:i:s e'), 
     'end ' => $endOfDay->format('Y-m-d H:i:s e'), 
    ) 
); 
+1

Cảm ơn rất nhiều! – Talon

+2

Tại sao trừ đi 1 giây ở cuối? –

+1

Tôi đã đọc câu hỏi ban đầu như nhận được giây cuối cùng của ngày, thay vì sau đó là giây đầu tiên của ngày hôm sau. 'ngày mai' sẽ đưa ra giây đầu tiên trong ngày, vì vậy '-1' để giành vị trí thứ hai trước ngày thứ hai đầu tiên trong ngày. – rrehbein

3

Bạn có thể chuyển đổi thời gian thành dữ liệu hiện tại và sau đó sử dụng hàm strtotime để tìm ngày bắt đầu và chỉ cần thêm 24 giờ để tìm kết thúc trong ngày.

Bạn cũng có thể sử dụng toán tử còn lại (%) để tìm ngày gần nhất. Ví dụ:

$start_of_day = time() - 86400 + (time() % 86400); 
$end_of_day = $start_of_day + 86400; 
+4

Không phải tất cả các ngày đều dài 86400 giây, vì vậy điều này sẽ không hoạt động như bạn mong đợi – Cal

+0

@Có oh yeah, tôi không nghĩ về điều đó – James

+0

thanx thanx rất nhiều .. –

5

Bạn có thể sử dụng một sự kết hợp của date()mktime():

list($y,$m,$d) = explode('-', date('Y-m-d', $ts)); 
$start = mktime(0,0,0,$m,$d,$y); 
$end = mktime(0,0,0,$m,$d+1,$y); 

mktime() là đủ thông minh để quấn tháng/năm khi đưa ra một ngày ngoài tháng quy định (Tháng Một 32 sẽ là tháng hai 1st, vv)

0

Đối với bất cứ ai có câu hỏi này trong tương lai:

Bất kỳ mã ngày

<?php 
$date = "2015-04-12 09:20:00"; 

$midnight = strtotime("midnight", strtotime($date)); 
$now = strtotime($date); 

$diff = $now - $midnight; 
echo $diff; 
?> 

Mã ngày hiện tại

<?php 
$midnight = strtotime("midnight"); 
$now = date('U'); 

$diff = $now - $midnight; 
echo $diff; 
?> 
5

Just DateTime

$beginOfDay = DateTime::createFromFormat('Y-m-d H:i:s', (new DateTime())->setTimestamp($timestamp)->format('Y-m-d 00:00:00'))->getTimestamp(); 
$endOfDay = DateTime::createFromFormat('Y-m-d H:i:s', (new DateTime())->setTimestamp($timestamp)->format('Y-m-d 23:59:59'))->getTimestamp(); 

Đối tượng DateTime đầu tiên được tạo và dấu thời gian được đặt thành dấu thời gian mong muốn. Sau đó, đối tượng được định dạng dưới dạng chuỗi thiết lập giờ/phút/giây thành đầu hoặc cuối ngày. Cuối cùng, một đối tượng DateTime mới được tạo ra từ chuỗi này và dấu thời gian được lấy ra.

Readable

$dateTimeObject = new DateTime(); 
$dateTimeObject->setTimestamp($timestamp); 
$beginOfDayString = $dateTimeObject->format('Y-m-d 00:00:00'); 
$beginOfDayObject = DateTime::createFromFormat('Y-m-d H:i:s', $beginOfDayString); 
$beginOfDay = $beginOfDayObject->getTimestamp(); 

Chúng tôi có thể nhận được vào cuối ngày một cách thay thế bằng phiên bản này còn:

$endOfDayObject = clone $beginOfDayOject(); // Cloning because add() and sub() modify the object 
$endOfDayObject->add(new DateInterval('P1D'))->sub(new DateInterval('PT1S')); 
$endOfDay = $endOfDayOject->getTimestamp(); 

múi giờ

Các múi giờ có thể được thiết lập như cũng bằng cách thêm một chỉ báo dấu thời gian theo định dạng như O và chỉ định dấu thời gian sau khi tạo đối tượng DateTime:

$beginOfDay = DateTime::createFromFormat('Y-m-d H:i:s O', (new DateTime())->setTimezone(new DateTimeZone('America/Los_Angeles'))->setTimestamp($timestamp)->format('Y-m-d 00:00:00 O'))->getTimestamp(); 

Tính linh hoạt của DateTime

Chúng tôi cũng có thể nhận được các thông tin khác như đầu/cuối tháng hoặc đầu/cuối giờ bằng cách thay đổi định dạng thứ hai quy định. Trong tháng: 'Y-m-01 00:00:00''Y-m-t 23:59:59'. Đối với giờ: 'Y-m-d H:00:00''Y-m-d H:59:59'

Sử dụng các định dạng khác nhau kết hợp với các đối tượng add()/sub() và DateInterval, chúng ta có thể bắt đầu hoặc kết thúc bất kỳ khoảng thời gian nào. đúng.

Liên kết liên quan

Từ các tài liệu PHP:

+0

Những gì bạn đã tạo là gọn gàng và dễ đọc. Thật không may nó sẽ thất bại trên giây nhuận. Một số ngày kết thúc lúc 23:59:58, trong khi những ngày khác kết thúc vào 23:59:60. Đặc biệt điều này sẽ gây ra vấn đề nếu cố gắng tạo một ngày cho một datetime không tồn tại, chẳng hạn như 23:59:59 vào một ngày mà về mặt lý thuyết có thể kết thúc một giây trước đó. Câu trả lời được chấp nhận, sử dụng phương pháp sửa đổi \ DateTime :: của PHP, sẽ tránh điều này. PHP được xây dựng trong lib là đủ thông minh để giải thích cho tất cả những điều kỳ quặc bao quanh ngày tháng và thời gian bao gồm cả giây nhảy vọt. – Elimn

+0

@Elimm, tôi đã không biết rằng một số ngày kết thúc một giây trước hoặc muộn hơn vì ngày nhuận. Tôi nghĩ rằng bước nhảy vọt chỉ thêm một ngày vào những năm nhuận và không có gì khác bị ảnh hưởng. Bạn có thể đưa ra một số ví dụ trong mã về cách điều này không thành công (hoặc bạn có thể chia sẻ một ngày có thêm một hoặc một vài giây) không? Ngoài ra, có một bài viết bạn có thể chia sẻ mà nói thêm về điều này? Cảm ơn bạn đã chỉ ra 'sửa đổi'. Tôi không biết về điều đó trước đây. –

+0

Để chắc chắn. Chúng được gọi là bước nhảy vọt _seconds_ không nhảy vọt _days_ hoặc _years_. Chúng chiếm luân chuyển của trái đất không phải là một tốc độ không đổi. Tôi tin rằng ngày 30 tháng 6 năm 2016 là bước nhảy vọt cuối cùng của chúng tôi. [Trang Wikipedia] (https://en.wikipedia.org/wiki/Leap_second) đi sâu vào các chi tiết nghiêm túc. – Elimn

0
$start_of_day = floor (time()/86400) * 86400; 
$end_of_day = ceil (time()/86400) * 86400; 

Nếu bạn cần cả hai giá trị trong cùng một tập lệnh. Nó nhanh hơn +/- 86400 giây đến một trong các biến hơn là cháy cả sàn và ceil. Ví dụ:

$start_of_day = floor (time()/86400) * 86400; 
$end_of_day = $start_of_day + 86400; 
1

Hôm nay Ngày bắt đầu dấu thời gian. Đơn giản

$stamp = mktime(0, 0, 0); 
echo date('m-d-Y H:i:s',$stamp); 
Các vấn đề liên quan