Nhận ngày đầu tiên trong tuần bằng PHP?


124

Với MM-dd-yyyyđịnh dạng ngày tháng , ai đó có thể giúp tôi xem ngày đầu tuần không?


4
Ý bạn là ngày đầu tiên của tuần là gì? Ý bạn là Sun, Mon? Hay ý của bạn là ngày của ngày đầu tuần?
Jeffrey Hines

2
Ngày đầu tiên của tuần không đổi: đó là Thứ Hai (hoặc có thể là Chủ Nhật). Ý của bạn là bạn muốn lấy ngày của Thứ Hai trước một ngày tùy ý nhất định?
Jon Cram

Phiên bản nào của PHP - 4 hoặc 5?
Jon Cram

ngày của chủ nhật trong tuần. php 5
Iggy Ma

Lạ thay, anh ta yêu cầu một DateTimegiải pháp và hầu hết các câu trả lời không cung cấp nó. =)
lin

Câu trả lời:


143

Đây là những gì tôi đang sử dụng ...

$day = date('w');
$week_start = date('m-d-Y', strtotime('-'.$day.' days'));
$week_end = date('m-d-Y', strtotime('+'.(6-$day).' days'));

$ day chứa một số từ 0 đến 6 đại diện cho ngày trong tuần (Chủ nhật = 0, Thứ hai = 1, v.v.).
$ week_start chứa ngày cho Chủ nhật của tuần hiện tại là mm-dd-yyyy.
$ week_end chứa ngày cho Thứ Bảy của tuần hiện tại là mm-dd-yyyy.


1
nhưng, nó có nghĩa là bắt đầu và kết thúc của 'tuần này', phải không?
Oki Erie Rinaldi

nếu số tuần được đưa ra thì sao? và tôi muốn nó trả về ngày bắt đầu và ngày kết thúc của tuần đó.
Oki Erie Rinaldi

1
@OkiErieRinaldi Có lẽ bạn nên mở một câu hỏi mới để nhận được sự quan tâm thích hợp.
JadedCore

Đừng lo, tôi đã hiểu rồi @JadedCore!
Oki Erie Rinaldi

Tôi không chắc tại sao cái kia lại cao hơn. Nó không hoạt động, nhưng cái này thì có! 3v4l.org/q6kKY
Jason

67
strtotime('this week', time());

Thay thế thời gian (). Các phương thức chủ nhật tiếp theo / thứ hai cuối cùng sẽ không hoạt động khi ngày hiện tại là chủ nhật / thứ hai.


55
$monday = strtotime('last monday', strtotime('tomorrow'));
Lewis Buckley

this weekkhông hoạt động nếu bạn luôn phải bắt đầu tuần trước đó, nhưng nhận xét của @ LewisBuckley làm được điều đó.
Smar

Đối số thứ hai time()là tùy chọn nếu bạn muốn chỉ định ngày hôm nay.
Ifnot,

không hiệu quả với tôi, tôi phải đặt cú pháp hơi khác cho YTD, MTD, WTD.
Ron

6
Câu trả lời này tạo ra kết quả không phù hợp, tùy theo phiên bản PHP sử dụng: 3v4l.org/Z3k4E @ LewisBuckley của giải pháp phù hợp cho tất cả các phiên bản: 3v4l.org/Eeh9c
Chris Baker

62

strtotimeChức năng sử dụng rất đơn giản :

echo date("Y-m-d", strtotime('monday this week')), "\n";   

echo date("Y-m-d", strtotime('sunday this week')), "\n";

Nó khác một chút giữa các phiên bản PHP :

Đầu ra cho 5.3.0 - 5.6.6, php7 @ 20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22

Đầu ra cho 4.3.5 - 5.2.17

2015-03-23
2015-03-22

Đầu ra cho 4.3.0 - 4.3.4

2015-03-30
2015-03-29

So sánh tại các trường hợp cạnh

Các mô tả tương đối như tuần này có bối cảnh riêng. Phần sau hiển thị kết quả cho thứ hai và chủ nhật của tuần này khi đó là thứ hai hoặc chủ nhật:

