What I Require
I have a certain list of datetimes. I want to get the first monday of each datetimes.
eg: Suppose the given datetimes are
2013-07-05 2013-08-05, 2013-09-13 etc.
I want to get the first monday of all these datetimes such that the output results in
2013-07-01, 2013-08-05, 2013-09-02 respectively
I am actually stuck with this using stftime.
strftime("%d/%m/%Y", strtotime("first Monday of July 2012"));
Using php Datetime class:
$Dates = array('2013-07-02', '2013-08-05', '2013-09-13');
foreach ($Dates as $Date)
{
$test = new DateTime($Date);
echo $test->modify('first monday')->format('Y-m-d');
}
<?php
function find_the_first_monday($date)
{
$time = strtotime($date);
$year = date('Y', $time);
$month = date('m', $time);
for($day = 1; $day <= 31; $day++)
{
$time = mktime(0, 0, 0, $month, $day, $year);
if (date('N', $time) == 1)
{
return date('Y-m-d', $time);
}
}
}
echo find_the_first_monday('2013-07-05'), "\n";
echo find_the_first_monday('2013-08-05'), "\n";
echo find_the_first_monday('2013-09-13'), "\n";
// output:
// 2013-07-01
// 2013-08-05
// 2013-09-02
the first monday would be within the first 7 days of a month,
DAYOFWEEK(date) returns 1=sunday, 2=monday, and so on
also see the hack#23
http://oreilly.com/catalog/sqlhks/chapter/ch04.pdf
I know this is an old question and my answer is not 100% solution for this question, but this might be usefull for someone, this will give "first Saturday of the given year/month":
date("Y-m-d", strtotime("First Saturday of 2021-08")); // gives: 2021-08-07
You can manipulate this in many ways.
obviously you can put "Second Saturday of year-month" and it will find that as well.
Works with PHP 5.3.0 and above (tested at https://sandbox.onlinephpfunctions.com/).
You could loop through the array of dates and then break out of the loop and return the $Date when you first encounter Monday
PHPFIDDLE
$Dates = array('2013-07-02', '2013-08-05', '2013-09-13');
foreach ($Dates as $Date)
{
$weekday = date('l', strtotime($Date));
if($weekday == 'Monday') {
echo "First Monday in list is - " . $Date;
break;
}
}
Output
First Monday in list is - 2013-08-05
Related
I'd like to calculate next billing date of Recurly plan in PHP.
There are 2 types of billing cycle: yearly | monthly.
I tried to use DateTime and DateInterval classes, but didn't get expected results.
<?php
$referenceTime = new \DateTime('2016-01-31');
$oneMonthLater = $referenceTime->modify('+1 month');
var_dump($oneMonthLater);
// public 'date' => string '2016-03-02 00:00:00.000000'
Adding one month to the 31st of Januray gives me the second of March and not the 29th (or 28th) of February as I would expect.
The same for the 31st of August:
<?php
$referenceTime = new \DateTime('2016-08-31');
$oneMonthLater = $referenceTime->modify('+1 month');
var_dump($oneMonthLater);
// public 'date' => string '2016-10-01 00:00:00.000000'
If yearly, I expect Feb 29, 2016 + 1 year => Feb 28, 2017
Thanks.
Try this, if date > 28 use last day of next month else use +1 month
$get_date = strtotime("31-01-2016");
$dt = explode("-",$get_date);
$dt = $dt[0];
var_dump(($dt > 28) ? date("d-m-Y", strtotime("31-01-2016 last day of next month")) : date("d-m-Y", strtotime("31-01-2016 +1 month")));
DEMO
You can call modify with PHP's DateTime object to calculate the next date relative to the current date. The following code shows how you would do it with your specific situation.
$next_bill_date = new DateTime();
switch($plan_interval_unit) {
case "year":
$next_bill_date->modify("last day of next month");
break;
case "month":
$next_bill_date->modify("last day of this month next year");
break;
}
May be something like that:
if (date('d') !== date('d', strtotime('+1 month'))
date ('Y-m-d H:i:s', strtotime('last day of next month'));
if (date('d') !== date('d', strtotime('+1 year'))
date ('Y-m-d H:i:s', strtotime('last day of this month next year'));
You can use PHP inbuilt strtotime() function
// One month from today
$date = date('Y-m-d', strtotime('+1 month'));
// One month from a specific date
$date = date('Y-m-d', strtotime('+1 month', strtotime('2016-12-06')));
function get_next_billing_date($now, $type, $format = 'Y-m-d')
{
$date = new DateTime($now);
$y = $date->format("Y");
$m = $date->format("m");
$d = $date->format("d");
if ($type == 'year') {
$y++;
if ($m == 2 && $d == 29) {
$d = 28;
}
} else if ($type == 'month') {
if ($m == 12) {
$y++;
$m = 1;
} else {
$m++;
}
$first_date = sprintf("%04d-%02d-01", $y, $m);
$last_day_of_next_month = date('t', strtotime($first_date));
if ($d > $last_day_of_next_month) {
$d = $last_day_of_next_month;
}
} else {
// not supported
return false;
}
$date->setDate($y, $m, $d);
return $date->format($format);
}
I'm trying to subtract 1 month from a date.
$today = date('m-Y');
This gives: 08-2016
How can I subtract a month to get 07-2016?
<?php
echo $newdate = date("m-Y", strtotime("-1 months"));
output
07-2016
Warning! The above-mentioned examples won't work if call them at the end of a month.
<?php
$now = mktime(0, 0, 0, 10, 31, 2017);
echo date("m-Y", $now)."\n";
echo date("m-Y", strtotime("-1 months", $now))."\n";
will output:
10-2017
10-2017
The following example will produce the same result:
$date = new DateTime('2017-10-31 00:00:00');
echo $date->format('m-Y')."\n";
$date->modify('-1 month');
echo $date->format('m-Y')."\n";
Plenty of ways how to solve the issue can be found in another thread: PHP DateTime::modify adding and subtracting months
Try this,
$today = date('m-Y');
$newdate = date('m-Y', strtotime('-1 months', strtotime($today)));
echo $newdate;
Depending on your PHP version you can use DateTime object (introduced in PHP 5.2 if I remember correctly):
<?php
$today = new DateTime(); // This will create a DateTime object with the current date
$today->modify('-1 month');
You can pass another date to the constructor, it does not have to be the current date. More information: http://php.net/manual/en/datetime.modify.php
I used this to prevent the "last days of month"-error. I just use a second strtotime() to set the date to the first day of the month:
<?php
echo $newdate = date("m-Y", strtotime("-1 months", strtotime(date("Y-m")."-01")));
if(date("d") > 28){
$date = date("Y-m", strtotime("-".$loop." months -2 Day"));
} else {
$date = date("Y-m", strtotime("-".$loop." months"));
}
$lastMonth = date('Y-m', strtotime('-1 MONTH'));
First change the date format m-Y to Y-m
$date = $_POST('date'); // Post month
or
$date = date('m-Y'); // currrent month
$date_txt = date_create_from_format('m-Y', $date);
$change_format = date_format($date_txt, 'Y-m');
This code minus 1 month to the given date
$final_date = new DateTime($change_format);
$final_date->modify('-1 month');
$output = $final_date->format('m-Y');
Try this,
$effectiveDate = date('2018-01'); <br>
echo 'Date'.$effectiveDate;<br>
$effectiveDate = date('m-y', strtotime($effectiveDate.'+-1 months'));<br>
echo 'Date'.$effectiveDate;
$currentMonth = date('m', time());
$currentDay = date('d',time());
$currentYear = date('Y',time());
$lastMonth = $currentMonth -1;
$one_month_ago=mkdate(0,0,0,$one_month_ago,$currentDay,$currentYear);
This could be rewritten more elegantly, but it works for me
I realize this is an old post, but I've been solving the same issue, and here is what I came up with to account for all the variability. This function is just trying to get relative dates, so same day of prior month, or last day of month if you are on the last day, regardless of exactly how many days a month has. So goal is given '2010-03-31' and subtract a month, we should output '2010-02-28'.
private function subtractRelativeMonth(DateTime $incomingDate): DateTime
{
$year = $incomingDate->format('Y');
$month = $incomingDate->format('m');
$day = $incomingDate->format('d');
$daysInOldMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
if ($month == 1) { //It's January, so we have to go back to December of prior year
$month = 12;
$year--;
} else {
$month--;
}
$daysInNewMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
if ($day > $daysInNewMonth && $month == 2) { //New month is Feb
$day = $daysInNewMonth;
}
if ($day > 29 && $daysInOldMonth > $daysInNewMonth) {
$day = $daysInNewMonth;
}
$adjustedDate = new \DateTime($year . '-' . $month . '-' . $day);
return $adjustedDate;
}
I have a problem,
$fridays = array();
$fridays[0] = date('Y-m-d', strtotime('first friday of this month'));
$fridays[1] = date('Y-m-d', strtotime('second friday of this month'));
$fridays[2] = date('Y-m-d', strtotime('third friday of this month'));
$fridays[3] = date('Y-m-d', strtotime('fourth friday of this month'));
$fridays[4] = date('Y-m-d', strtotime('fifth friday of this month'));
but there is no fifth friday. Some months have fifth fridays. How to check and not set the last item array?
$fifth = strtotime('fifth friday of this month');
if (date('m') === date('m', $fifth)) {
$fridays[4] = date('Y-m-d', $fifth);
}
You can do this using the PHP date function. Get the month you want in $timestamp and then do something like this:
<?php
function fridays_get($month, $stop_if_today = true) {
$timestamp_now = time();
for($a = 1; $a < 32; $a++) {
$day = strlen($a) == 1 ? "0".$a : $a;
$timestamp = strtotime($month . "-$day");
$day_code = date("w", $timestamp);
if($timestamp > $timestamp_now)
break;
if($day_code == 5)
#$fridays++;
}
return $fridays;
}
echo fridays_get('2011-02');
You can find a similar post about this: In PHP, how to know how many mondays have passed in this month uptil today?
I have a function to count fridays in a month to my very own application.... it could be helpful for someone.
function countFridays($month,$year){
$ts=strtotime('first friday of '.$year.'-'.$month.'-01');
$ls=strtotime('last day of '.$year.'-'.$month.'-01');
$fridays=array(date('Y-m-d', $ts));
while(($ts=strtotime('+1 week', $ts))<=$ls){
$fridays[]=date('Y-m-d', $ts);
}return $fridays;
}
I'm not on a machine that I could test this but what about something along the lines of....
if(date('Y-m-d', strtotime('fifth friday of this month')) > ""){
$fridays[4] = date('Y-m-d', strtotime('fifth friday of this month'));
}
The link below does exactly the same thing and will cover exactly what you are wanting todo without clunky if statements like above..
VERY Similar reading: read more...
the month will have 5 fridays only if it has 30 days and first friday is 1st or 2nd day of the month or if it has 31 days and the first friday is 1st, 2nd or 3rd day of the month, so you can make conditional statement based on this calculation for 5th friday
for($i=0;$i<=5;$i++)
{
echo date("d/m/y", strtotime('+'.$i.' week friday september 2012'));
}
I used this as the basis for my own solution:
$fridays = array();
$fridays[0] = date('d',strtotime('first fri of this month'));
$fridays[1] = $fridays[0] + 7;
$fridays[2] = $fridays[0] + 14;
$fridays[3] = $fridays[0] + 21;
$fridays['last'] = date('d',strtotime('last fri of this month'));
if($fridays[3] == $fridays['last']){
unset($fridays['last']);
}
else {
$fridays[4] = $fridays['last'];
unset($fridays['last']);
}
print_r($fridays);
I needed to get an array of every Friday in a month, even if there were 5 and this seemed to do the trick using the original question as my basis.
<?php //php 7.0.8
$offDays = array();
$date = date('2020-02');
$day= 'Friday';
$offDays[0] = date('d',strtotime("first {$day} of ".$date));
$offDays[1] = $offDays[0] + 7;
$offDays[2] = $offDays[0] + 14;
$offDays[3] = $offDays[0] + 21;
$offDays['last'] = date('d',strtotime("last {$day} of ".$date));
if($offDays[3] == $offDays['last']){
unset($offDays['last']);
}
else {
$offDays[4] = $offDays['last'];
unset($offDays['last']);
}
foreach($offDays as $off){
echo date('Y-m-d-D',strtotime(date($date."-".$off)));
echo "\n";
}
?>
Is there a way to find the day of the week in php with a particular date.
I don't mean
date('D', $timestamp);
I mean if I was to supply a date like 2010-10-21 it would return "third thursday".
Not directly, you need a helper function for that:
function literalDate($timestamp) {
$timestamp = is_numeric($timestamp) ? $timestamp : strtotime($timestamp);
$weekday = date('l', $timestamp);
$month = date('M', $timestamp);
$ord = 0;
while(date('M', ($timestamp = strtotime('-1 week', $timestamp))) == $month) {
$ord++;
}
$lit = array('first', 'second', 'third', 'fourth', 'fifth');
return strtolower($lit[$ord].' '.$weekday);
}
echo literalDate('2010-10-21'); // outputs "third thursday"
Working example:
http://codepad.org/PTWUocx9
strtotime() seems to understand the syntax. You just need to provide it with the first day of the month in question as a starting point.
echo date("d.m.Y", strtotime("third thursday", mktime(0,0,0,10,1,2010)));
// Will output October 21
echo date("d.m.Y", strtotime("third thursday", mktime(0,0,0,11,1,2010)));
// Will output November 18
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