Getting the last occurrence of a day/month in PHP - php

I'm wondering if there's an easy way (like using strtotime) whereby I can get the unix time for the last occurrence of a day/month combination. For example, if I was to ask for "1st of September" today (9th May 2012) I would get 1314835200 (1st Sep 2011), but if the code was to run again this October, I would get 1346457600 (1st Sep 2012), and the same if I ran it 1 year from now.
Being able to do it forwards as well as backwards would be a massive bonus.

$month = 9;
$day = 1;
$timestamp = mktime(0, 0, 0, $month, $day);
if ($timestamp > time()) {
$timestamp = mktime(0, 0, 0, $month, $day, date('Y') - 1);
}

Related

Convert month number to month name

I want to convert month number to the month name. I have tried the below code:
A.
$month = 01;
$monthName = date("M", mktime(0, 0, 0, $month);
B.
$month = 01;
$monthName = date("M", mktime(0, 0, 0, $month, 10));
C.
$month = 01;
$monthName = date("M", mktime(0, 0, 0, $month, 1, 2015));
Here is my questions:
(1) Are they perform same output? Which one should I choose?
(2) I don't understand the 10 after the $month variable. What does it means?
(3) Any other ways to convert month number to the month name except the A, B, C?
Do they perform the same output?
Most days, yes. However, if the current day is 31 and $month is a 30-day month, A will return the next month. February is problematic too, naturally.
Which one should I choose?
A is wrong
B is ok (I'd use 1 instead of 10 though)
C is too much
Choose B.
What does the 10 after the $month variable mean?
It's the day of the month of the date you're creating with mktime(). If you leave it out, PHP assumes you want the same as the current day of the month. That's why A is wrong (bug described above).
Any other ways?
function getShortMonthNameByNumber($monthNum)
switch ($monthNum) {
case 1:
return "Jan";
case 2:
return "Feb";
case 3:
return "Mar";
// etc
}
However, I'd stick with B.
Your code uses date("M"), which returns the short name of the month (Jan, Feb etc). If you want full names (January, February etc), use "F" instead of "M".
NOTE: NEVER write numbers with leading zeroes in source code, because this usually means octal (instead of decimal). In your examples, $month = 08 or $month = 09 would explode your script.
Without using mktme , use date()
echo date("F");// directly to get current month ie October
If you alerady have date and in that you want to extract month bane, use strrtotime() with date()
$date = "2015-09-11";
echo date("F",strtotime($date));// will echo September

Can't get last day of June with PHP

Comment is the output I'm seeing. Help!
echo date("Y-m-t", strtotime("2012-07-31 -1 month")); //2012-07-31
echo date("Y-m-t", strtotime("2012-07-31 -2 month")); //2012-05-31
July has 31 days, so it can't be processing it as August 1, right? Even if it were, the second line should work. Right?!
Thanks!
What's happening here is, "7-31" minus one month comes out as "6-31", which translates to "7-1", which - asking for the last day of the month - comes out as "7-31".
When you want to do month math, it's almost always, if not always, better to build the time using mktime.
$month = 7;
echo date("Y-m-t", mktime(0, 0, 0, $month - 1, 1, 2012)); //2012-06-30
Note that when doing month math in mktime, always give '1' as the day. Or really anything as long as it's 28 or lower.
You can do something like this:
$month = date('m') ;
$day = date('d') ;
$year = date('Y') ;
// ----
$current = mktime( 0, 0, 0, $month , $day, $year);
$yesterday = mktime( 0, 0, 0, $month , $day-1, $year);
$tomorrow = mktime( 0, 0, 0, $month , $day+1, $year);
// ----
echo '<pre>Current Day: '.date('Y-m-d', $current).'</pre>';
echo '<pre>Day Before: '.date('Y-m-d', $yesterday).'</pre>';
echo '<pre>Day After: '.date('Y-m-d', $tomorrow).'</pre>';
If you're looking for the last day of July:
$july = mktime( 0, 0, 0, 8, 1-1, 2012);
// Last Day of July: 2012-07-31
echo '<pre>Last Day of July: '.date('Y-m-d', $july).'</pre>';
Using mktime, just enter the first day of August and subtract one day.

Get current date and time form mktime in PHP

I have a problem with find the current date from past mktime. In PHP I find the current date using date("j");. Here I need, suppose my date was in the past year like mktime(0, 0, 0, 2, 1, 2008), then here how can I find the current date of this particular past month.
Either as #octern's solution, or you can do
$day = date('j', strtotime("-2 months"));
or
$day = date('j', strtotime('-30 days'));
depending on your need.
You may also want to refer to strtotime() manual.
Try this:
$date = getdate(mktime(0, 0, 0, 2, 1, 2008));
$day = $date['mday'];
Or just:
$day = date('j', mktime(0, 0, 0, 2, 1, 2008))

How do I get last year's start and end date?

How can I get last year's start and end date using PHP code? Is it possible?
The first day is always January 1, the last day is always December 31. You're really only changing the year attached to it. Depending on how you want the date formatted, you have a couple possibilities...
If you just want to display the physical date:
$year = date('Y') - 1; // Get current year and subtract 1
$start = "January 1st, {$year}";
$end = "December 31st, {$year}";
If you need the timestamp for both those dates:
$year = date('Y') - 1; // Get current year and subtract 1
$start = mktime(0, 0, 0, 1, 1, $year);
$end = mktime(0, 0, 0, 12, 31, $year);
Very simple stuff. You can manually specify which year if you wanted too. The premise is the same.
You can do it by using the below. Hope it helps someone.
//to get start date of previous year
echo date("d-m-y",strtotime("last year January 1st"));
//to get end date of previous year
echo date("d-m-y",strtotime("last year December 31st"));
start date of the year :
mktime(0,0,0,1,1,$year);
end date of the year :
mktime(0,0,0,1,0,$year+1);
Check this Stuff
$currentY = date('Y');
$lastyearS = mktime(0, 0, 0, 1, 1, $currentY-1 )."<br/>";
$lastyearE = mktime(0, 0, 0, 12, 31, $currentY-1 )."<br/>";
echo date('Y-m-d',$lastyearS)."<br/>";echo date('Y-m-d',$lastyearE);
Suppose if your current month is February or the month which has 30 days
echo date('Y-12-t', strtotime(date('Y-m-d'))); // if current month is february (2015-02-01) than it gives 2015-02-28
will give you inaccurate results
Solution:
So to get accurate result for the end date of an year, try the code below
$start_date = date("Y-01-01", strtotime("-1 year"));// get start date from here
$end_date = date("Y-12-t", strtotime($start_date));
(OR)
$last_year_last_month_date = date("Y-12-01", strtotime("-1 year"));
$end_date = date("Y-12-t", strtotime($last_year_last_month_date));

Get the First or Last Friday in a Month

I'm trying to write a calendar function like this
function get_date($month, $year, $week, $day, $direction)
{
....
}
$week is a an integer (1, 2, 3...), $day is a day (Sun, Mon, ...) or number, whichever is easier. The direction is a little confusing, because it does a different calculation.
For an example, let's call
get_date(5, 2009, 1, 'Sun', 'forward');
It uses the default, and gets the first Sunday in May ie 2009-05-03. If we call
get_date(5, 2009, 2, 'Sun', 'backward');
, it returns the second last Sunday in May ie 2009-05-24.
The language-agnostic version:
To get the first particular day of the month, start with the first day of the month: yyyy-mm-01. Use whatever function is available to give a number corresponding to the day of the week. Subtract that number from the day you are looking for; for example, if the first day of the month is Wednesday (2) and you're looking for Friday (4), subtract 2 from 4, leaving 2. If the answer is negative, add 7. Finally add that to the first of the month; for my example, the first Friday would be the 3rd.
To get the last Friday of the month, find the first Friday of the next month and subtract 7 days.
Perhaps it can be made quicker...
This was VERY interesting to code.
Please note that $direction is 1 for forward and -1 for backward to ease things up :)
Also, $day begins with a value of 1 for Monday and ends at 7 for Sunday.
function get_date($month, $year, $week, $day, $direction) {
if($direction > 0)
$startday = 1;
else
$startday = date('t', mktime(0, 0, 0, $month, 1, $year));
$start = mktime(0, 0, 0, $month, $startday, $year);
$weekday = date('N', $start);
if($direction * $day >= $direction * $weekday)
$offset = -$direction * 7;
else
$offset = 0;
$offset += $direction * ($week * 7) + ($day - $weekday);
return mktime(0, 0, 0, $month, $startday + $offset, $year);
}
I've tested it with a few examples and seems to work always, be sure to double-check it though ;)
PHP's built-in time functions make this simple.
http://php.net/manual/en/function.strtotime.php
// Get first Friday of next month.
$timestamp = strtotime('first fri of next month');
// Get second to last Friday of the current month.
$timestamp = strtotime('last fri of this month -7 days');
// Format a timestamp as a human-meaningful string.
$formattedDate = date('F j, Y', strtotime('first wed of last month'));
Note that we always want to make sure that we've defined the correct timezone for use with strtotime so that PHP has an understanding of where to compute the timestamp for relative to what time zone the machine thinks it's in.
date_default_timezone_set('America/New_York');
$formattedDate = date('F j, Y', strtotime('first wed of last month +1 week'));
strtotime() can help you. e.g. <?php
$tsFirst = strtotime('2009-04-00 next friday');
$tsLast = strtotime('2009-05-01 last friday');
echo date(DATE_RFC850, $tsFirst), " | ", date(DATE_RFC850, $tsLast);printsFriday, 03-Apr-09 00:00:00 CEST | Friday, 24-Apr-09 00:00:00 CEST
No need for calculations or loops - this is very easy to do with strtotime():
Find the the Nth or Last occurrence of a particular day of a particular a month:
/////////////////////////////////////////////////////////////////
// Quick Code
/////////////////////////////////////////////////////////////////
// Convenience mapping.
$Names = array( 0=>"Sun", 1=>"Mon", 2=>"Tue", 3=>"Wed", 4=>"Thu", 5=>"Fri", 6=>"Sat" );
// Specify what we want
// In this example, the Second Monday of Next March
$tsInMonth = strtotime('March');
$Day = 1;
$Ord = 2;
// The actual calculations
$ThisMonthTS = strtotime( date("Y-m-01", $tsInMonth ) );
$NextMonthTS = strtotime( date("Y-m-01", strtotime("next month", $tsInMonth) ) );
$DateOfInterest = (-1 == $Ord)
? strtotime( "last ".$Names[$Day], $NextMonthTS )
: strtotime( $Names[$Day]." + ".($Ord-1)." weeks", $ThisMonthTS );
/////////////////////////////////////////////////////////////////
// Explanation
/////////////////////////////////////////////////////////////////
// Specify the month of which we are interested.
// You can use any timestamp inside that month, I'm using strtotime for convenience.
$tsInMonth = strtotime('March');
// The day of interest, ie: Friday.
// It can be 0=Sunday through 6=Saturday (Like 'w' from date()).
$Day = 5;
// The occurrence of this day in which we are interested.
// It can be 1, 2, 3, 4 for the first, second, third, and fourth occurrence of the day in question in the month in question.
// You can also use -1 to fine the LAST occurrence. That will return the fifth occurrence if there is one, else the 4th.
$Ord = 3;
////////////////////////////////////////////////////////////////
// We now have all the specific values we need.
// The example values above specify the 3rd friday of next march
////////////////////////////////////////////////////////////////
// We need the day name that corresponds with our day number to pass to strtotime().
// This isn't really necessary = we could just specify the string in the first place, but for date calcs, you are more likely to have the day number than the string itself, so this is convenient.
$Names = array( 0=>"Sun", 1=>"Mon", 2=>"Tue", 3=>"Wed", 4=>"Thu", 5=>"Fri", 6=>"Sat" );
// Calculate the timestamp at midnight of the first of the month in question.
// Remember $tsInMonth is any date in that month.
$ThisMonthTS = strtotime( date("Y-m-01", $tsInMonth ) );
// Calculate the timestamp at midnight of the first of the FOLLOWING month.
// This will be used if we specify -1 for last occurrence.
$NextMonthTS = strtotime( date("Y-m-01", strtotime("next month", $tsInMonth) ) );
// Now we just format the values a bit and pass them to strtotime().
// To find the 1,2,3,4th occurrence, we work from the first of the month forward.
// For the last (-1) occurence,work we work back from the first occurrence of the following month.
$DateOfInterest = (-1 == $Ord) ?
strtotime( "last ".$Names[$Day], $NextMonthTS ) : // The last occurrence of the day in this month. Calculated as "last dayname" from the first of next month, which will be the last one in this month.
strtotime( $Names[$Day]." + ".($Ord-1)." weeks", $ThisMonthTS ); // From the first of this month, move to "next dayname" which will be the first occurrence, and then move ahead a week for as many additional occurrences as you need.
echo date('Y-m-d',strtotime('last friday'));
You can use mktime to retrieve the unix timestamp of the first day in the month:
$firstOfMonth = mktime(0, 0, 0, $month, 1, $year);
When you have the date of the first day of a certain month it's easy to retrieve the weekday for that date using date:
$weekday = date("N", $firstOfMonth);
From there it's rather easy to just step forward to get the date you're after.
function get_date($month, $year, $week, $day) {
# $month, $year: current month to search in
# $week: 0=1st, 1=2nd, 2=3rd, 3=4th, -1=last
# $day: 0=mon, 1=tue, ..., 6=sun
$startday=1; $delta=0;
if ($week < 0) {
$startday = date('t', mktime(0, 0, 0, $month, 1, $year)); # 28..31
$delta=1;
}
$start = mktime(0, 0, 0, $month, $startday, $year);
$dstart = date('w', $start)-1; # last of the month falls on 0=mon,6=sun
$offset=$day-$dstart; if ($offset<$delta){$offset+=7;}
$newday=$startday+$offset+($week*7);
return mktime(0, 0, 0, $month, $newday, $year);
}
This works for me, and based on the language-agnostic version :-)
Only too bad, I needed to do that delta-thing (for if the last day of the month is the wanted week-day, we do not need to subtract 7)
The same can be accomplished very elegantly using the DateTime class.
$time_zone = new DateTimeZone('Europe/Ljubljana');
$first_friday_of_this_month = new DateTime('first Friday of this month', $time_zone);
$last_friday_of_this_month = new DateTime('last Friday of this month', $time_zone);
echo $first_friday_of_this_month->format('Y-m-d'); # 2015-11-06
echo $last_friday_of_this_month->format('Y-m-d'); # 2015-11-27
Just find out what the first and last day of the month in question is (i.e. May 1, 2009 is a Friday and May 31, 2009 is a Sunday) I believe most PHP functions use Monday=0, Sunday=6, thus Friday=4, so you know that Sunday (6) - Friday (4) = 2, then 31-2 = 29, meaning the last friday of this month is on the 29th. For the first Friday, if the number is negative, add 7, if the number is 0, the month starts on Friday.
This seems to work perfect everytime; it takes any date provided and returns the date of the last friday of the month, even in case of 5 friday in the month.
function get_last_friday_of_month($inDate) {
$inDate = date('Y-m-24', strtotime($inDate));
$last_friday = date('Y-m-d',strtotime($inDate.' next friday'));
$next_friday = date('Y-m-d',strtotime($inDate.' next friday'));
if(date('m', strtotime($last_friday)) === date('m', strtotime($next_friday))){
$last_friday = $next_friday;
}else{
//
}
return $last_friday;
}
Below is the quickest solution and you can use in all conditions. Also you could get an array of all day of week if you tweak it a bit.
function findDate($date, $week, $weekday){
# $date is the date we are using to get the month and year which should be a datetime object
# $week can be: 0 for first, 1 for second, 2 for third, 3 for fourth and -1 for last
# $weekday can be: 1 for Monday, 2 for Tuesday, 3 for Wednesday, 4 for Thursday, 5 for Friday, 6 for Saturday and 7 for Sunday
$start = clone $date;
$finish = clone $date;
$start->modify('first day of this month');
$finish->modify('last day of this month');
$finish->modify('+1 day');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $finish);
foreach($period AS $date){
$result[$date->format('N')][] = $date;
}
if($week == -1)
return end($result[$weekday]);
else
return $result[$weekday][$week];
}
$date = DateTime::createFromFormat('d/m/Y', '25/12/2016');
# find the third Wednesday in December 2016
$result = findDate($date, 2, 3);
echo $result->format('d/m/Y');
I hope this helps.
Let me know if you need any further info. ;)

Categories