$date = '2015-03-16'; // monday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

$date = '2015-03-22'; // sunday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

Đồng ý rằng nó khác một chút giữa các phiên bản PHP :

Đầu ra cho 5.3.0 - 5.6.6, php7 @ 20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22
2015-03-23
2015-03-29

Đầu ra cho 4.3.5 - 5.0.5, 5.2.0 - 5.2.17

2015-03-16
2015-03-22
2015-03-23
2015-03-22

Đầu ra cho 5.1.0 - 5.1.6

2015-03-23
2015-03-22
2015-03-23
2015-03-29

Đầu ra cho 4.3.0 - 4.3.4

2015-03-23
2015-03-29
2015-03-30
2015-03-29

tại sao điều này không hoạt động cho ngày 2016-06-05, nó cho các ngày trong tuần tiếp theo.

1
Cảm ơn vì điều này, tôi vừa sửa đổi mã này để tôi có thể chuyển tham số ngày tùy chọn $ dt = $ custom_date? strtotime ($ custom_date): time (); $ monday = date ("Ymd", strtotime ('thứ hai tuần này', $ dt)); $ sunday = date ("Ymd", strtotime ('chủ nhật tuần này', $ dt));
Ron Michael

47

Giữ nó đơn giản:

<?php    
$dateTime = new \DateTime('2020-04-01');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');    
?>

Nguồn: hướng dẫn sử dụng PHP

NB: như một số người dùng đã nhận xét, giá trị $ dateTime sẽ được sửa đổi.


chỉnh sửa: lỗi chính tả hoặc một số cú pháp không xác định? \ đến từ đâu? $dateTime = new \DateTime('2012-05-14');
Sliq

2
Tôi đang làm điều này để tránh bất kỳ xung đột nào với một đối tượng có thể được tải tự động trong ứng dụng của bạn. Đó giống như đường dẫn tuyệt đối hoặc đường dẫn tương đối.
job3dot5

9
@Panique - "cú pháp không xác định" là cú pháp Không gian tên của PHP 5.3. Không gian tên cho phép bạn đặt trước một lớp có không gian tên theo sau là dấu gạch chéo ngược. Ở đây anh ta đang sử dụng nó mà không có không gian tên để chỉ định DateTimelớp lõi , có nghĩa là mã sẽ hoạt động ngay cả khi bạn có một lớp khác được gọi DateTimetrong không gian tên hiện tại.
Spudley

Có phải tên ngày luôn bằng tiếng Anh không?
Marwelln

1
Phần sao chép không hoạt động chính xác. Bạn nên sao chép trước sau đó thực hiện thao tác trên bản sao nếu bạn cần bản gốc.
Farid Movsumov

25
$givenday = date("w", mktime(0, 0, 0, MM, dd, yyyy));

Điều này cung cấp cho bạn ngày trong tuần của chính ngày đã cho trong đó 0= Chủ nhật và 6= Thứ bảy. Từ đó bạn có thể tính ngược lại ngày mình muốn một cách đơn giản.


6
Câu trả lời này trả về việc một ngày nhất định là chủ nhật hay thứ hai, v.v. Nhưng, người hỏi đã hỏi ngày chủ nhật trong tuần của ngày nhất định như đã đề cập trong nhận xét của anh ta về câu hỏi ban đầu.
Rakib

19

Câu hỏi này cần một câu trả lời DateTime tốt : -

function firstDayOfWeek($date)
{
    $day = DateTime::createFromFormat('m-d-Y', $date);
    $day->setISODate((int)$day->format('o'), (int)$day->format('W'), 1);
    return $day->format('m-d-Y');
}

var_dump(firstDayOfWeek('06-13-2013'));

Đầu ra: -

string '06-10-2013' (length=10)

Điều này sẽ giải quyết các ranh giới năm và năm nhuận.


18

