2011-02-01 47 views
34

Tôi đã nhìn thấy một số biến thể về câu hỏi này nhưng tôi tin rằng câu trả lời này chưa được trả lời.PHP có ngày bắt đầu và ngày kết thúc của tuần theo số tuần

tôi cần để có được ngày bắt đầu và kết thúc ngày một tuần, được lựa chọn bởi năm và số tuần (không phải là một ngày)

dụ:

đầu vào:

getStartAndEndDate($week, $year); 

đầu ra:

$return[0] = $firstDay; 
$return[1] = $lastDay; 

Giá trị trả lại sẽ giống như một mảng trong đó mục nhập đầu tiên là ngày bắt đầu tuần và ngày thứ hai là ngày kết thúc.

TỰ CHỌN THÊM: trong khi chúng tôi đang ở đó, định dạng ngày cần phải được Y-n-j (định dạng ngày tháng bình thường, không có số không hàng đầu

Tôi đã cố gắng chỉnh sửa các chức năng hiện có mà gần như đã làm những gì tôi muốn nhưng tôi không có may mắn. cho đến nay.

Xin hãy giúp tôi ra ngoài, cảm ơn trước.

+1

StackOverflow không phải là về việc nhận được nhiều biến thể nhất có thể. Nếu bạn có thể tìm ra giải pháp từ các biến thể, đừng hỏi câu hỏi. Nếu bạn không thể hình dung ra nó, bạn được khuyến khích để giải thích cách xa bạn đã nhận được từ các biến thể. – Gordon

Trả lời

32
function getStartAndEndDate($week, $year) 
{ 

    $time = strtotime("1 January $year", time()); 
    $day = date('w', $time); 
    $time += ((7*$week)+1-$day)*24*3600; 
    $return[0] = date('Y-n-j', $time); 
    $time += 6*24*3600; 
    $return[1] = date('Y-n-j', $time); 
    return $return; 
} 
+8

Tính toán không chính xác. Tuần 1 năm 2014 là từ '2013-12-30' đến '2014-01-05', không phải từ '2014-01-06' đến '2014-01-12' đây thực sự là tuần 2. –

+2

thực sự điều này sẽ diễn ra một tuần nghỉ. –

+0

Sai, vì tính năng Tiết kiệm ánh sáng ban ngày đã bị bỏ qua. –

0

các bạn đã thử PHP relative dates? Nó có thể làm việc.

+0

thì bạn sẽ sử dụng lệnh nào? 'strtotime ('ngày đầu tiên của tuần 12')'? – Pieter888

+0

@ Pieter888 này không hoạt động và không phải là năm dựa –

+1

Có lẽ bạn có thể chuỗi chúng. Hãy thử '+ n tuần' để có được tuần. Sau đó, nhìn vào các tài liệu một lần nữa. Ngoài ra còn có một cách để có được một ngày trong tuần. – Mikel

1

Đầu tiên chúng ta cần một ngày từ tuần đó nên bằng cách biết số tuần và Knô cánh mà một tuần có bảy ngày chúng tôi sẽ làm như vậy các

cách này pickAday sẽ là một ngày trong tuần mong muốn của chúng tôi.

Bây giờ, vì chúng tôi biết năm chúng ta có thể kiểm tra ngày đó là ngày nào. mọi thứ rất đơn giản nếu chúng ta chỉ cần ngày mới hơn dấu thời gian Chúng tôi sẽ nhận được dấu thời gian unix cho ngày đầu tiên của năm và thêm vào đó 24*3600*$pickADay và tất cả đều đơn giản từ đây vì chúng tôi có dấu thời gian, chúng ta có thể biết ngày nào của tuần nó là và tính toán đầu và đuôi của tuần đó cho phù hợp.

Nếu chúng ta muốn tìm hiểu điều tương tự, hãy nói tuần thứ 12 của năm 1848, chúng ta phải sử dụng cách tiếp cận khác vì chúng ta không thể nhận được dấu thời gian. Biết rằng mỗi năm một ngày tiến 1 ý nghĩa trong tuần (ngày 1 tháng 11 năm ngoái là vào ngày chủ nhật, năm nay là vào thứ hai, ngoại lệ cho những năm nhuận khi nó tiến lên 2 ngày tôi tin, bạn có thể kiểm tra điều đó). Tôi sẽ làm gì nếu năm đó lớn hơn năm 1970 hơn là tạo sự khác biệt giữa năm và năm cần thiết để biết có bao nhiêu năm ở đó, tính toán ngày trong tuần khi pickADay của tôi là một phần của năm 1970, chuyển nó trở lại một ngày trong tuần cho mỗi . $shiftTimes = ($yearDifference + $numberOfLeapYears)%7, trong sự khác biệt. thay đổi ngày backwords $ shiftTimes, sau đó bạn sẽ biết những gì ngày trong tuần là ngày đó những năm trước, sau đó tìm thấy các đầu tuần và weektail. Điều tương tự cũng có thể được sử dụng cho tương lai nếu nó có vẻ đơn giản hơn. Hãy thử nó nếu nó hoạt động và cho tôi biết nếu nó không.

+0

Cảm ơn, nó chắc chắn xóa một số nhầm lẫn của tôi về những ngày này. Câu trả lời được đưa ra bởi Roham Rafii khẳng định lý thuyết của bạn và tôi cảm ơn cả hai rất nhiều! – Pieter888

0

Thậm chí nếu bạn không muốn sử dụng một ngày cụ thể, bạn không thể thoát khỏi nó. Bạn có thể tính toán một tuần dựa trên ngày CHỈ.

bước:

  1. có được ngày đầu tiên của năm
  2. quyết định khi nào bắt đầu tuần đầu tiên (có một số quy tắc bao gồm Thứ Năm đầu tiên nếu tôi nhớ.
  3. thêm một số tuần (tham số đầu tiên của bạn). Zend_Date có hàm add(), nơi bạn có thể thêm tuần ví dụ. Điều này sẽ cung cấp cho bạn ngày đầu tiên của tuần.
  4. bù đắp và nhận ngày cuối cùng.

Tôi khuyên bạn nên làm việc với một số ngày nhất quán như Zend_Date hoặc Pear Date.

9

giải pháp Hơi gọn gàng, sử dụng "[năm] W [tuần] [ngày]" định dạng strtotime:

function getStartAndEndDate($week, $year) { 
    // Adding leading zeros for weeks 1 - 9. 
    $date_string = $year . 'W' . sprintf('%02d', $week); 
    $return[0] = date('Y-n-j', strtotime($date_string)); 
    $return[1] = date('Y-n-j', strtotime($date_string . '7')); 
    return $return; 
} 
-1
function getStartAndEndDate($week, $year) 
    { 
     $week_start = new DateTime(); 
     $week_start->setISODate($year,$week); 
     $return[0] = $week_start->format('d-M-Y'); 
     $time = strtotime($return[0], time()); 
     $time += 6*24*3600; 
     $return[1] = date('d-M-Y', $time); 
     return $return; 
    } 
+0

giải thích những gì bạn đã làm một chút tương lai hơn là chỉ cần đăng mã số –

118

Sử dụng DateTime lớp:

function getStartAndEndDate($week, $year) { 
    $dto = new DateTime(); 
    $dto->setISODate($year, $week); 
    $ret['week_start'] = $dto->format('Y-m-d'); 
    $dto->modify('+6 days'); 
    $ret['week_end'] = $dto->format('Y-m-d'); 
    return $ret; 
} 

$week_array = getStartAndEndDate(52,2013); 
print_r($week_array); 

Returns :

Array 
(
    [week_start] => 2013-12-23 
    [week_end] => 2013-12-29 
) 

Giải thích:

  • Tạo một đối tượng DateTime mới mà mặc định là bây giờ()
  • Gọi setISODate thay đổi đối tượng cho đến ngày đầu tiên của $ tuần $ năm thay vì bây giờ()
  • ngày Định dạng như ' Ymd 'và đặt $ ret [' week_start ']
  • Sửa đổi đối tượng bằng cách thêm 6 ngày, sẽ kết thúc $ week
  • Ngày định dạng là' Ymd 'và đặt $ ret [' week_end ']

Một phiên bản ngắn hơn (chỉ hoạt động trong> = PHP5.3):

function getStartAndEndDate($week, $year) { 
    $dto = new DateTime(); 
    $ret['week_start'] = $dto->setISODate($year, $week)->format('Y-m-d'); 
    $ret['week_end'] = $dto->modify('+6 days')->format('Y-m-d'); 
    return $ret; 
} 

thể được rút ngắn với class member access on instantiation trong> = php5.4.

+8

Đây phải là câu trả lời được chấp nhận, thực hiện. Nó nhanh hơn, sạch hơn và sử dụng lớp DateTime() bên trong. – BizLab

+0

Để lưu ý, nếu bạn quyết định trả lại đối tượng DateTime bạn cần phải thêm bản sao trước khi làm như vậy hoặc bạn sẽ luôn nhận được ngày sửa đổi. '$ ret ['week_start'] = sao chép $ dto;' – Styledev

+1

Bởi vì đôi khi chúng ta cần điều này cho mysql, chúng ta cần thời gian là tốt. Vì vậy, tôi sửa đổi điều này một chút. Đặt lại thời gian, thêm 7 ngày và giảm 1 giây. $ dto = new DateTime(); \t $ dto-> setISODate ($ year, $ week); \t $ dto-> setTime (0,0,0); \t $ ret ['week_start'] = $ dto-> định dạng ('Y-m-d H: i: s'); \t $ dto-> modify ('+ 7 days'); \t $ dto-> modify ('- 1 sec'); \t $ ret ['week_end'] = $ dto-> định dạng ('Y-m-d H: i: s'); –

1

Tính toán của Roham Rafii là sai. Dưới đây là một giải pháp ngắn hạn:

// week number to timestamp (first day of week number) 
function wn2ts($week, $year) { 
    return strtotime(sprintf('%dW%02d', $year, $week)); 
} 

nếu bạn muốn ngày cuối cùng của số tuần, bạn có thể thêm lên 6 * 24 * 3600

1

Đây là một câu hỏi cũ, nhưng nhiều người trong các câu trả lời được đăng trên đây xuất hiện không chính xác . tôi đã đưa ra giải pháp của riêng tôi:

function getStartAndEndDate($week, $year){ 
    $dates[0] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT))); 
    $dates[1] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT).' +6 days')); 
    return $dates; 
} 
0

con đường ngắn nhất để làm điều đó:

function week_date($week, $year){ 
    $date = new DateTime(); 
    return "first day of the week is ".$date->setISODate($year, $week, "1")->format('Y-m-d') 
    ."and last day of the week is ".$date->setISODate($year, $week, "7")->format('Y-m-d'); 
} 
echo week_date(12,2014); 
7

Chúng ta có thể đạt được điều này một cách dễ dàng mà không cần tính toán thêm ngoài những luận gắn liền với lớp DateTime.

function getStartAndEndDate($year, $week) 
{ 
    return [ 
     (new DateTime())->setISODate($year, $week)->format('Y-m-d'), //start date 
     (new DateTime())->setISODate($year, $week, 7)->format('Y-m-d') //end date 
    ]; 
} 

Chức năng setISODate() mất ba đối số: $year, $week, và $day tương ứng, nơi $day mặc định là 1 - ngày đầu tiên của tuần. Do đó, chúng tôi vượt qua 7 để có được ngày chính xác của ngày thứ 7 của $week.

+0

Giải pháp tốt nhất, tốt đẹp! – nights

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