mktime() changes days when it should't [message #172414] |
Thu, 17 February 2011 00:43  |
TAXI
Messages: 3 Registered: February 2011
Karma: 0
|
Junior Member |
|
|
Hi,
I write this couse of http://bugs.php.net/bug.php?id=54005 - As you can
see Derik says it's not a bug (in PHP itself) and links me to here for
support.
P.S. Couse of Deriks last sentence I changed the script so that it
passes 0 as hour to mktime() but that doesn't change anything.
P.P.S. Sorry for my bad english. :)
|
|
|
|
|
Re: mktime() changes days when it should't [message #172418 is a reply to message #172416] |
Thu, 17 February 2011 04:12   |
TAXI
Messages: 3 Registered: February 2011
Karma: 0
|
Junior Member |
|
|
Am Thu, 17 Feb 2011 01:49:52 +0000
schrieb Denis McMahon <denis(dot)m(dot)f(dot)mcmahon(at)googlemail(dot)com>:
> On 17/02/11 00:51, TAXI wrote:
>> Sorry, I have forgotten someting:
>> Bevore somebody asks why I need this: I want to write a script which
>> does an action every month. For that I save the timestamp of the
>> last execution and now I need a save way to check if one month is
>> over. But couse different months doesn't have the same amount of
>> days I can't simply count the secounds 30 days have and calculate
>> with this.
>>
>> Am Thu, 17 Feb 2011 01:43:39 +0100
>> schrieb TAXI <taxi(at)a-city(dot)de>:
>>
>>> Hi,
>>> I write this couse of http://bugs.php.net/bug.php?id=54005 - As you
>>> can see Derik says it's not a bug (in PHP itself) and links me to
>>> here for support.
>>>
>>> P.S. Couse of Deriks last sentence I changed the script so that it
>>> passes 0 as hour to mktime() but that doesn't change anything.
>>>
>>> P.P.S. Sorry for my bad english. :)
>
> The best solution is probably using crontab to schedule your job to
> run at the same time each month, eg 03:27 on the 3rd
>
> Failing that, you could use a semaphore file and the getdate,
> filemtime and touch functions, like this:
>
> <?php
>
> $sf = "semaphore-file-name";
> $newmonth = false;
> $last = @filemtime($sf);
> if ($last) {
> $then = getdate($last);
> $now = getdate();
> if ($then["mon"] != $now["mon"]) {
> $newmonth = true;
> }
> }
> else {
> $newmonth = true;
> }
>
> if ($newmonth) {
> touch($sf) or die "unable to modify file\n";
> // do once a month stuff
> }
>
> ?>
>
> Rgds
>
> Denis McMahon
Thank you, but that's not what I need. Your script would execute the
action at the first day of every month.
I want it exactly after one month, so when it's executed today the
first time the next execution should be the 17.03.2011, then the 17.04.
and so on. But the execution of the first time isn't static, too.
|
|
|
Re: mktime() changes days when it should't [message #172423 is a reply to message #172414] |
Thu, 17 February 2011 09:33   |
alvaro.NOSPAMTHANX
Messages: 277 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
El 17/02/2011 1:43, TAXI escribió/wrote:
> I write this couse of http://bugs.php.net/bug.php?id=54005 - As you can
> see Derik says it's not a bug (in PHP itself) and links me to here for
> support.
>
> P.S. Couse of Deriks last sentence I changed the script so that it
> passes 0 as hour to mktime() but that doesn't change anything.
The test code in your bug report is really hard to follow but you appear
to be trying to perform date calculation by adding raw amounts of
seconds and months.
That might be useful if time was the same all around Earth, days always
had the same amount of seconds and years always had the same amount of
days. Unluckily, none of these statements are true.
Time calculations are harder than you think. I suggest you have a look
at the relative formats provided by strtotime():
http://es.php.net/strtotime
http://es.php.net/manual/en/datetime.formats.relative.php
> I think the problem with february is that mktime() doesn't know that february only has 28 days?
See the day parameter at http://es.php.net/mktime
«The number of the day relevant to the end of the previous month. Values
1 to 28, 29, 30 or 31 (depending upon the month) reference the normal
days in the relevant month. Values less than 1 (including negative
values) reference the days in the previous month, so 0 is the last day
of the previous month, -1 is the day before that, etc. Values greater
than the number of days in the relevant month reference the appropriate
day in the following month(s).»
An example:
echo date('Y-m-d H:i:s', mktime(0, 0, 0, 2, 31, 2011));
.... prints 2011-03-03 00:00:00
--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://borrame.com
-- Mi web de humor satinado: http://www.demogracia.com
--
|
|
|
|
|
Re: mktime() changes days when it should't [message #172468 is a reply to message #172414] |
Sat, 19 February 2011 23:53  |
Thomas 'PointedEars'
Messages: 701 Registered: October 2010
Karma: 0
|
Senior Member |
|
|
TAXI wrote:
^^^^
Who?
> I write this couse of http://bugs.php.net/bug.php?id=54005 - As you can
> see Derik says it's not a bug (in PHP itself) and links me to here for
> support.
>
> P.S. Couse of Deriks last sentence I changed the script so that it
> passes 0 as hour to mktime() but that doesn't change anything.
Your approach is bogus, indeed: It will in at least 11 of 12 cases not yield
the date of the last day of the month, since there are months with 28, 29
(February), 30 (April, June, September, November), and 31 days (the rest)¹;
but 1 + 28, for which you could have simply passed 29, will only ever yield
a date of 29 (no overflow) or 1 (overflow in February in a non-leap year).
To determine the last day of a month (which is what you *really* wanted to
do, but did not ask), pass 0 for the day-of-month of the *next* month, then
retrieve the date:
/* 1970 CE was not a leap year, since it was not divisible by 4: "28" */
echo date('d', mktime(0, 0, 0, 3, 0, 1970)) . "\n";
/*
* 2000 was a leap year, since it was divisible by 4 and by 100,
* but also by 400: "29"
*/
echo date('d', mktime(0, 0, 0, 3, 0, 2000)) . "\n";
/* and so was 2004 (divisible by 4), so 2004-02 also had "29" days */
echo date('d', mktime(0, 0, 0, 3, 0, 2004)) . "\n";
/*
* 2100 will not be a leap year, since it is divisible by 4 and by 100,
* but not by 400; but dates after 2038-01-19 03:14:07.999 UTC are
* unsupported by 32-bit timestamps so the result is necessarily wrong:
* "01"
*/
echo date('d', mktime(0, 0, 0, 3, 0, 2100)) . "\n";
RTFM: <http://php.net/mktime>
PointedEars
___________
¹ Whenever you are unsure which are which, there is ─ quite literally ─
a rule of thumb I have learned as a child: Make a fist and count the
months along the ridges of the hands, from the left to right. The peaks
represent the months with 31 days, the valleys with 30 days or less.
(So the peaks at the index fingers represent July and August, both of
which have 31 days.)
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
|
|
|