CHỈNH SỬA: liên kết dưới đây không còn chạy trên phiên bản PHP đã nêu. Nó đang chạy trên PHP 5.6 giúp cải thiện độ tin cậy của strtotime, nhưng không hoàn hảo! Kết quả trong bảng là kết quả trực tiếp từ PHP 5.6.

Đối với những gì nó đáng giá, đây là bảng phân tích về hành vi nhạy cảm của strtotime khi xác định một hệ quy chiếu nhất quán:

http://gamereplays.org/reference/strtotime.php

Về cơ bản, chỉ những chuỗi này sẽ cung cấp cho bạn cùng một ngày một cách đáng tin cậy, bất kể bạn hiện đang ở ngày nào trong tuần khi bạn gọi chúng:

strtotime("next monday");
strtotime("this sunday");
strtotime("last sunday"); 

Bài báo cũng đưa ra một số mã cụ thể để sử dụng: $ start_of_week = strtotime ("thứ hai tới - 1 tuần"); // Sẽ quay lại vào Thứ Hai của tuần hiện tại bắt đầu lúc 00:00:00 "$ end_of_week = strtotime (" thứ hai tới - 1 giây "); // Sẽ quay lại Chủ nhật của tuần hiện tại kết thúc lúc 23:59:59"
Scott M. Stolz

11

Mã sau sẽ hoạt động với bất kỳ ngày tùy chỉnh nào, chỉ cần sử dụng định dạng ngày mong muốn.

$custom_date = strtotime( date('d-m-Y', strtotime('31-07-2012')) ); 
$week_start = date('d-m-Y', strtotime('this week last monday', $custom_date));
$week_end = date('d-m-Y', strtotime('this week next sunday', $custom_date));
echo '<br>Start: '. $week_start;
echo '<br>End: '. $week_end;

Tôi đã kiểm tra mã với PHP 5.2.17 Kết quả:

Start: 30-07-2012
End: 05-08-2012

1
Cần lưu ý rằng điều này sẽ luôn trả về Thứ Hai trước đó, vì vậy nếu $ custom_date là Thứ Hai, nó sẽ trả về ngày Thứ Hai sớm hơn một tuần.
Hill79

2
Không hoạt động bình thường, hôm nay là chủ nhật, kết quả là: Bắt đầu: 09-09-2013 Kết thúc: 22-09-2013
user2019515 15/09/2013

10

Giả sử thứ Hai là ngày đầu tiên trong tuần, điều này hoạt động:

echo date("M-d-y", strtotime('last monday', strtotime('next week', time())));

1
"MM-dd-yyyy" không giống với "Ymd", vui lòng điều chỉnh câu trả lời của bạn cho phù hợp với các chi tiết cụ thể của câu hỏi.
Yevgeniy Afanasyev

1
date ("MM-dd-yyyy") xuất ra ngày tháng là: NovNov-0202-15151515. Tôi hy vọng nó phải là: date ("Mdy") xuất ra một ngày có thể đọc được như: 02-15 tháng 11
shasi kanth

"MM-dd-yyyy" xuất phát từ câu hỏi. Nếu bạn không chắc nó có nghĩa là gì - hãy hỏi nó trong một bình luận cho câu hỏi. Cảm ơn bạn đã sửa đổi câu trả lời của bạn.
Yevgeniy Afanasyev

9

Còn cái này thì sao?

$first_day_of_week = date('m-d-Y', strtotime('Last Monday', time()));
$last_day_of_week = date('m-d-Y', strtotime('Next Sunday', time()));

8
Thứ hai cuối cùng vào thứ hai sẽ cung cấp cho bạn thứ hai trước đó.
Ikke

8

Đây là những gì tôi đang sử dụng để có được ngày đầu tiên và cuối cùng của tuần từ bất kỳ ngày nào . Trong trường hợp này, thứ hai là ngày đầu tiên của tuần ...

$date = date('Y-m-d') // you can put any date you want
$nbDay = date('N', strtotime($date));
$monday = new DateTime($date);
$sunday = new DateTime($date);
$monday->modify('-'.($nbDay-1).' days');
$sunday->modify('+'.(7-$nbDay).' days');

