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").
Related
I'm working on a PHP function which calculates holidays:
function holidays($country = 1, $timespan_start = 0, $timespan_end = 0)
The holidays are returned as timestamps in an array.
Since I have to calculate dates like the first Monday of February, I tried strtotime("first monday february $year") and I've discovered that this does not work for 2010, since 02/01/2010 is a Monday - I get February 8th instead.
This bug is actually mentioned in the change log:
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.
But I'm using PHP 5.3.8.
Why am I experiencing this error?
Looks like you are just missing an "of":
echo date('Y-m-d', strtotime('first monday of february 2010'));
will give the expected result. See the PHP Manual on Relative dates for the various input formats.
Depending on your version of PHP the 'of' statement may or may not work. As another solution try:
echo date('Y-m-d',strtotime('monday February 2010'));
will return the first monday of February 2010. Works for all days as well.
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
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
I'm trying to convert a date to a string by using the toString('dd MMMM YYY') function.
But here, this isn't working.
Here is my code:
$date_start = new Zend_Date(strtotime($this->startdate));
echo($date_start);
The result is: 31 Dec 2012 00:00:00
$date_input = $date_start->toString('dd MMMM YYY');
echo($date_input);
The result is: 31 December 2013
What do I have to do to obtain 31 December 2012 ?
This is a known issue described here: http://framework.zend.com/issues/browse/ZF-5297
Note that the default ISO format differs from PHP's format which can be irritating if you have not used in previous. Especially the format specifiers for Year and Minute are often not used in the intended way.
For year there are two specifiers available which are often mistaken. The Y specifier for the ISO year and the y specifier for the real year. The difference is small but significant. Y calculates the ISO year, which is often used for calendar formats. See for example the 31. December 2007. The real year is 2007, but it is the first day of the first week in the week 1 of the year 2008. So, if you are using 'dd.MM.yyyy' you will get '31.December.2007' but if you use 'dd.MM.YYYY' you will get '31.December.2008'. As you see this is no bug but a expected behaviour depending on the used specifiers.
Use "yyy" instead of "YYY".
Use yyy instead of YYY.
YYY is the ISO-8601 date, which is different from a calendar date.
http://framework.zend.com/manual/1.12/en/zend.date.constants.html
I am encountering a slightly frustrating problem and I have a feeling there is a simple solution to it. When I pass the same UNIX timestamp to the PHP date and MySQL FROM_UNIXTIME methods they are returning two very different dates. I would like to return a value from MySQL that matches the one returned by PHP.
Here is the code I am currently using along with it's output. The timestamp provided represents the date Tue, 01 Jan 2013 (01/01/2013). Also for reference, here are the format values.
MySQL Format
%j = Day of year (001..366).
%m = Month, numeric (00..12).
%y = Year, numeric (two digits).
PHP Format
z = The day of the year starting from 0 (0 through 365).
m = Numeric representation of a month, with leading zeros (01 through 12).
y = A two digit representation of a year (Examples: 99 or 03).
MySQL Query
SELECT FROM_UNIXTIME(1357018200, '%j-%m-%y');
-> 366-12-12
PHP Code
echo date('z-m-y', 1357018200);
-> 0-01-13
Any help would be greatly appreciated, thanks for your time. :)
Other Information
MySQL Version: 5.5.23
MySQL system_time_zone: CDT
MySQL time_zone: SYSTEM
PHP date_default_timezone_get: America/Chicago (CDT)
Your PHP and MySQL aren't agreeing on the time. Using the time converter at:
http://www.4webhelp.net/us/timestamp.php?action=stamp&stamp=1357018200&timezone=-6
gives the result "Monday, December 31st 2012, 23:30:00 (GMT -6)" so your PHP is giving the wrong result. Although you've given the timezone that PHP is running in, can you double check by running:
date_default_timezone_set ("America/Chicago");
echo date('z-m-y', 1357018200)."\r\n";
Which should give "365-12-12".
I guess it's possible either something is setting the timezone incorrectly somewhere else or possibly that "America/Chicago (CDT)" is an old setting in your php.ini file from a previous version of PHP.
Looking at the list of allowed timezone values from http://php.net/manual/en/timezones.america.php there is no "America/Chicago (CDT)" listed, so you should figure out where it's getting set to that bogus value as it may cause other issues.
Once you've got your timezone issues sorted out, the answer to your actual question is:
function sqlStyleDate($timestamp){
$dayOfYear = date("z", $timestamp) + 1;
$year = date("y", $timestamp);
$month = date("n", $timestamp);
$result = "$dayOfYear-$year-$month";
return $result;
}
echo sqlStyleDate(1357018200)."\r\n";
That will convert PHPs 0-365 day of year, to be the same as MySQL's 1-366 day of year.