I currently need to get the previous week from a variable that passes a php week number so if it is week 13 I will get week 12.
The problem I am facing is that if I just minus 1 from the original number if I am in week 1 it will return week 0 unless I create an if statement ie:
if($week==1)
{
$prev_week=52;
$prev_year=$year-1;
}
This is assuming that php counts the weeks from 1 and not 0. This seems a bit clumsy and I was thinking there may be a better way of doing this utilizing PHP's many date and time functions.
Try this:
$currentWeek = date( 'W' );
$today = strtotime( date( 'Y-m-d' ) ) - 7*24*60*60; // last week this day
// change 7 to 30 to see last year's week numer
$lastWeek = date( 'W', $today );
echo $currentWeek . '--' . $lastWeek;
Hope this helps.
Update
$lastWeekNumber = date( 'W', strtotime( 'last week' ) );
$PreviousWeek = date("W",strtotime("-1 week"));
HamZa's and web-nomad's answers helped me to go a bit further and make sure, I get the right year. Using date ('Y') can lead to unexpected behavior since it can happen, that week 1 belongs to the next or the previous year according to ISO-8601 (which is what is used in Europe). Instead use date ('o'). Otherwise it can happen that you jump from week 52 to week 1 of the previous year (because the start of the week is in the previous year according to date ('Y').
$jahr = 2014; // jahr means year
$kw = 52; // kw contains week
Using date ('Y')returns:
previousWeek: 51-2014
currentWeek: 52-2014
nextWeek: 01-2014
Using date ('o')returns:
previousWeek: 51-2014
currentWeek: 52-2014
nextWeek: 01-2015
See all the code together, e. g. for building forward and backward-links:
$kwBack['kw'] = date ("W", strtotime ($jahr. 'W' . str_pad ($kw, 2, 0, STR_PAD_LEFT). ' -1 week'));
$kwBack['jahr'] = date ("o", strtotime ($jahr. 'W' . str_pad ($kw, 2, 0, STR_PAD_LEFT). ' -1 week'));
$kwNext['kw'] = date ("W", strtotime ($jahr. 'W' . str_pad ($kw, 2, 0, STR_PAD_LEFT). ' +1 week'));
$kwNext['jahr'] = date ("o", strtotime ($jahr. 'W' . str_pad ($kw, 2, 0, STR_PAD_LEFT). ' +1 week'));
echo "previousWeek: " . $kwBack['kw'] . "-" . $kwBack['jahr'];
echo "<br>currentWeek: " . $kw . "-" . $jahr;
echo "<br>nextWeek: " . $kwNext['kw'] . "-" . $kwNext['jahr'];
echo "<br>";
// Build the links
$urlBack = $_SERVER['PHP_SELF'] . "?" . http_build_query ($kwBack);
$urlNext = $_SERVER['PHP_SELF'] . "?" . http_build_query ($kwNext);
echo "Previous week: ". $urlBack . "<br>";
echo "Next week: ". $urlNext;
I think I could be over complicating the problem - basically I need to obtain results from the database that appear in the previous weeks from the selected week therefore if there is a possibility of 54 weeks in a year all I really need to do is:-
if($week==1)
{
$year_minsued=$year-1;
$week_minused=54;
}
else
{
$week_minused=$week-1;
$year_minused=$year;
}
My select statement can then read:
SELECT SUM(post_price), SUM(total_price) FROM
database_table
WHERE client_id='$account_no'
AND
(year<='$year_minused' AND week<='$week_minused')
I have not tested this as yet but thinks it should do the job.
We know that a year can be between 52 or 53 weeks. So, I created here a function that receives the current week and the current year. If this is true, it is obvious that the previous week will be the last week of the previous year, so through the variable year that I gave to this function, I subtract 1 to have the value or the previous year and I try to know how many weeks this year has, in this case that will be the week before week 1 for example. Otherwise, I subtract 1 in the value of the current week to have the value of the previous week.
i hope i have helped
function PreviusWeekNumber($ActualWeek, $Year){
if($ActualWeek === 1){
$TransformYearIntolastYear = $Year -1;
$date = new DateTime;
$date->setISODate($TransformYearIntolastYear, 53);
$Result = ($date->format("W") === "53" ? 53 : 52);
}else{
$Result = $ActualWeek -1;
}
return $Result;
}
Check this
$year = 2013; // Retrieved from the DB
$week = 1;
$prev_week = date("W",strtotime($year. 'W'.str_pad($week, 2, 0, STR_PAD_LEFT). ' -1 week'));
echo $prev_week; // returns 52
A demo which shows the year:
$year = 2013; // Retrieved from the DB
$week = 1;
$prev_week = date("W - Y",strtotime($year. 'W'.str_pad($week, 2, 0, STR_PAD_LEFT). ' -1 week'));
echo $prev_week; // returns 52 - 2012
Related
PHP 7.1.7
There's a work function I'm dealing with that has a custom "week" (where a "week" for this function is Saturday through Friday).
For any given day of the week, how could I set two variables to contain the start of the custom defined week (Saturday) and the end of the custom defined week (Friday).
So, if I had a date of 8-11-17, I would need to come up with a a start date variable holding 8-05-17 and an end date variable holding 8-11-17.
Thanks
Not sure if I understood the question correct but is this what you are looking for?
It uses strtotime() to find previous saturday from input. Then next friday from that saturday.
$Input = "08/12/2017";
if(date("l", strtotime($Input)) == "Saturday"){
$Saturday = strtotime($Input);
}else{
$Saturday = strtotime($Input . " previous saturday");
}
$Friday = strtotime(date("m/d/Y", $Saturday) . " next friday");
echo date("m/d/Y", $Saturday) . " to " . date("m/d/Y", $Friday);
https://3v4l.org/l4g8D
EDIT; I just noticed if the Input is a saturday my code choosed the wrong dates. Corrected.
you could use date('w') to determine the day of week for given date.
If the number found is less than 6, move that number + 1 backwards. That's your starting date. End date will be 7 days later:
<?php
$date = new DateTime('08-11-2017');
$daynumber = $date->format('w');
if($daynumber < 6) {
$tomove = $daynumber + 1;
$date->modify('-' . $tomove.'day');
}
$startdate = $date;
$enddate = clone $date;
$enddate->modify('+7day');
echo $startdate->format('d-m-y');
echo $enddate->format('d-m-y');
?>
edit
forgot the word "day" in modify
In the Christian liturgical year, Advent starts things off four weeks before Christmas, and there are three cycles (Year A, B, and C).
In PHP, what would be the most efficient and elegant method to determine what cycle we would be in for any given year.
Here are the rules:
The beginning of the cycle occurs on whatever Sunday falls on or closest to Nov. 30
November 30, 2016 was the beginning of year A.
There are three iterations, being year A, year B, and year C, after which we return to year A.
So if given any year month and day, would it be possible to determine whether that date was in the cycle A, B, or C?
UPDATE: What I've tried
I'm not very good with math, so haven't had much luck in figuring this out.
I've been focusing first on the year and how it relates to A B and C.
So if I equate A to 1 and B to 2 and C to 3, I could get the first three years by subtracting 2015 from the current date - but I don't know what to do after 2018.
To calculate the year, I think this would work:
$year = date('Y');
$year_A = strtotime(date('Y', strtotime('-1 year', strtotime($year))));
if($year % 3 == 0) {
$liturgical_year = "C" ;
} else if ($year_A % 3 == 0) {
$liturgical_year = "A" ;
} else {
$liturgical_year = "B" ;
}
echo $liturgical_year;
Also, to calculate the first date of the Liturgical year you can use St Andrew's feast day and find the closest Sunday:
$St_Andrew = date("Y") . "-11-30";
$St_Andrew = date($St_Andrew);
$last_Sunday = date('Y-m-d', strtotime('last Sunday', strtotime($St_Andrew)));
$next_Sunday = date('Y-m-d', strtotime('next Sunday', strtotime($St_Andrew)));
$days_delta = abs(strtotime($St_Andrew) - strtotime($last_Sunday))/(60 * 60 * 24);
if ($days_delta <= 3) {
$advent = $last_Sunday;
} else {
$advent = $next_Sunday;
}
Thanks to #Qirel for pointing me in the right direction. I've never really used the modulus operator before!
So problem is solved as follows (though my coding might be sloppy / inefficient):
$cycle = array(1=>"A",2=>"B",3=>"C");
for($year=2016;$year<2120;$year++){
$date = strtotime("Nov 30, " . $year);
echo "Sunday closest to " . date("Y-m-d",$date) . " is ";
$date = new DateTime($year . "/11/30 -4 days");
$date->modify("next Sunday");
echo $date->format("Y-d-m");
echo " where we start Year " . $cycle[(($year % 3) + 1)] . "<br/>";
}
Here's what's going on:
$cycle is defined as an array, where numbers 1, 2, and 3 are associated with years A, B, and C.
I then start a for loop to work through the years 2016 to 2120, incrementing the years by 1 on each iteration.
I then create a date of XXXX Nov 30 minus 4 days, where XXXX is the year we're iterating through. The minus four days helps us to be sure we're considering the date closest to the 30th, so that when we modify it in the following line to "next Sunday" it will always be the one closest to the 30th.
We then use the array $cycle, divide the year by 3 and take the remainder (using the modulus operator) which gives us either 0, 1, or 2 as an answer. I add one to it so it's returning 1, 2, or 3.
That isn't really necessary if I assign 0=>A, 1=>B, and 2=>C but...
I wrote a function to return this information:
function returnLiturgicalYear($year){
$cycle = array(0=>"A",1=>"B",2=>"C");
$date = new DateTime($year . "/11/30 -4 days");
$date->modify("next Sunday");
return $cycle[($year % 3)];
}
Hopefully this helps someone else trying to determine the Christian liturgical year for any date.
I'm a newbie in both php and codeigniter.
I have a function which is used to label the x-axis of a chart of weekly sums of kilometers rode on a bicycle. It works (or is supposed to work) by counting back from today's date either zero Sundays or 1, 2, 3, etc as passed by an array.
I am using PHP Version 5.6.19, and this is my code:
In the Model:
public function week_start($date, $counter){
$tstring = strtotime($date);
$wknumber = ($counter + 1);
$start = strtotime("-$wknumber weeks sunday", $tstring);
return array(date('M d', $start));}
In the Controller:
$datenumbers = array(0, 1, 2, 3, 4, 5, 6, 7);
$dateResult = $this->bike_model->week_start(date("Y/m/d"), $datenumber);
In the view:
for ($i = 0; $i < 8; $i++){
echo "<text class = \"axis\" y = \"357\" x = \"";
echo 26 + ($i*70);
echo "\" dy = \".35em\">";
echo $dates_for_table[$i];}
I have had it up for few days and it has been showing Sunday July 3 as the first number on on my x-axis, as it should have. But today, it is Sunday and I expect it to now say Sunday July 10 as my most recent week. However, it is still showing last Sunday!
So my question is, is there a bug here or am I misunderstanding how '- one week Sunday' should work?
My goal is to have my function with zero as the argument return the most recent week start--either the current Sunday if it is Sunday or the past Sunday. I have found a workaround by adding an if else to the function checking if it is Sunday.
if ($tstring == strtotime('this Sunday')){
$wknumber = $counter;}
else{
$wknumber = ($counter + 1);}
However, this feels clunky and I'm looking for a more elegant way. I also want to understand what went wrong with "- one week Sunday" since I thought I had understood how it was working.
Thank you!
Here is how I did something similar using the object oriented DateTime style:
$startDate = new DateTime('NOW'); // can pass date string if not today
# reset start date to last Sunday or today if it is Sunday:
$startDate->sub(new DateInterval('P'.($startDate->format('w')).'D'));
# for debugging, output first Sunday:
echo $startDate->format('Y-m-d H:i:s') . " => full date and time (check for timezone issues) \n\n";
$weeks = 8;
for ($i = 0; $i < $weeks; $i++) {
# don't decrement first pass; sub 1 week on subsequent:
$startDate->sub(new DateInterval('P'. (($i) ? 1 : 0) .'W'));
echo $startDate->format('Y-m-d') . "\n";
};
You should be able to adapt for your purpose.
If you want to get fancy, you can also use DatePeriod instead of using sub within a loop:
$period = new DatePeriod(
$startDate,
DateInterval::createFromDateString('-1 week'),
7
);
foreach ($period as $date) {
echo $date->format('Y-m-d') . "\n";
}
I can display dates from start to end date from stored data in mysql, but I want to display current month dates from 1st to end date of this month in form of
1
2
3
4
.
.
.
.
.
31
Is this possible?
Refer to PHP cal_days_in_month
As explained here
This function will return the number of days in the month of year for the specified calendar.
int cal_days_in_month ( int $calendar , int $month , int $year )
And an example:
$number = cal_days_in_month(CAL_GREGORIAN, 8, 2003); // 31
echo "There were {$number} days in August 2003";
Use a loop to display a count of the number of days
For the PHP part, this might help you:
// Get the current date
$today = getdate();
// Get the number of days in current month
$days_in_month = cal_days_in_month(CAL_GREGORIAN, $today['mon'], $today['year']);
// Print the dates
for ($i = 1; $i <= $days_in_month; $i++) {
echo ' ' . $i;
}
Styling and output is another task, this is just to get you started.
yes. it is possible.
please, use below php code. it can work for php 4.1 and higher.
<?php
$number = cal_days_in_month(CAL_GREGORIAN, date('m'), date('Y'));
for($i=1;$i<=$number;$i++)
echo $i.'<br>';
?>
If you want all days in the month, try this loop where date("t") give you the numerical last day of the month, and we know the first day is always 1.
$last = date("t");
for($i=1; $i<= $last; $i++) echo "$i ";
I am trying to write a custom function for getting dates from week numbers but the requirement is that the week numbers are custom i.e. the week1 starts from 1st Week of March and the First Day of each week is Friday
I trying to do this in PHP.
Your help or advice would be really helpful for writing this function.
I have gone through some of functions here but doesnt actually fit my requirement.
Thanking You
This might give you a starting point:
$year = 2012;
$startDate = new \DateTime($year . '-03-01');
$startDate->modify('Friday');
echo $startDate->format('Y-m-d') , PHP_EOL;
$endDate = new \DateTime($year+1 . '-03-01');
$endDate->modify('Friday');
echo $endDate->format('Y-m-d') , PHP_EOL;
$interval = new \DateInterval('P1W');
$weekPeriod = new \DatePeriod ($startDate, $interval, $endDate);
foreach ($weekPeriod as $key => $weekDate) {
echo 'Week #' , $key + 1 , ' starts on ';
echo $weekDate->format('Y-m-d') , PHP_EOL;
}
You can use this to build an array, that you can then use as a lookup