1
Đó là câu trả lời thực sự!
Manuel

1
Hoạt động như một sự quyến rũ!
Liga

6

Ở đây, tôi đang coi Chủ nhật là ngày đầu tiên và thứ bảy là ngày cuối cùng trong tuần.

$m = strtotime('06-08-2012');  
$today =   date('l', $m);  
$custom_date = strtotime( date('d-m-Y', $m) );   
if ($today == 'Sunday') {  
   $week_start = date("d-m-Y", $m);  
} else {  
  $week_start = date('d-m-Y', strtotime('this week last sunday', $custom_date));  
}  

if ($today == 'Saturday') {  
  $week_end = date("d-m-Y", $m);
} else {  
  $week_end = date('d-m-Y', strtotime('this week next saturday', $custom_date));  
}
echo '<br>Start: '. $week_start;  
echo '<br>End: '. $week_end;  

Đầu ra:

Bắt đầu: 05-08-2012
Kết thúc: 11-08-2012


5

Còn cái này thì sao?

$day_of_week = date('N', strtotime($string_date));
$week_first_day = date('Y-m-d', strtotime($string_date . " - " . ($day_of_week - 1) . " days"));
$week_last_day = date('Y-m-d', strtotime($string_date . " + " . (7 - $day_of_week) . " days"));

4

Thử cái này:

function week_start_date($wk_num, $yr, $first = 1, $format = 'F d, Y')
{
    $wk_ts  = strtotime('+' . $wk_num . ' weeks', strtotime($yr . '0101'));
    $mon_ts = strtotime('-' . date('w', $wk_ts) + $first . ' days', $wk_ts);
    return date($format, $mon_ts);
}

$sStartDate = week_start_date($week_number, $year);
$sEndDate   = date('F d, Y', strtotime('+6 days', strtotime($sStartDate)));

(từ chủ đề diễn đàn này )


làm cách nào để lấy số tuần và năm trong tất cả những thứ đó? Tôi có một chuỗi ngày ở định dạng MM-dd-yyyy
Iggy Ma

4

Đây là giải pháp ngắn nhất và dễ đọc nhất mà tôi tìm thấy:

    <?php
    $weekstart = strtotime('monday this week');
    $weekstop = strtotime('sunday this week 23:59:59');
    //echo date('d.m.Y H:i:s', $weekstart) .' - '. date('d.m.Y H:i:s', $weekstop);
    ?>

strtotimenhanh hơn new DateTime()->getTimestamp().


Điều này thật hoàn hảo, hãy xem bản sửa lỗi của tôi cho các ngày ở Úc / Vương quốc Anh
zanderwar


2

Với phiên bản PHP trước 5.3, hàm sau cung cấp cho bạn một ngày đầu tiên trong tuần của ngày cụ thể (trong trường hợp này - Chủ nhật, 2013-02-03):

