I'm writing a script that gets some statistics about my website for a date this year, but I also want it to get me the data for the nearest corresponding day last year so I can compare them.
For example if I were to get the data for "Wednesday 14th Dec 2011", I'd want to also get the data for "Wednesday 15th Dec 2010".
I'm having a bit of trouble thinking of how to get the correct date from this year's date. I'd prefer to be able to pass the data into a function, something like:
// $date as a unix timestamp
// $day (0 for Sunday through 6 for Saturday)
function getClosestDay($date,$day=0) {
}
So I would be passing in a unix timestamp of last year's date, and also the day I'm looking to find. I'd expect it to return a unix timestamp of the correct day.
But I'm not sure where to even start with the function.
I'm not looking for someone to write the function for me, but if anyone has any ideas on where to start (even a nudge in the right direction) then that would be great!
I believe this would do. First we get the unix time of the same day last year
$newDate = '14th Dec 2011';
$newDate = strtotime($newDate);
$oldDate = strtotime('-1 year',$newDate);
Now we find the difference in week day. In this example, it'll be -1
$newDayOfWeek = date('w',$oldDate);
$oldDayOfWeek = date('w',$newDate);
$dayDiff = $oldDayOfWeek-$newDayOfWeek;
And then we extract/add that difference to the date
$oldDate = strtotime("$dayDiff days",$oldDate);
And output it
print date('r',$oldDate)."\n";
print date('r',$newDate)."\n";
The above should yield
Wed, 15 Dec 2010 00:00:00 +0100
Wed, 14 Dec 2011 00:00:00 +0100
Here is what I came up with:
function getClosestDate($date, $day = 0, $year = -1) {
$cts = strtotime($date);
$ts = strtotime("{$year} YEAR", $cts);
$days = array(
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
);
$day = $days[$day];
$prev = strtotime("PREVIOUS {$day}", $ts);
$next = strtotime("NEXT {$day}", $ts);
$prev_gap = $ts - $prev;
$next_gap = $next - $ts;
return $prev_gap < $next_gap ? $prev : $next;
}
echo date('Y-m-d', getClosestDate('2011-12-12', 1));
// prints 2010-12-13 (closest Monday to 2010-12-12)
echo date('Y-m-d', getClosestDate('2011-12-12', 4));
// prints 2010-12-09 (closest Thursday to 2010-12-12)
And by the way (and fortunately), December 14th 2011 is not a Monday. :)
I got it, here it goes:
function getClosestDay($date) {
$w = date("w", strtotime("-1 year", $date));
$week = date("w", $date);
$days = ($week - $w);
return date("Y-m-d l", strtotime($days . " days -1 year", $date));
}
echo getClosestDay(mktime(0, 0, 0, 12, 14, 2011));
Try this
function getClosestDay($date,$day=0) {
$days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
return strtotime('last ' . $days[$day], $date);
}
Here is a less elegant but tested function :
function getClosestDay($time,$dayOfTheWeek) {
$last_year=strtotime("last year",$time);
$next=strtotime("next $dayOfTheWeek",$last_year);
$last=strtotime("previous $dayOfTheWeek",$last_year);
$most_near = (min($next-$last_year,$last_year-$last) == ($next-$last_year)) ? $next : $last;
return $most_near;
}
Have you tried strtotime?
strtotime('-1 year',time());
Related
How can I calculate the day of month in PHP with giving month, year, day of week and number of week.
Like, if I have September 2013 and day of week is Friday and number of week is 2, I should get 6. (9/6/2013 is Friday on the 2nd week.)
One way to achieve this is using relative formats for strtotime().
Unfortunately, it's not as straightforward as:
strtotime('Friday of second week of September 2013');
In order for the weeks to work as you mentioned, you need to call strtotime() again with a relative timestamp.
$first_of_month_timestamp = strtotime('first day of September 2013');
$second_week_friday = strtotime('+1 week, Friday', $first_of_month_timestamp);
echo date('Y-m-d', $second_week_friday); // 2013-09-13
Note: Since the first day of the month starts on week one, I've decremented the week accordingly.
I was going to suggest to just use strtotime() in this fashion:
$ts = strtotime('2nd friday of september 2013');
echo date('Y-m-d', $ts), PHP_EOL;
// outputs: 2013-09-13
It seems that this is not how you want the calendar to behave? But it is following a (proper) standard :)
This way its a little longer and obvious but it works.
/* INPUT */
$month = "September";
$year = "2013";
$dayWeek= "Friday";
$week = 2;
$start = strtotime("{$year}/{$month}/1"); //get first day of that month
$result = false;
while(true) { //loop all days of month to find expected day
if(date("w", $start) == $week && date("l", $start) == $dayWeek) {
$result = date("d", $start);
break;
}
$start += 60 * 60 * 24;
}
var_dump($result); // string(2) "06"
I have a day value of 1 through 7 where 1 is Monday and 7 is Sunday.
I need to get a strtotime value of the appropriate day NEXT week.
For example:Today is Tuesday 13th November.
My day value is "2" so strtotime should return the appropriate value for Tuesday 20th November.
My day value is "1" so strtotime should return the appropriate value for Monday 19th November.
My day value is "5" so strtotime should return the appropriate value for Friday 23rd November.
I'm hoping this can be done with just a few built in PHP functions (strtotime(+1week+something))?
If not I will attempt to code some comparison checks!
Thanks!
function dayNextWeek($num) {
return date('Y-m-d', strtotime("+1 week +" . ($num - date('w')) . "days"));
}
And to test:
foreach (range(1, 7) as $i) {
echo $i . ' ' . dayNextWeek($i) . "\n";
}
OUTPUT
1 2012-11-19
2 2012-11-20
3 2012-11-21
4 2012-11-22
5 2012-11-23
6 2012-11-24
7 2012-11-25
Not tested extensively:
$givenDayNumber = 1; // Your value here
$date = new DateTime(); // Today (reference point)
$currentDayOfWeek = date('N'); // This is 1 = Monday, see php date manual for more options
$diff = $givenDayNumber- $currentDayOfWeek; // Difference between given number and todays number
$date->modify('+ '.$diff.' day'); // Subtract difference
$date->modify('+ 1 week'); // Add a week
echo $date->format('d/m/Y'); // Output
Codepad here for fiddling: http://codepad.org/7SylbJOX
function getNext($dow)
{
$now = intval(date('N'));
$toAdd = $dow - $now;
if($toAdd<=0)
{
$toAdd += 7;
}
return date('r', strtotime('+'.$toAdd.'day'));
}
Hopefully, This should work for you.
<?php
$array = array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday');
$your_value = 2;
$str = 'next ' . $array[$your_value -1];
echo date('D d M Y', strtotime($str));
?>
http://codepad.org/OIrzRxpl
Try:
$day_nxt_week = date('N', strtotime(date('Ymd') . '+1 week'));
print_r($day_nxt_week);
Demo
How can I get the same day of the same ISO-8601 week number but in the previous year using php?
I am familiar with extracting this soft of information from a time stamp. Is there a built-in way for me to go from day of week, week of year and year to time stamp?
You can use the combination of both date and strtotime like so:
// get the timestamp
$ts = strtotime('today');
// get year, week number and day of week
list($year, $week, $dow) = explode('-', date('Y-W-N', $ts));
// use the "YYYY-WXX-ZZ" format
$format = ($year - 1) . "-W$week-$dow";
echo date('Y-m-d', strtotime($format)), PHP_EOL;
You can do this with strtotime:
$now = time(); // Mon, 12 Nov 2012
$targetYear = date('Y', $now) - 1; // 2011
$targetWeek = date('\\WW-N', $now); // W46-1
$lastYear = strtotime($targetYear . $targetWeek); // Mon, 14 Nov 2011
Try this one:
$date = "2012-11-13";
echo getLastYearWeek($date);
function getLastYearWeek($date)
{
$last_year = date("Y-m-d W N", strtotime("-52 Weeks ".$date));
return $last_year;
}
Or just,
$last_year = date("Y-m-d W N", strtotime("-52 Weeks ".$date));
Use this for reference.
I think you are looking for mktime. have a look here http://php.net/manual/en/function.mktime.php
How to find a speciefic nearest day of the week in PHP if initially I have a date string like: 07.05.2010? For example, I want to find the nearest Sunday (or any day of the week). How can I implement this? Thanks
Just in case you wanted the nearest day rather than the next one, here is a way to do that.
$target = "Sunday";
$date = "07.05.2010";
// Old-school DateTime::createFromFormat
list($dom, $mon, $year) = sscanf($date, "%02d.%02d.%04d");
$date = new DateTime("$year/$mon/$dom -4 days");
// Skip ahead to $target day
$date->modify("next $target");
echo $date->format("d.m.Y");
And as of PHP 5.3, that middle portion can be simply
$date = DateTime::createFromFormat("!d.m.Y", $date)
->modify("-4 days")->modify("next $target");
This should do:
echo date('d.m.Y', strtotime('next Sunday', strtotime('07.05.2010')));
/**
*
* #param \DateTime $date
* #param $dayOfWeek - e.g Monday, Tuesday ...
*/
public function findNearestDayOfWeek(\DateTime $date, $dayOfWeek)
{
$dayOfWeek = ucfirst($dayOfWeek);
$daysOfWeek = array(
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
);
if(!in_array($dayOfWeek, $daysOfWeek)){
throw new \InvalidArgumentException('Invalid day of week:'.$dayOfWeek);
}
if($date->format('l') == $dayOfWeek){
return $date;
}
$previous = clone $date;
$previous->modify('last '.$dayOfWeek);
$next = clone $date;
$next->modify('next '.$dayOfWeek);
$previousDiff = $date->diff($previous);
$nextDiff = $date->diff($next);
$previousDiffDays = $previousDiff->format('%a');
$nextDiffDays = $nextDiff->format('%a');
if($previousDiffDays < $nextDiffDays){
return $previous;
}
return $next;
}
Alternatively you could create a map of what days of weeks are closer, e.g if you're after closest Monday to Wednesday, it would be faster to just find the previous Monday given that it's closer than the next Monday.
There are several answers posted and I keep seeing solutions that could give me either the next instance of a day of the week or the previous instance but not the closest. To address this, I came up with this function:
function closestDate($day){
$day = ucfirst($day);
if(date('l', time()) == $day)
return date("Y-m-d", time());
else if(abs(time()-strtotime('next '.$day)) < abs(time()-strtotime('last '.$day)))
return date("Y-m-d", strtotime('next '.$day));
else
return date("Y-m-d", strtotime('last '.$day));
}
Input: a day of the week ("sunday", "Monday", etc.)
Output: If I asked for the nearest "sunday" and today is:
"Sunday": I will get today's date
"Monday": I will get yesterday's date
"Saturday: I will get tomorrow's date
Hope this helps :)
strtotime is magical
echo date("d/m/y", strtotime("next sunday", strtotime("07.05.2010") ) );
This can be done using only strtotime() and a little trickery.
function findNearest($day, $date)
{
return strtotime("next $day", strtotime("$date - 4 days"));
}
echo date('d.m.Y', findNearest("Sunday", "07.05.2010")); // 09.05.2010
echo findNearest("Sunday", "07.05.2010"); // 1273377600
echo date('d.m.Y', findNearest("Sunday", "09.05.2010")); // 09.05.2010
echo findNearest("Sunday", "09.05.2010"); // 1273377600
echo date('d.m.Y', findNearest("Sunday", "05.05.2010")); // 02.05.2010
echo findNearest("Sunday", "05.05.2010"); // 1272772800
You can use Carbon library as well
$date = Carbon::create(2015, 7, 2); // 2015-07-02
// To get the first day of the week
$monday = $date->startOfWeek(); // 2015-06-29
$mondayTwoWeeksLater = $date->addWeek(2); // 2015-07-13
How can I get the date for monday and friday for the current week?
I have the following code, but it fails if current day is sunday or saturday.
$current_day = date("N");
$days_to_friday = 5 - $current_day;
$days_from_monday = $current_day - 1;
$monday = date("Y-m-d", strtotime("- {$days_from_monday} Days"));
$friday = date("Y-m-d", strtotime("+ {$days_to_friday} Days"));
Best solution would be:
$monday = date( 'Y-m-d', strtotime( 'monday this week' ) );
$friday = date( 'Y-m-d', strtotime( 'friday this week' ) );
These strtotime inputs work very well:
strtotime( "next monday" );
strtotime( "previous monday" );
strtotime( "today" );
strtotime( "next friday" );
strtotime( "previous friday" );
All you need to do is to wrap the logic inside some if statements.
This question needs a DateTime answer:-
/**
* #param String $day
* #return DateTime
*/
function getDay($day)
{
$days = ['Monday' => 1, 'Tuesday' => 2, 'Wednesday' => 3, 'Thursday' => 4, 'Friday' => 5, 'Saturday' => 6, 'Sunday' => 7];
$today = new \DateTime();
$today->setISODate((int)$today->format('o'), (int)$today->format('W'), $days[ucfirst($day)]);
return $today;
}
Usage:
var_dump(getDay('Monday')->format('l dS F Y'));
var_dump(getDay('Friday')->format('l dS F Y'));
Output:
string 'Monday 30th September 2013' (length=26)
string 'Friday 04th October 2013' (length=24)
See it working
i use :
$first_week_date = date('d F Y', strtotime('next Monday -1 week', strtotime('this sunday')));
$last_week_date = date('d F Y', strtotime('next Monday -1 week + 4 days', strtotime('this sunday')));
This really depends on how you define a week but I came up with this function that will give you the date for the nearest "monday" or "friday" (or any day for that matter):
function closestDate($day){
$day = ucfirst($day);
if(date('l', time()) == $day)
return date("Y-m-d", time());
else if(abs(time()-strtotime('next '.$day)) < abs(time()-strtotime('last '.$day)))
return date("Y-m-d", strtotime('next '.$day));
else
return date("Y-m-d", strtotime('last '.$day));
}
Input: a day of the week ("sunday", "Monday", etc.)
Output: If I asked for the nearest "sunday" and today is:
"Sunday": I will get today's date
"Monday": I will get yesterday's date
"Saturday: I will get tomorrow's date
Hope this helps :)
As the top answer suggests, using PHP's strtotime() function is the easiest way.
However, instead of using if statements as he suggests, you could simply reset back to the previous Sunday and grab the dates you require from there.
$monday = strtotime('next monday', strtotime('previous sunday'));
$friday = strtotime('next friday', strtotime('previous sunday'));
I needed a definition of the current week per ISO 8601. I want Monday to always be defined as the Monday that started this current week.
The following solution works excellent for me:
$monday = strtotime(date('o-\WW'));
$friday = strtotime("next friday",$monday);
For $monday, this method will always return the Monday that started this calendar week. unfortunately, this method relies on PHP 5.1 to parse the o date format.
To get any day of the week, you could try:
function time_for_week_day($day_name, $ref_time=null){
$monday = strtotime(date('o-\WW',$ref_time));
if(substr(strtoupper($day_name),0,3) === "MON")
return $monday;
else
return strtotime("next $day_name",$monday);
}
Usage:
time_for_week_day('wednesday');
time_for_week_day('friday',strtotime('2014-12-25'));
I was looking for a similar thing, except I wanted any Monday, not just this week. This is what I came up with:
function getSunday(DateTime $date){
$outdate = clone($date);
$day = $date->format("w"); // get the weekday (sunday is 0)
$outdate->sub(new DateInterval("P".$day."D")); // subtracting the weekday from the date always gives Sunday
return $outdate;
}
It accepts an arbitrary date and gives the Sunday. Then you can easily add back days to get Monday through Saturday.
get the current week
$week = [];
$saturday = strtotime('saturday this week');
foreach (range(0, 6) as $day) {
$week[] = date("Y-m-d", (($day * 86400) + $saturday));
}