I had this bug yesterday (August 31st) where the following printed out...
$timezone = new DateTimeZone('Europe/Helsinki');
$calendar_month_name = DateTime::createFromFormat('m', 9, $timezone)->format('F');
echo $calendar_month_name; // returns October
echo date('M'); // returns August
However, when the date changed to the 1st September, $calendar_month_name corrected itself.
Anyone know why this was? Thanks.
Edit I've turned my calendar back to be on the 31 Aug again, which is why echo date('M'); returns August.
Edit 2 Here is an example using date()
date_default_timezone_set('Europe/Helsinki');
echo date('F', mktime(0,0,0,9)); // returns October
In one line you are asking the name of the month 9 which is September.
On the last line you are asking the short name of the current month.
I think that this is what you intend, isn't?
$calendar_month_name = DateTime::createFromFormat('m', date('m'),$timezone)->format('F');
Cheers!
Related
To get the second Friday of next year I used second Friday of Januar next year, however, this returns the wrong date. (It's not only the second or Friday, this concerns every date in this fashion)
See following example
$FIRST_FRI_JAN_NEXT_YEAR_TEXT = 'second friday of january next year';
$jan1 = new DateTime($FIRST_FRI_JAN_NEXT_YEAR_TEXT ); // = 22-01-08 // wrong date
$FIRST_FRI_JAN_NEXT_YEAR_NUMBER = 'second friday of 2022-01';
$jan2 = new DateTime($FIRST_FRI_JAN_NEXT_YEAR_NUMBER); // = 22-01-14 // right date
Online Demo
Is there a reason for that or is this a bug?
It is not a bug. “Second Friday in January next year” is interpreted as “second Friday in January” of this year and “next year” as +1 year. With long expressions it is not always clear in which order they are processed. It is usually better to do this in several steps.
$jan2 = date_create('next year')->modify('second friday of january'); //2022-01-14
Trying to get the week number from a given date within PHP. For some reason various things I try seem to be a week off.
Looking at the following link we should be on week 3
http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php
Yet when I do the following I get week 2
echo "Weeknummer: " . date("W", strtotime("2016-01-17"));
I've also tried this code getting the same result, week 2
$date = new DateTime("2016-01-17");
$week = $date->format("W");
echo "Weeknummer: $week";
Any ideas why its seems to be a week behind and how I can fix that?
Thanks
We are, but today is the 19th (at least in my time-zone...).
You have hard-coded the 17th in your script and as you can see in the site that you mentioned, that is the last day of week 2.
The link you sent shows that 2016-01-17 is on week 2. See screenshot. In PHP the weeks start on Monday (you can read more in the docs)
It's because in mktime(), it goes like this:
mktime(hour, minute, second, month, day, year);
so try with the below code hope it's what you want
<?php
$ddate = "2016-01-17";
$duedt = explode("-", $ddate);
$date = mktime(0, 0, 0, $duedt[1], $duedt[2], $duedt[0]);
$week = (int)date('W', $date);
echo "Weeknummer: " . $week;
?>
also you can try github.com/briannesbitt/Carbon to maximize your skills in Date manipulation. For carbon you can do that by:
Carbon::createFromFormat('Y-m-d H', '2012-10-18')->format('W');
I need to create functions in PHP that let me step up/down given datetime units. Specifically, I need to be able to move to the next/previous month from the current one.
I thought I could do this using DateTime::add/sub(P1M). However, when trying to get the previous month, it messes up if the date value = 31- looks like it's actually trying to count back 30 days instead of decrementing the month value!:
$prevMonth = new DateTime('2010-12-31');
Try to decrement the month:
$prevMonth->sub(new DateInterval('P1M')); // = '2010-12-01'
$prevMonth->add(DateInterval::createFromDateString('-1 month')); // = '2010-12-01'
$prevMonth->sub(DateInterval::createFromDateString('+1 month')); // = '2010-12-01'
$prevMonth->add(DateInterval::createFromDateString('previous month')); // = '2010-12-01'
This certainly seems like the wrong behavior. Anyone have any insight?
Thanks-
NOTE: PHP version 5.3.3
(Credit actually belongs to Alex for pointing this out in the comments)
The problem is not a PHP one but a GNU one, as outlined here:
Relative items in date strings
The key here is differentiating between the concept of 'this date last month', which, because months are 'fuzzy units' with different numbers of dates, is impossible to define for a date like Dec 31 (because Nov 31 doesn't exist), and the concept of 'last month, irrespective of date'.
If all we're interested in is the previous month, the only way to gaurantee a proper DateInterval calculation is to reset the date value to the 1st, or some other number that every month will have.
What really strikes me is how undocumented this issue is, in PHP and elsewhere- considering how much date-dependent software it's probably affecting.
Here's a safe way to handle it:
/*
Handles month/year increment calculations in a safe way,
avoiding the pitfall of 'fuzzy' month units.
Returns a DateTime object with incremented month/year values, and a date value == 1.
*/
function incrementDate($startDate, $monthIncrement = 0, $yearIncrement = 0) {
$startingTimeStamp = $startDate->getTimestamp();
// Get the month value of the given date:
$monthString = date('Y-m', $startingTimeStamp);
// Create a date string corresponding to the 1st of the give month,
// making it safe for monthly/yearly calculations:
$safeDateString = "first day of $monthString";
// Increment date by given month/year increments:
$incrementedDateString = "$safeDateString $monthIncrement month $yearIncrement year";
$newTimeStamp = strtotime($incrementedDateString);
$newDate = DateTime::createFromFormat('U', $newTimeStamp);
return $newDate;
}
Easiest way to achieve this in my opinion is using mktime.
Like this:
$date = mktime(0,0,0,date('m')-1,date('d'),date('Y'));
echo date('d-m-Y', $date);
Greetz Michael
p.s mktime documentation can be found here: http://nl2.php.net/mktime
You could go old school on it and just use the date and strtotime functions.
$date = '2010-12-31';
$monthOnly = date('Y-m', strtotime($date));
$previousMonth = date('Y-m-d', strtotime($monthOnly . ' -1 month'));
(This maybe should be a comment but it's to long for one)
Here is how it works on windows 7 Apache 2.2.15 with PHP 5.3.3:
<?php $dt = new DateTime('2010-12-31');
$dt->sub(new DateInterval('P1M'));
print $dt->format('Y-m-d').'<br>';
$dt->add(DateInterval::createFromDateString('-1 month'));
print $dt->format('Y-m-d').'<br>';
$dt->sub(DateInterval::createFromDateString('+1 month'));
print $dt->format('Y-m-d').'<br>';
$dt->add(DateInterval::createFromDateString('previous month'));
print $dt->format('Y-m-d').'<br>'; ?>
2010-12-01
2010-11-01
2010-10-01
2010-09-01
So this does seem to confirm it's related to the GNU above.
Note: IMO the code below works as expected.
$dt->sub(new DateInterval('P1M'));
Current month: 12
Last month: 11
Number of Days in 12th month: 31
Number of Days in 11th month: 30
Dec 31st - 31 days = Nov 31st
Nov 31st = Nov 1 + 31 Days = 1st of Dec (30+1)
I'm kind of at a loss here. It seems as though somehow my code is missing a whole week at the end of 2009 and I've tried a couple different things.
My base function to get the start and end date for a week is below. Given a Year, Week and Day of the Week it gives you a date.
function datefromweeknr($aYear, $aWeek, $aDay)
{
$Days=array('xx','ma','di','wo','do','vr','za','zo');
//xx = Current Sun, ma = Mon ..... zo = Sun of the next Week
$DayOfWeek=array_search($aDay,$Days); //get day of week (1=Monday)
$DayOfWeekRef = date("w", mktime (0,0,0,1,4,$aYear)); //get day of week of January 4 (always week 1)
if ($DayOfWeekRef==0){
$DayOfWeekRef=7;
}
$ResultDate=mktime(0,0,0,1,4,$aYear)+((($aWeek-1)*7+($DayOfWeek-$DayOfWeekRef))*86400);
return $ResultDate;
}
Seemed to work completely fine until I realized that I was missing the week of December 27th 2009 to January 2nd 2010.
echo '<table border="1">';
for($i = 1; $i < 53; $i++){
if($i < 10){
$w = '0'.$i.'1';
}
else{
$w = $i.'1';
}
echo '<tr><td>Week#'.$i.' </td><td> '.date("Y-m-d",datefromweeknr(2009,$i,"xx")).' </td><td> '.date("Y-m-d",datefromweeknr(2009, $i,"za")).'</td><td> Week = '.date("W: Y-m-d",strtotime("2009W$w")).' </td></tr>';
}
echo '</table>';
It seems the 52nd week of the year ends on 2009-12-26 and the 1st week of the new year starts on 2010-01-03. I'm losing a whole week, No Bueno!
Anyone know what I'm doing wrong or can point me to a fool proof way of supplying a week number and a year to get me the start and end date of that week without losing any days in the process?
Check here:
http://www.onlineconversion.com/day_week_number.htm
If you enter 29 december 2009, so see that US and ISO/Europe give different week numbers (resp. 52 and 53).
Could this be related to your problem? Which standard do you dates conform too?
Edit:
From http://www.epochconverter.com/epoch/weeknumbers.php :
Week number according to the ISO-8601 standard, weeks starting on Monday. The first week of the year is the week that contains that year's first Thursday. The highest week number in a year is either 52 or 53.
Your question remainded me of a bug comment I read today on php.net:
In PHP 5 prior to 5.2.7, requesting a
given occurrence of a given weekday in
a month where that weekday was the
first day of the month would
incorrectly add one week to the
returned timestamp. This has been
corrected in 5.2.7 and later versions.
Which is irrevelent for now but I would suggest you to replace your calculations in datefromweeknr with strtotime calls. I'm pretty sure strtotime will fix your calculation bug.
So you could use something like:
strtotime('last Monday', $timestamp);
I have a simple situation where I have a user supplied week number X, and I need to find out that week's monday's date (e.g. 12 December). How would I achieve this? I know year and week.
Some code based mainly on previous proposals:
$predefinedYear = 2009;
$predefinedWeeks = 47;
// find first mоnday of the year
$firstMon = strtotime("mon jan {$predefinedYear}");
// calculate how much weeks to add
$weeksOffset = $predefinedWeeks - date('W', $firstMon);
// calculate searched monday
$searchedMon = strtotime("+{$weeksOffset} week " . date('Y-m-d', $firstMon));
An idea to get you started:
take first day of year
add 7 * X days
use strtodate, passing in "last Monday" and the date calculated above.
May need to add one day to the above.
Depending on the way you are calculating week numbers and the start of the week this may sometimes be out. (i.e. if the monday in the first week of the year was actually in the previous year!)
TEST THIS THOROUGHLY - but I've used a similar approach for similar calcualtions in the past.
This will solve the problem for you. It mainly derives from Mihail Dimitrov's answer, but simplifies and condenses this somewhat. It can be a one-line solution if you really want it to be.
function getMondaysDate($year, $week) {
if (!is_numeric($year) || !is_numeric($week)) {
return null;
// or throw Exception, etc.
}
$timestamp = strtotime("+$week weeks Monday January $year");
$prettyDate = date('d M Y');
return $prettyDate;
}
A couple of notes:
As above, strtotime("Monday January $year") will give you the timestamp of the first Monday of the year.
As above +X weeks will increment a specified date by that many weeks.
You can validate this by trying:
date('c',strtotime('Sunday Jan 2018'));
// "2018-01-07T00:00:00+11:00" (or whatever your timezone is)
date('c',strtotime('+1 weeks Sunday Jan 2018'));
// "2018-01-14T00:00:00+11:00" (or whatever your timezone is)
date('c',strtotime('+52 weeks Sunday Jan 2018'));
// "2019-01-06T00:00:00+11:00"
Due to reputation restriction i can't post multiple links
for details check
http://php.net/manual/en/function.date.php and http://php.net/manual/en/function.mktime.php
you can use something like this :
use mktime to get a timestamp of the week : $stamp = mktime(0,0,0,0,<7*x>,) {used something similar a few years back, so i'm not sure it works like this}
and then use $wDay = date('N',$stamp). You now have the day of the week, the timestamp of the monday should be
mktime(0,0,0,0,<7*x>-$wDay+1,) {the 'N' parameter returns 1 for monday, 6 for sunday}
hope this helps
//To calculate 12 th Monday from this Monday(2014-04-07)
$n_monday=12;
$cur_mon=strtotime("next Monday");
for($i=1;$i<=$n_monday;$i++){
echo date('Y-m-d', $cur_mon);
$cur_mon=strtotime(date('Y-m-d', strtotime("next Monday",$cur_mon)));
}
Out Put
2014-04-07
2014-04-14
2014-04-21
2014-04-28
2014-05-05
2014-05-12
2014-05-19
2014-05-26
2014-06-02
2014-06-09
2014-06-16
2014-06-23