<?php
  function startOfWeek($aDate){
    $d=strtotime($aDate);
    return strtotime(date('Y-m-d',$d).' - '.date("w",$d).' days');
  }

  echo(date('Y-m-d',startOfWeek("2013-02-07")).'
');
?>

2
$today_day = date('D'); //Or add your own date
$start_of_week = date('Ymd');
$end_of_week = date('Ymd');

if($today_day != "Mon")
    $start_of_week = date('Ymd', strtotime("last monday"));

if($today_day != "Sun")
                    $end_of_week = date('Ymd', strtotime("next sunday"));

2
$monday = date('d-m-Y',strtotime('last monday',strtotime('next monday',strtotime($date))));

Trước tiên, bạn phải nhận được thứ hai tiếp theo sau đó nhận được 'ngày thứ hai cuối cùng' của thứ hai tiếp theo. Vì vậy, nếu ngày nhất định là thứ hai, nó sẽ trả về cùng một ngày không phải thứ hai của tuần trước.


2

Nếu bạn muốn thứ Hai là đầu tuần của mình, hãy làm như sau:

$date = '2015-10-12';
$day = date('N', strtotime($date));
$week_start = date('Y-m-d', strtotime('-'.($day-1).' days', strtotime($date)));
$week_end = date('Y-m-d', strtotime('+'.(7-$day).' days', strtotime($date)));

Điều gì làm cho câu trả lời này thích hợp hơn câu trả lời này , hay câu trả lời này ? Dường như với tôi có hơn tùy chọn đủ trong 30 câu trả lời khác ...
Mogsdad

Cám ơn. đây là giải pháp đơn giản và nó hoạt động như một sự quyến rũ.
Oleg Popov

2

Một cách thông minh để làm điều này là để PHP xử lý sự khác biệt về múi giờ và Giờ tiết kiệm ánh sáng ban ngày (DST). Hãy để tôi chỉ cho bạn cách làm điều này.

Hàm này sẽ tạo tất cả các ngày từ Thứ Hai đến Thứ Sáu, bao gồm cả (tiện dụng để tạo các ngày làm việc trong tuần):

class DateTimeUtilities {
    public static function getPeriodFromMondayUntilFriday($offset = 'now') {
        $now = new \DateTimeImmutable($offset, new \DateTimeZone('UTC'));
        $today = $now->setTime(0, 0, 1);

        $daysFromMonday = $today->format('N') - 1;

        $monday = $today->sub(new \DateInterval(sprintf('P%dD', $daysFromMonday)));
        $saturday = $monday->add(new \DateInterval('P5D'));

        return new \DatePeriod($monday, new \DateInterval('P1D'), $saturday);
    }
}

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday() as $day) {
    print $day->format('c');
    print PHP_EOL;
}

Điều này sẽ trả về lịch ngày từ Thứ Hai đến Thứ Sáu cho tuần hiện tại. Để làm tương tự cho một ngày tùy ý, hãy chuyển một ngày làm tham số cho DateTimeUtilities ::getPeriodFromMondayUntilFriday, do đó:

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00') as $day) {
    print $day->format('c');
    print PHP_EOL;
}

//prints 
//2017-01-02T00:00:01+00:00
//2017-01-03T00:00:01+00:00
//2017-01-04T00:00:01+00:00
//2017-01-05T00:00:01+00:00
//2017-01-06T00:00:01+00:00

Chỉ quan tâm đến thứ Hai, như OP yêu cầu?

$monday = DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00')->getStartDate()->format('c');
print $monday;
// prints
//2017-01-02T00:00:01+00:00

1

Bạn phân tích cú pháp ngày bằng cách sử dụng strptime()và sử dụng date()trên kết quả:

date('N', strptime('%m-%d-%g', $dateString));

1
<?php
/* PHP 5.3.0 */

date_default_timezone_set('America/Denver'); //Set apprpriate timezone
$start_date = strtotime('2009-12-15'); //Set start date

//Today's date if $start_date is a Sunday, otherwise date of previous Sunday
$today_or_previous_sunday = mktime(0, 0, 0, date('m', $start_date), date('d', $start_date), date('Y', $start_date)) - ((date("w", $start_date) ==0) ? 0 : (86400 * date("w", $start_date)));

//prints 12-13-2009 (month-day-year)
echo date('m-d-Y', $today_or_previous_sunday);

?>

(Lưu ý: MM, dd và yyyy trong Câu hỏi không phải là cú pháp định dạng ngày php tiêu chuẩn - Tôi không thể chắc chắn ý nghĩa của nó là gì, vì vậy tôi đã đặt $ start_date với ISO year-month-day)


1

Một cách khác để làm điều đó ....

$year = '2014';
$month = '02';
$day = '26';

$date = DateTime::createFromFormat('Y-m-d H:i:s', $year . '-' . $month . '-' . $day . '00:00:00');
$day = date('w', $date->getTimestamp());

