FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » mktime() changes days when it should't
Show: Today's Messages :: Polls :: Message Navigator
Switch to threaded view of this topic Create a new topic Submit Reply
mktime() changes days when it should't [message #172414] Thu, 17 February 2011 00:43 Go to next message
TAXI is currently offline  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 #172415 is a reply to message #172414] Thu, 17 February 2011 00:51 Go to previous messageGo to next message
TAXI is currently offline  TAXI
Messages: 3
Registered: February 2011
Karma: 0
Junior Member
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. :)
Re: mktime() changes days when it should't [message #172416 is a reply to message #172415] Thu, 17 February 2011 01:49 Go to previous messageGo to next message
Denis McMahon is currently offline  Denis McMahon
Messages: 634
Registered: September 2010
Karma: 0
Senior Member
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
Re: mktime() changes days when it should't [message #172418 is a reply to message #172416] Thu, 17 February 2011 04:12 Go to previous messageGo to next message
TAXI is currently offline  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 Go to previous messageGo to next message
alvaro.NOSPAMTHANX is currently offline  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 #172425 is a reply to message #172418] Thu, 17 February 2011 13:03 Go to previous messageGo to next message
Denis McMahon is currently offline  Denis McMahon
Messages: 634
Registered: September 2010
Karma: 0
Senior Member
On 17/02/11 04:12, TAXI wrote:

> 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.

It's certainly the base of what you need. You just need to play around
with the if clause that decides if it is one month since the script was
last run.

If you can't work out the logic involved to do that, then you're not
ready to program computers yet.

Did you look at the php.net documentation for mktime()? Did you consider
adapting the if clause to include a check for day of month?

crontab is still the better solution if you want a job to run at exactly
the same time every month.

Rgds

Denis McMahon
Re: mktime() changes days when it should't [message #172433 is a reply to message #172415] Thu, 17 February 2011 22:34 Go to previous messageGo to next message
Captain Paralytic is currently offline  Captain Paralytic
Messages: 204
Registered: September 2010
Karma: 0
Senior Member
On Feb 17, 12:51 am, TAXI <t...@a-city.de> 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 <t...@a-city.de>:
>
>
>
>> Hi,
>> I write this couse ofhttp://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. :)

When I need to do this (and I had to within the last 2 weeks), I use a
MySQL table to store the run date and then use the mysql date
functions to calculate the next date on which I need to run (it is
simple to add a month in MySQL). I then run a small cron job daily
which checks the table to see if it is required to do anything that
day. If not the job just exits.

However you need to think about how what you seem to want to do can be
achieved. What happens if the first event occurs on the 29th, 30th or
31st of a month. What will you expect ro happen when the next
scheduled date should be in a month that doesn't have a 29th, 30th or
31st? If you can state this I can help you more. As it is your
requirement is incomplete and impossible to fulfil.
Re: mktime() changes days when it should't [message #172468 is a reply to message #172414] Sat, 19 February 2011 23:53 Go to previous message
Thomas 'PointedEars'  is currently offline  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
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Almost done - Just need a way to assign a variable
Next Topic: Grate opportunities to earn money from online!
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Wed Nov 27 00:51:08 GMT 2024

Total time taken to generate the page: 0.03085 seconds