I have an array of random dates (not coming from MySQL). I need to group them by the week as Week1, Week2, and so on upto Week5.
What I have is this:
$dates = array('2015-09-01','2015-09-05','2015-09-06','2015-09-15','2015-09-17');
What I need is a function to get the week number of the month by providing the date.
I know that I can get the weeknumber by doing
date('W',strtotime('2015-09-01'));
but this week number is the number between year (1-52) but I need the week number of the month only, e.g. in Sep 2015 there are 5 weeks:
Week1 = 1st to 5th
Week2 = 6th to 12th
Week3 = 13th to 19th
Week4 = 20th to 26th
Week5 = 27th to 30th
I should be able to get the week Week1 by just providing the date
e.g.
$weekNumber = getWeekNumber('2015-09-01') //output 1;
$weekNumber = getWeekNumber('2015-09-17') //output 3;
I think this relationship should be true and come in handy:
Week of the month = Week of the year - Week of the year of first day of month + 1
We also need to make sure that "overlapping" weeks from the previous year are handeled correctly - if January 1st is in week 52 or 53, it should be counted as week 0. In a similar fashion, if a day in December is in the first week of the next year, it should be counted as 53. (Previous versions of this answer failed to do this properly.)
<?php
function weekOfMonth($date) {
//Get the first day of the month.
$firstOfMonth = strtotime(date("Y-m-01", $date));
//Apply above formula.
return weekOfYear($date) - weekOfYear($firstOfMonth) + 1;
}
function weekOfYear($date) {
$weekOfYear = intval(date("W", $date));
if (date('n', $date) == "1" && $weekOfYear > 51) {
// It's the last week of the previos year.
return 0;
}
else if (date('n', $date) == "12" && $weekOfYear == 1) {
// It's the first week of the next year.
return 53;
}
else {
// It's a "normal" week.
return $weekOfYear;
}
}
// A few test cases.
echo weekOfMonth(strtotime("2020-04-12")) . " "; // 2
echo weekOfMonth(strtotime("2020-12-31")) . " "; // 5
echo weekOfMonth(strtotime("2020-01-02")) . " "; // 1
echo weekOfMonth(strtotime("2021-01-28")) . " "; // 5
echo weekOfMonth(strtotime("2018-12-31")) . " "; // 6
To get weeks that starts with sunday, simply replace date("W", ...) with strftime("%U", ...).
You can use the function below, fully commented:
/**
* Returns the number of week in a month for the specified date.
*
* #param string $date
* #return int
*/
function weekOfMonth($date) {
// estract date parts
list($y, $m, $d) = explode('-', date('Y-m-d', strtotime($date)));
// current week, min 1
$w = 1;
// for each day since the start of the month
for ($i = 1; $i < $d; ++$i) {
// if that day was a sunday and is not the first day of month
if ($i > 1 && date('w', strtotime("$y-$m-$i")) == 0) {
// increment current week
++$w;
}
}
// now return
return $w;
}
The corect way is
function weekOfMonth($date) {
$firstOfMonth = date("Y-m-01", strtotime($date));
return intval(date("W", strtotime($date))) - intval(date("W", strtotime($firstOfMonth)));
}
I have created this function on my own, which seems to work correctly. In case somebody else have a better way of doing this, please share.. Here is what I have done.
function weekOfMonth($qDate) {
$dt = strtotime($qDate);
$day = date('j',$dt);
$month = date('m',$dt);
$year = date('Y',$dt);
$totalDays = date('t',$dt);
$weekCnt = 1;
$retWeek = 0;
for($i=1;$i<=$totalDays;$i++) {
$curDay = date("N", mktime(0,0,0,$month,$i,$year));
if($curDay==7) {
if($i==$day) {
$retWeek = $weekCnt+1;
}
$weekCnt++;
} else {
if($i==$day) {
$retWeek = $weekCnt;
}
}
}
return $retWeek;
}
echo weekOfMonth('2015-09-08') // gives me 2;
function getWeekOfMonth(DateTime $date) {
$firstDayOfMonth = new DateTime($date->format('Y-m-1'));
return ceil(($firstDayOfMonth->format('N') + $date->format('j') - 1) / 7);
}
Goendg solution does not work for 2016-10-31.
function weekOfMonth($strDate) {
$dateArray = explode("-", $strDate);
$date = new DateTime();
$date->setDate($dateArray[0], $dateArray[1], $dateArray[2]);
return floor((date_format($date, 'j') - 1) / 7) + 1;
}
weekOfMonth ('2015-09-17') // returns 3
Given the time_t wday (0=Sunday through 6=Saturday) of the first of the month in firstWday, this returns the (Sunday-based) week number within the month:
weekOfMonth = floor((dayOfMonth + firstWday - 1)/7) + 1
Translated into PHP:
function weekOfMonth($dateString) {
list($year, $month, $mday) = explode("-", $dateString);
$firstWday = date("w",strtotime("$year-$month-1"));
return floor(($mday + $firstWday - 1)/7) + 1;
}
You can also use this simple formula for finding week of the month
$currentWeek = ceil((date("d",strtotime($today_date)) - date("w",strtotime($today_date)) - 1) / 7) + 1;
ALGORITHM :
Date = '2018-08-08' => Y-m-d
Find out day of the month eg. 08
Find out Numeric representation of the day of the week minus 1 (number of days in week) eg. (3-1)
Take difference and store in result
Subtract 1 from result
Divide it by 7 to result and ceil the value of result
Add 1 to result eg. ceil(( 08 - 3 ) - 1 ) / 7) + 1 = 2
My function. The main idea: we would count amount of weeks passed from the month's first date to current. And the current week number would be the next one. Works on rule: "Week starts from monday" (for sunday-based type we need to transform the increasing algorithm)
function GetWeekNumberOfMonth ($date){
echo $date -> format('d.m.Y');
//define current year, month and day in numeric
$_year = $date -> format('Y');
$_month = $date -> format('n');
$_day = $date -> format('j');
$_week = 0; //count of weeks passed
for ($i = 1; $i < $_day; $i++){
echo "\n\n-->";
$_newDate = mktime(0,0,1, $_month, $i, $_year);
echo "\n";
echo date("d.m.Y", $_newDate);
echo "-->";
echo date("N", $_newDate);
//on sunday increasing weeks passed count
if (date("N", $_newDate) == 7){
echo "New week";
$_week += 1;
}
}
return $_week + 1; // as we are counting only passed weeks the current one would be on one higher
}
$date = new DateTime("2019-04-08");
echo "\n\nResult: ". GetWeekNumberOfMonth($date);
$month = 6;
$year = 2021;
$week = date("W", strtotime($year . "-" . $month ."-01"));
$str='';
$str .= date("d-m-Y", strtotime($year . "-" . $month ."-01")) ."to";
$unix = strtotime($year."W".$week ."+1 week");
while(date("m", $unix) == $month){
$str .= date("d-m-Y", $unix-86400) . "|";
$str .= date("d-m-Y", $unix) ."to";
$unix = $unix + (86400*7);
}
$str .= date("d-m-Y", strtotime("last day of ".$year . "-" . $month));
$weeks_ar = explode('|',$str);
echo '<pre>'; print_r($weeks_ar);
working fine.
// Current week of the month starts with Sunday
$first_day_of_the_week = 'Sunday';
$start_of_the_week1 = strtotime("Last $first_day_of_the_week");
if (strtolower(date('l')) === strtolower($first_day_of_the_week)) {
$start_of_the_week1 = strtotime('today');
}
$end_of_the_week1 = $start_of_the_week1 + (60 * 60 * 24 * 7) - 1;
// Get the date format
print date('Y-m-d', $start_of_the_week1) . ' 00:00:00';
print date('Y-m-d', $end_of_the_week1) . ' 23:59:59';
// self::DAYS_IN_WEEK = 7;
function getWeeksNumberOfMonth(): int
{
$currentDate = new \DateTime();
$dayNumberInMonth = (int) $currentDate->format('j');
$dayNumberInWeek = (int) $currentDate->format('N');
$dayNumberToLastSunday = $dayNumberInMonth - $dayNumberInWeek;
$daysCountInFirstWeek = $dayNumberToLastSunday % self::DAYS_IN_WEEK;
$weeksCountToLastSunday = ($dayNumberToLastSunday - $daysCountInFirstWeek) / self::DAYS_IN_WEEK;
$weeks = [];
array_push($weeks, $daysCountInFirstWeek);
for ($i = 0; $i < $weeksCountToLastSunday; $i++) {
array_push($weeks, self::DAYS_IN_WEEK);
}
array_push($weeks, $dayNumberInWeek);
if (array_sum($weeks) !== $dayNumberInMonth) {
throw new Exception('Logic is not valid');
}
return count($weeks);
}
Short variant:
(int) (new \DateTime())->format('W') - (int) (new \DateTime('first day of this month'))->format('W') + 1;
There is a many solutions but here is one my solution that working well in the most cases.
function current_week ($date = NULL) {
if($date) {
if(is_numeric($date) && ctype_digit($date) && strtotime(date('Y-m-d H:i:s',$date)) === (int)$date)
$unix_timestamp = $date;
else
$unix_timestamp = strtotime($date);
} else $unix_timestamp = time();
return (ceil((date('d', $unix_timestamp) - date('w', $unix_timestamp) - 1) / 7) + 1);
}
It accept unix timestamp, normal date or return current week from the time() if you not pass any value.
Enjoy!
I know this an old post but i have an idea!
$datetime0 = date_create("1970-01-01");
$datetime1 = date_create(date("Y-m-d",mktime(0,0,0,$m,"01",$Y)));
$datetime2 = date_create(date("Y-m-d",mktime(0,0,0,$m,$d,$Y)));
$interval1 = date_diff($datetime0, $datetime1);
$daysdiff1= $interval1->format('%a');
$interval2 = date_diff($datetime0, $datetime2);
$daysdiff2= $interval2->format('%a');
$week1=round($daysdiff1/7);
$week2=round($daysdiff2/7);
$WeekOfMonth=$week2-$week1+1;
$date = new DateTime('first Monday of this month');
$thisMonth = $date->format('m');
$mondays_arr = [];
// Get all the Mondays in the current month and store in array
while ($date->format('m') === $thisMonth) {
//echo $date->format('Y-m-d'), "\n";
$mondays_arr[] = $date->format('d');
$date->modify('next Monday');
}
// Get the day of the week (1-7 from monday to sunday)
$day_of_week = date('N') - 1;
// Get the day of month (1 to 31)
$current_week_monday_date = date('j') - $day_of_week;
/*$day_of_week = date('N',mktime(0, 0, 0, 2, 11, 2020)) - 1;
$current_week_monday_date = date('j',mktime(0, 0, 0, 2, 11, 2020)) - $day_of_week;*/
$week_no = array_search($current_week_monday_date,$mondays_arr) + 1;
echo "Week No: ". $week_no;
How about this function making use of PHP's relative dates?
This function assumes the week ends on Saturday. But this can be changed easily.
function get_weekNumMonth($date) {
$CI = &get_instance();
$strtotimedate = strtotime($date);
$firstweekEnd = date('j', strtotime("FIRST SATURDAY OF " . date("F", $strtotimedate) . " " . date("Y", $strtotimedate)));
$cutoff = date('j', strtotime($date));
$weekcount = 1;
while ($cutoff > $firstweekEnd) {
$weekcount++;
$firstweekEnd += 7; // move to next week
}
return $weekcount;
}
This function returns the integer week number of the current month. Weeks always start on Monday and counting always starts with 1.
function weekOfmonth(DateTime $date)
{
$dayFirstMonday = date_create('first monday of '.$date->format('F Y'))->format('j');
return (int)(($date->format('j') - $dayFirstMonday +7)/7) + ($dayFirstMonday == 1 ? 0 : 1);
}
Example of use
echo weekOfmonth(new DateTime("2020-04-12")); //2
A test for all days from 1900-2038 with the accepted solution from #Anders as a reference:
//reference functions
//integer $date (Timestamp)
function weekOfMonthAnders($date) {
//Get the first day of the month.
$firstOfMonth = strtotime(date("Y-m-01", $date));
//Apply above formula.
return weekOfYear($date) - weekOfYear($firstOfMonth) + 1;
}
function weekOfYear($date) {
$weekOfYear = intval(date("W", $date));
if (date('n', $date) == "1" && $weekOfYear > 51) {
// It's the last week of the previos year.
return 0;
}
else if (date('n', $date) == "12" && $weekOfYear == 1) {
// It's the first week of the next year.
return 53;
}
else {
// It's a "normal" week.
return $weekOfYear;
}
}
//this function
function weekOfmonth(DateTime $date)
{
$dayFirstMonday = date_create('first monday of '.$date->format('F Y'))->format('j');
return (int)(($date->format('j') - $dayFirstMonday +7)/7) + ($dayFirstMonday == 1 ? 0 : 1);
}
$dt = date_create('1900-01-01');
$end = date_create('2038-01-02');
$countOk = 0;
$countError = 0;
for(;$dt < $end; $dt->modify('+1 Day')){
$ts = $dt->getTimestamp();
if(weekOfmonth($dt) === weekOfMonthAnders($ts)){
++$countOk;
}
else {
++$countError;
}
}
echo $countOk.' compare ok, '.$countError.' errors';
Result: 50405 compare ok, 0 errors
I took the visual approach (like how we do it in the real world). Instead of using formulas or what not, I solved it (or at least I think I did) by visualizing a literal calendar and then putting the dates in a multidimensional array. The first dimension corresponds to the week.
I hope someone can check if it stands your tests. Or help someone out with a different approach.
# date in this format 2021-08-03
# week_start is either Sunday or Monday
function getWeekOfMonth($date, $week_start = "Sunday"){
list($year, $month, $day) = explode("-", $date);
$dates = array();
$current_week = 1;
$new_week_signal = $week_start == "Sunday" ? 6 : 0;
for($i = 1; $i <= date("t", strtotime($date)); $i++){
$current_date = strtotime("{$year}-{$month}-".$i);
$dates[$current_week][] = $i;
if(date('w', $current_date) == $new_week_signal){
$current_week++;
}
}
foreach($dates as $week => $days){
if(in_array(intval($day), $days)){
return $week;
}
}
return false;
}
//It's easy, no need to use php function
//Let's say your date is 2017-07-02
$Date = explode("-","2017-07-02");
$DateNo = $Date[2];
$WeekNo = $DateNo / 7; // devide it with 7
if(is_float($WeekNo) == true)
{
$WeekNo = ceil($WeekNo); //So answer will be 1
}
//If value is not float then ,you got your answer directly
I am working on a "cut-off" date and I need to set it on every month. Say, I set the cut-off date to August 25 for this year, then it should be September 25, October 25 and so on till the year ends.
Here's the code I have:
$now = "2015-08-25";
$nextDate = getCutoffDate($now);
echo $nextDate;
function getCutoffDate($start_date)
{
$date_array = explode("-",$start_date); // split the array
// var_dump($date_array);
$year = $date_array[0];
$month = $date_array[1];
$day = $date_array[2];
/*if (date('n', $now)==12)
{
return date("Y-m-d",strtotime(date("Y-m-d", $start_date) . "+1 month"));
}*/
if (date("d") <= $day) {
$billMonth = date_format(date_create(), 'm');
}
else{
$billMonth = date_format(date_modify(date_create(), 'first day of next month'), 'm');
}
// echo date("d").' '. $billMonth.'<br>';
$billMonthDays = cal_days_in_month(CAL_GREGORIAN, ($billMonth), date("Y"));
// echo $billMonthDays.'<br>';
if ($billMonthDays > $day) {
$billDay = $day;
} else {
$billDay = $billMonthDays;
}
}
I got this from here: http://www.midwesternmac.com/blogs/jeff-geerling/php-calculating-monthly
It returns the same date for the next month only, but how do I get the specific date of EACH month of the current year? Kindly leave your thoughts. Still a newbie here, sorry.
In that case, this should be enough:
<?php
for($i=8; $i<=12; $i++) {
echo sprintf('25-%02d-2015', $i) . '<br>';
}
but if you need more flexible way:
<?php
$date = new DateTime('25-08-2015');
function getCutoffDate($date) {
$days = cal_days_in_month(CAL_GREGORIAN, $date->format('n'), $date->format('Y'));
$date->add(new DateInterval('P' . $days .'D'));
return $date;
}
for($i = 0; $i < 5; $i++) {
$date = getCutoffDate($date);
echo $date->format('d-m-Y') . '<br>';
}
This should print:
25-09-2015
25-10-2015
25-11-2015
25-12-2015
25-01-2016
I am storing the date of a post in mysql database in this form y/m/d I want to check if the post is older than 3 days. Is there any way I can convert it to seconds ? and then check like so:
if($mysql_date > $three_days_old){
echo "old post";
}else {
echo "new post";
}
Using a mix of date() and strtotime() :
$myDate = date('Y-m-d', strtotime($mysql_date));
$oldDate = date('Y-m-d', strtotime('3 days ago'));
if ($myDate > $oldDate) {
echo "old post";
} else {
echo "new post";
}
Try, strtotime, that can parse various time string formats.
You can do following :
$d1 = strtotime(date('Y-m-d', strtotime($mysql_date)));
$d3 = mktime(0, 0, 0, date('m', $d1), date('d', $d1)-3, date('Y', $d1));
$d2 = strtotime(date('Y-m-d', strtotime('3 days ago')));
if ($d3 > $d2) {
echo 'old post';
}else {
echo 'new post';
}
i want to calculate latest 31-Mar .... suppose date is 1-Jan-2012 i want result as 31-mar-2011 and if is 1-April-2011 then also i want result 31-mar-2011 and if its 1-mar-2011 it should come as 31-mar-2010.....hope i made my self clear ...(with php) ... i al calculating date with this for financial year ...
always between 31-mar-lastyear to 1-April-thisyear
... year should be taken automatically ...
i was trying like this
31-mar-date('y') and 31-mar-date('y')-1
but its not working as its taking current year every time.
Here is an example using the wonderful strtotime function of php.
<?php
$day = 1;
$month = 1;
$year = 2011;
$date = mktime(12, 0, 0, $month, $day, $year);
$targetMonth = 3;
$difference = $month - $targetMonth;
if($difference < 0) {
$difference += 12;
}
$sameDateInMarch = strtotime("- " . $difference . " months", $date);
echo "Entered date: " . date("d M Y", $date) . "<br />";
echo "Last 31 march: " . date("t M Y", $sameDateInMarch);
// the parameter 't' displays the last day of the month
?>
Something like this:
function getLast() {
$currentYear = date('Y');
// Check if it happened this year, AND it's not in the future.
$today = new DateTime();
if (checkdate(3, 31, $currentYear) && $today->getTimestamp() > mktime(0, 0, 0, 3, 31, $currentYear)) {
return $currentYear;
}
while (--$currentYear) {
if (checkdate(3, 31, $currentYear)) {
return $currentYear;
}
}
return false;
}
var_dump(getLast());
It should return the year or false.
if (date('m')>3) {
$year = date('Y').'-'.(date('Y')+1);
} else {
$year = (date('Y')-1).'-'.date('Y');
}
echo $year;
this is to get the current financial year for India
I would like to know how to check if the timestamp is today, tomorrow or the day after tomorrow.
I have e.g. :
$timestamp = "1313000474";
How to make a check if this timestamp is today,tomorrow or the day after tomorrow?
e.g.
if today then echo $output = "today";
if tomorrow then echo $output = "tomorrow";
if the day after tomorrow then echo $output = "dayaftertomorrow";
How to do this?
EDIT: corrected unix timestamp
Thank you in advance.
$timestamp = "1313000474";
$date = date('Y-m-d', $timestamp);
$today = date('Y-m-d');
$tomorrow = date('Y-m-d', strtotime('tomorrow'));
$day_after_tomorrow = date('Y-m-d', strtotime('tomorrow + 1 day'));
if ($date == $today) {
echo "today";
} else if ($date == $tomorrow) {
echo "tomorrow";
} else if ($date == $day_after_tomorrow) {
echo "dayaftertomorrow";
}
Keep your code clean...
$timestamp = "1313000474";
// Description demonstrate proposes only...
$compare_dates = array(
'today' => 'today!!',
'tomorrow' => 'Tomorrow!!!',
'tomorrow +1 day' => 'day after tomorrow? YEAH',
);
foreach($compare_dates => $compare_date => $compare_date_desc){
if(strtotime($compare_date) > $timestamp && $timestamp < strtotime($compare_date.' +1 day') ){
echo $compare_date_desc;
break;
}
}
EDIT: With this you dont have to worry if the timestamp is already without hours, minutes and seconds... Or create different output dates, replacing echo $compare_date_desc; by echo date($compare_date_desc,$timestamp);
<?php
$time = "20060713174545";
$date = date('Y-m-d', strtotime($time));
$now = date('Y-m-d');
$tomorrow = date('Y-m-d', time() + strtotime('tomorrow'));
$day_after_tomorrow = date('Y-m-d', time() + strtotime('tomorrow + 1 day'));
if ($date == $now){
echo "It's today";
}
elseif($date == $tomorrow){
echo "It's tomorrow";
}
elseif($date == $day_after_tomorrow){
echo "It's day after tomorrow";
}
else{
echo "None of previous if statements passed";
}
<?php
function getTheDay($date)
{
$curr_date=strtotime(date("Y-m-d H:i:s"));
$the_date=strtotime($date);
$diff=floor(($curr_date-$the_date)/(60*60*24));
switch($diff)
{
case 0:
return "Today";
break;
case 1:
return "Yesterday";
break;
default:
return $diff." Days ago";
}
}
?>