// 0=Sunday 6=Saturday
if($day!=0){

   $newdate = $date->getTimestamp() - $day * 86400;  //86400 seconds in a day

   // Look for DST change 
   if($old = date('I', $date->getTimestamp()) != $new = date('I', $newdate)){
       if($old == 0){
           $newdate -= 3600;  //3600 seconds in an hour
       } else {
           $newdate += 3600;
       }
   }

   $date->setTimestamp($newdate);
}

echo $date->format('D Y-m-d H:i:s');

1

Cách dễ nhất để có được ngày đầu tiên (thứ Hai) của tuần hiện tại là:

strtotime("next Monday") - 604800;

trong đó 604800 - là số giây trong 1 tuần (60 * 60 * 24 * 7).

Mã này nhận được vào thứ Hai tới và giảm xuống trong 1 tuần. Mã này sẽ hoạt động tốt vào bất kỳ ngày nào trong tuần. Ngay cả khi hôm nay là thứ Hai.


1

Tôi thấy điều này khá bực bội vì múi giờ của tôi là Úc và strtotime() ghét ngày ở Vương quốc Anh.

Nếu ngày hiện tại là Chủ nhật, thì strtotime("monday this week")ngày hôm sau sẽ quay lại.

Để khắc phục điều này:

Thận trọng : Điều này chỉ hợp lệ cho các ngày ở Úc / Vương quốc Anh

$startOfWeek = (date('l') == 'Monday') ? date('d/m/Y 00:00') : date('d/m/Y', strtotime("last monday 00:00"));
$endOfWeek = (date('l') == 'Sunday') ? date('d/m/Y 23:59:59') : date('d/m/Y', strtotime("sunday 23:59:59"));

2
Điều này cũng hoạt động cho các ngày của Hoa Kỳ. Tôi đã thử nghiệm điều này với múi giờ Newyork.
Jayesh D

Miễn là Chủ nhật không phải là ngày đầu tiên trong tuần của bạn (Thứ Hai ở Úc / Anh) thì mọi chuyện sẽ ổn.
zanderwar

1

Đây là một lớp lót cho ngày đầu tiên của tuần trước và ngày cuối cùng của tuần trước dưới dạng một DateTimeđối tượng.

$firstDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 7))
                             ->setTime(0, 0, 0);
$lastDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 1))
                            ->setTime(23, 59, 59);

1
$string_date = '2019-07-31';
echo $day_of_week = date('N', strtotime($string_date));
echo $week_first_day = date('Y-m-d', strtotime($string_date . " - " . ($day_of_week - 1) . " days"));
echo $week_last_day = date('Y-m-d', strtotime($string_date . " + " . (7 - $day_of_week) . " days"));

Hữu ích khi chúng ta có Thứ Hai là ngày đầu tiên của tuần (Thứ Hai-Chủ Nhật).
Kamran Mushtaq

0

Tôi đã phản đối câu hỏi này một vài lần và luôn ngạc nhiên khi các hàm ngày tháng không làm cho điều này dễ dàng hơn hoặc rõ ràng hơn. Đây là giải pháp của tôi cho PHP5 sử dụng DateTimelớp:

/**
 * @param DateTime $date A given date
 * @param int $firstDay 0-6, Sun-Sat respectively
 * @return DateTime
 */
function getFirstDayOfWeek(DateTime $date, $firstDay = 0) {
    $offset = 7 - $firstDay;
    $ret = clone $date;
    $ret->modify(-(($date->format('w') + $offset) % 7) . 'days');
    return $ret;
}

Cần thiết để nhân bản để tránh thay đổi ngày gốc.


0

Thế còn:

$date = "2013-03-18"; 
$searchRow = date("d.m.Y", strtotime('last monday',strtotime($date." + 1 day")));
echo "for date " .$date ." we get this monday: " ;echo $searchRow; echo '<br>';

Đó không phải là cách tốt nhất nhưng tôi đã thử nghiệm và nếu tôi ở trong tuần này, tôi sẽ nhận được đúng thứ hai, và nếu tôi vào thứ hai, tôi sẽ nhận được thứ hai đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.