Can someone kindly explain me why these two give different results?
I execute this with PHP.
date("YW",mktime(0, 0, 0, 3, 22 , 2013)); // outputs 201312
And when I execute this with MySQL
SELECT YEARWEEK(now()); // outputs 201311
You need to specify mode 3 on the mysql YEARWEEK call:
SELECT YEARWEEK(now(),3);
The PHP date() placeholder W returns the week number according to the ISO 8601 specification. That means weeks start on Monday (not Sunday), the first week of the year is number 1 (not 0), and that week is the first one that with more than half its days in the new year (so it has to be January by Thursday). According to the documentation for the MySQL WEEK function, that combination of options is mode 3.
Also, to pull Alles's note into the accepted answer because it's important: the placeholders Y and W don't go together. If you want the year that goes with the ISO week number, you should use o instead of Y. For example, consider the week starting on Monday, December 29th, 2014:
date('YW', mktime(0,0,0,12,29,2014)); #=> 201401 : 1st week of 2014??
date('oW', mktime(0,0,0,12,29,2014)); #=> 201501 : better
Please be aware that YEARWEEK('2012-01-01', 3) => 201152 while the PHP "YW" will give 201252. The year in the result may be different from the year in the date argument for the first and the last week of the year. (i.e. the year in the YEARWEEK is the year of the Monday of the week and not the year of the date being used to calculate).
In order to get the right result, you need to do
date("oW",mktime(0, 0, 0, 1, 1, 2012)); // outputs 201152
as "o" gives you the Year the week belongs to.
I hope this helps.
YEARWEEK takes a second (optional) parameter that specifies the range of the week [0- 53] or [1-53]).
This function returns the week number for date. The two-argument form
of WEEK() enables you to specify whether the week starts on Sunday or
Monday and whether the return value should be in the range from 0 to
53 or from 1 to 53. If the mode argument is omitted, the value of the
default_week_format system variable is used.
while date(W) is an ISO8601 date that is always in the range [01-53]. Therefore my guess is that by default YEARWEEK is using the [0-53] range.
So, if you want to get the same result try using 1 as the second parameter for YEARWEEK
Related
This question already has answers here:
strtotime on incorrect dates
(2 answers)
Closed 5 years ago.
I have been working in PHP Development for 5 years but never seen this type of error before.
I have a date which is the last day of the month and I am going to change its format with using below code :
$data['toDate'] = "2017-04-31";
echo $data['toDate']." : ".date('d-m-Y',strtotime($data['toDate']))." ### ";
die;
It outputs :
2017-04-31 00:00:00 : 01-05-2017 ###
I am working on PHP version 5.6.25.
Is there anyone can help me in this??
The 31th April don't exist. Because of that PHP going to the day after the 30th April
April only has 30 days, so it's actually correcting the date your using. The 31st would really be the 1st of May.
Its wrong with input, not with date().
$data['toDate'] = "2017-04-31";// no 31st in 4th(April) month
echo $data['toDate'] ." : ". date('d-m-Y',strtotime($data['toDate']))." ### ";
die;
Its just showing up next date which is 01-05-2017
tl;dr
04-31 is valid but not technically a date in April, since April only has 30 days and thus strtotime() yields 05-01.
Documentation
If you look at the documentation for strtotime() you will see the first parameter is:
time
A date/time string. Valid formats are explained in Date and Time Formats.
If you follow the link for the date and time formats and go to Date Formats you will see:
Thus for the date format (I.e. DD), 01-31 is valid (since a 3 can only be followed by a 0 or 1) despite the month. Depending on the supplied month and date value the date will be adjusted.
Also found in the notes on that same page:
Note:
It is possible to over- and underflow the dd and DD format. Day 0 means the last day of previous month, whereas overflows count into the next month. This makes "2008-08-00" equivalent to "2008-07-31" and "2008-06-31" equivalent to "2008-07-01" (June only has 30 days).1
Hence 04-31 is valid but overflows.
Additionally, in the User Contributed Notes section, the note by Mirek at 2015-04-01 01:14 might be useful/interesting:
Note: the day (dd or DD) is first checked for range 0..31 and only if it fits, the overflow and underflow mechanism may apply. If not, strtotime() simply returns false.
If you need unlimited over/underflow for date calculations (for example 2015-01-40 to 2015-02-09), use mktime() instead.2
1http://php.net/manual/en/datetime.formats.date.php
2http://php.net/manual/en/datetime.formats.date.php#Hcom117014
I'm using a time-based token using as seed the year and the number of week, example:
$token = md5($salt + gmdate('YW'));
Yesterday sunday the token got broken, the time on server and client was synced (on time).
Checking with the interactive cli tool of php, I realized the number of week returned by PHP is "01" (zero-one).
ex:
Interactive mode enabled
php > echo gmdate('W');
01php > echo date('W');
01php >
At the moment of this post, it is 29-dec at 21:58 UTC (9:58 pm) and this was broken since yesterday at 00:00 UTC.
Tested on php 5.5.9
Instead of format character Y, use o, which will return ISO-8601 year number.
This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0)
Example:
echo gmdate('oW');
Probably due to different timezone or locale settings. In some countries/standards sunday is considered as the first day of the week.
WEEK(date[mode]);
date = a date value. mode = An integer indicating the starting of
the week.
The default arugment is 0 which is sunday, setting this to 1 will be
monday, 2 tuesday and so on.
week(date,1);
Quoted from How do I set first day of the week to Monday when using Week(Date) in PHP/MySQL?
I found the problem.
In the ISO-8601 standar, this week is the 01 of 2015, and not the last of 2014. This can be check here:
The problem is, I on the client use a function returns 2015 and 1 (And I from PHP use 2014 and 01 "201401" !== "20151").
I don't understand why PHP and MySQL give two different values of month number for some particular date:
echo date('W', strtotime('2014-04-16'));
this gives 16
while this:
SELECT WEEK('2014-04-16')
gives 15
Could anyone help me?
Thanks
Try using SELECT WEEK('2014-04-16',3) for returning a PHP compatible value. The ,3 indicates that this has weeks starting on Mondays and weeks numbered 1-53.
Play with MySQL WEEK() function parameters: see here
For the same result you should use mode parameter in MYSQL function with value of 4.
PHP
string date ( string $format [, int $timestamp = time() ] )
W ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0)
MYSQL
WEEK(date[,mode])
For mode values with a meaning of “with 4 or more days this year,” weeks are numbered according to ISO 8601:1988:
I need to filter some results of this week and next week. But it gives me no result for this week.
I have records with the date "2013-10-25 12:00:00" and "2013-10-22 12:00:00".
I am getting current week by date('W', time()) in php and using WEEK(tdi.due_at) in mysql query.
date('W', time()) return 43 which is current week number.
but WEEK(tdi.due_at) returns 42 why?
MySQL WEEK() has also an optional mode parameter that sets the condition when the first week of a year starts.
Why not you subtract -1 from PHP date('W') - 1.
or add +1 to MySQL WEEK(tdi.due_at) + 1.
PHP Indexed with 1 and MySQL starts index with 0 like JavaScript does.
I'm trying to get the number of the month of the year by the number of a week of the year and the year.
So for example week 1 is in january and returns 1, week 6 is in february so I want 2.
I tried to go with date_parse_from_format('W/Y') but had no success (it's giving me errors).
Is there any way to go with date_parse_from_format() or is there another way?
print date("m",strtotime("2011-W6-1"));
(noting that in 2011, January has six weeks so week 6 (by some definitions) is in month 1).
Just wanted to add a note for the first answer, the week number should be 01-09 for Weeks 1 through 9 (it will always give month 1 if you don't add the leading zero)
date("m",strtotime("2011-W06-1"));
Using PHP DateTime objects (which is the preferred way of dealing with dates see links below for more info) you can accomplish it this way:
$dateTime = new \DateTime();
$dateTime->setISODate($year,$week);
$month = $dateTime->format('n');
Note that the following will not work as week "W" is not a supported format:
$month = \DateTime::createFromFormat("W/Y ", "1/2015")->format('n');
The format used by this method is the same supported by the function you where trying to use date_parse_from_format, hence the errors.
Why PHP DateTime Rocks
DateTime class vs. native PHP date-functions
strtotime notes
PHP/Architect's Guide to Date and Time Programming (Chapter 2)
Something like this will do, this is also tested and works:
function getMonthByNumber($number,$year)
{
return date("F",strtotime('+ '.$number.' weeks', mktime(0,0,0,1,1,$year,-1)));
}
echo getMonthByNumber(27,2011);
Hope this helps