2013-04-08 40 views
5

Tôi muốn tính toán tất cả các ngày Chủ Nhật trong hai ngày nhất định. Tôi đã thử mã sau đây. Nó hoạt động tốt nếu ngày ít hơn nhưng nếu tôi nhập nhiều ngày hơn. Nó tiếp tục xử lý và thời gian thực hiện tối đa vượt quá tôi đã thay đổi thời gian nhưng nó thậm chí giữ chế biến ngay cả thời gian thực hiện là 200 giây.tính ngày chủ nhật giữa hai ngày

code đang

<?php 
$one="2013-01-01"; 
$two="2013-02-30"; 

$no=0; 
for($i=$one;$i<=$two;$i++) 
{ 

    $day=date("N",strtotime($i)); 
    if($day==7) 
    { 
    $no++; 
    } 
} 
echo $no; 

?> 

xin vui lòng giúp đỡ.

+0

bạn có thể sử dụng một vòng lặp for trên một chuỗi ngày như thế? – andrewsi

+0

Bạn không thể tăng chuỗi như vậy. Hãy xem cách người khác làm điều đó: http://stackoverflow.com/search?q=php+number+of+sundays –

+0

Đây có phải là một [vấn đề về dự án euler (19)] (http://projecteuler.net/problem=19)? – HamZa

Trả lời

25

câu trả lời John Conde là đúng, nhưng đây là một giải pháp hiệu quả hơn và mathy:

$start = new DateTime('2013-01-06'); 
$end = new DateTime('2013-01-20'); 
$days = $start->diff($end, true)->days; 

$sundays = intval($days/7) + ($start->format('N') + $days % 7 >= 7); 

echo $sundays; 

Hãy để tôi phá vỡ nó xuống cho bạn.

$start = new DateTime('2013-01-06'); 
$end = new DateTime('2013-01-20'); 

Trước tiên, hãy tạo một số đối tượng PHP được xây dựng sẵn có nghĩa là chính xác loại sự cố này.

$days = $start->diff($end, true)->days; 

Tiếp theo, sử dụng DateTime::diff để tìm sự khác biệt từ $start để $end (đi qua true ở đây là tham số thứ hai đảm bảo rằng giá trị này luôn luôn là tích cực), và nhận được số ngày giữa chúng.

$sundays = intval($days/7) + ($start->format('N') + $days % 7 >= 7); 

Đây là một ứng dụng lớn nhưng thực sự không phức tạp lắm. Đầu tiên, chúng tôi biết có một Chủ Nhật cho mỗi tuần, vì vậy chúng tôi có ít nhất $days/7 Chủ Nhật để bắt đầu, được làm tròn xuống số int gần nhất với intval.

Ngày đầu đó, có thể có một ngày chủ nhật trong một khoảng thời gian ít hơn một tuần; ví dụ: Thứ Sáu đến Thứ Hai của tuần tiếp theo có 4 ngày; một trong số họ là chủ nhật. Vì vậy, tùy thuộc vào thời điểm chúng ta bắt đầu và kết thúc, có thể có khác. Đây là dễ dàng để giải thích cho:

  • $start->format('N') (thấy DateTime::format) cho chúng ta ISO-8601 ngày trong tuần cho ngày bắt đầu, đó là một con số 1-7 (1 là Thứ Hai, 7 là chủ nhật) .
  • $days % 7 cung cấp cho chúng tôi số ngày còn lại không phân chia đồng đều thành các tuần.

Nếu ngày bắt đầu của chúng tôi và số ngày còn lại thêm tối đa 7 hoặc nhiều hơn, thì chúng tôi đã đến Chủ nhật. Biết rằng, chúng tôi chỉ cần thêm biểu thức đó, sẽ cung cấp cho chúng tôi 1 nếu đúng hoặc 0 nếu sai, vì chúng tôi sẽ thêm nó vào giá trị int.

Và ở đó bạn có nó! Ưu điểm của phương pháp này là nó không yêu cầu lặp lại mỗi ngày giữa thời gian đã cho và kiểm tra xem đó có phải là chủ nhật hay không, điều này sẽ giúp bạn tiết kiệm rất nhiều, và nó cũng sẽ khiến bạn trông rất thông minh. Hy vọng rằng sẽ giúp!

+2

Phần này không đúng 'Vì $ days và 7 đều là giá trị int, giá trị này sẽ luôn được làm tròn xuống int' gần nhất. Bạn phải sử dụng một hàm tròn như [floor()] (http://www.php.net/manual/en/function.floor.php) để làm tròn nó, PHP sẽ không làm điều đó cho bạn, hãy thử ví dụ '$ end = new DateTime ('2013-02-20');' và đầu ra sẽ là số thập phân. – HamZa

+2

Bạn hoàn toàn đúng, rất tiếc! Quên tôi đã nói về PHP trong một giây. –

+1

+1 cho cách tiếp cận thông minh và giải thích chi tiết. –

8
<?php 
$no = 0; 
$start = new DateTime('2013-01-01'); 
$end = new DateTime('2013-04-30'); 
$interval = DateInterval::createFromDateString('1 day'); 
$period = new DatePeriod($start, $interval, $end); 
foreach ($period as $dt) 
{ 
    if ($dt->format('N') == 7) 
    { 
     $no++; 
    } 
} 
echo $no; 

See it in action

+0

cảm ơn bạn. nó hoạt động. vì vậy nó không hoạt động vì chuỗi không được tăng lên đúng cách? –

+0

Về cơ bản có. Làm việc với các chuỗi, đặc biệt là ngày tháng, là tốt nhất còn lại để chức năng được thiết kế để làm điều đó. DateTime được thiết kế đặc biệt để làm việc với ngày tháng và như bạn có thể thấy làm cho nó dễ dàng để làm. –

+0

có. cảm ơn. –

0

Đây là giải pháp nếu bạn muốn Chủ Nhật trong một phạm vi ngày cụ thể.

function dateRange($begin, $end, $interval = null) 
{ 
    $begin = new DateTime($begin); 
    $end = new DateTime($end); 

    $end = $end->modify('+1 day'); 
    $interval = new DateInterval($interval ? $interval : 'P1D'); 

    return iterator_to_array(new DatePeriod($begin, $interval, $end)); 
} 

/* define date range */ 
$dates = dateRange('2018-03-01', '2018-03-31'); 

/* define weekdays */ 
$weekends = array_filter($dates, function ($date) { 
    $day = $date->format("N"); 
    return $day === '6' || $day === '7'; 
}); 

/* weekdays output */ 
foreach ($weekends as $date) { 
    echo $date->format("D Y-m-d") . "</br>"; 
} 

/* define sundays */ 
$sundays = array_filter($dates, function ($date) { 
    return $date->format("N") === '7'; 
}); 

/* sundays output */ 
foreach ($sundays as $date) { 
echo $date->format("D Y-m-d") . "</br>"; 
} 

/* define mondays */ 
$mondays = array_filter($dates, function ($date) { 
return $date->format("N") === '1'; 
}); 

/* mondays output */ 
foreach ($mondays as $date) { 
echo $date->format("D Y-m-d") . "</br>"; 
} 

Chỉ cần thay đổi số cho bất kỳ ngày bạn muốn trong đầu ra của bạn:

Monday = 1 
Tuesday = 2 
Wednesday = 3 
Thursday = 4 
Friday = 5 
Saturday = 6 
Sunday = 7 
Các vấn đề liên quan