PHP - date() reduction bug? - php

I am using a unix time stamp as the base of my starting date for use in a date ranged query. The start date is not the problem, for the purpose of this example i will use the following time stamp: 1228089600 (01 December 2008 00:00:00).
For use in my query I needed to easily figure out the last day of any given month to the last second so..
date('o-m-d G:i:s',mktime(0, 0, -1, date("m",1228089600)+1, 1, date("o",1228089600)));
This method has been working fine for me for every other month except December.. By taking the start date, adding a whole month (01 January 2009 00:00:00) then taking away 1 second I was expecting to result in the date I required (31 December 2008 23:59:59). However it appears the year is being calculated correctly for the additional month, but not for the subtracting second as the date returned is 31 December 2009 23:59:59.
As I say, this method has worked great until I discovered this problem. But it's a problem I am unable to figure out the cause of or simple solution to..
Any help is greatly appreciated.

This happens because:
flag 'o' - 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)
So in your case happens this:
Date generated is 1st January 2009
Date is decremented with 1 second (so you get 31st December 2008)
But as goes the description above - the week belongs to 2009 so 2009 is returned instead of 2008
(belongs to year means: More days of the week are in 2009 than in 2008 - in the case above: 3 days are in 2008 (mon, tue, wed - 29th,30th,31st) and 4 are in 2009 (thu, fri, sat, sun - 1st,2nd,3rd,4th))

That does indeed seem to be a bug with how mktime() handles a "months" value greater than 12.
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 2, 1, 2008));
2008-01-31 23:59:59
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 3, 1, 2008));
2008-02-28 23:59:59
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 1, 1, 2008));
2007-12-31 23:59:59
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 13, 1, 2008));
2009-12-31 23:59:59
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 13, 1, 2007));
2008-12-31 23:59:59
Your best bet right now is probably to just check the output from date('m', ...)+1 yourself and special-case the calculation if the result is 13.

I did add some exceptions to reduce the year if the month was January, however i also had another date range which is built at the same stage which is used with GA api. I was surprised to see this date range was fine despite the method being similar. The difference being..
Problematic:
date('o-m-d G:i:s',mktime(0, 0, -1, date("m",1228089600)+1, 1, date("o",1228089600)));
Fine:
date('Y-m-d G:i:s',mktime(0, 0, -1, date("m",1228089600)+1, 1, date("Y",1228089600)));
So making the switch appears to have solved the problem.
Hopefully all this may be of use to someone, someday.

Try this:
$start = 1228089600;
$number_of_days_in_month = date('t', $time);
$end = strtotime('+' . $number_of_days_in_month . ' days', $start) - 1;
// subtract one second to get 23:59:59 or don't to get 00:00:00.
// Also note that there can be a leap second.
// $end = $start + $number_of_days_in_month * 86400 - 1; would probably work as well.
echo date('o-m-d G:i:s', $end);

Related

PHP How do I find the number of days until the next January 1 (without specifying the year)?

How do I find out the number of days until the next January 1 without specifying a year?
I always want to know how many days until the next January 1, so I don't want to say "how many until Jan 1, 2020" or I'll need to reset my variable every year.
You can use DateTime objects to do the math. Create one object which is today, and another which is January 1, to which we then add a year, and then take the difference:
$today = new DateTime();
$jan1 = new DateTime('January 1');
$jan1->modify('+1 year');
$days = $today->diff($jan1)->days;
echo "$days days until January 1\n";
Output (on December 6)
25 days until January 1
Demo on 3v4l.org

Wrong php date('t')

I have this script
echo 'giorni mese: '.date('t', $mese_start).' - mese start: '.$mese_start;
output is:
giorni mese: 31 - mese start: 11
But november doesn't have 30 days?
What am I missing?
Update:
right, thank you.
The second argument to date() is a timestamp, which is the number of seconds since 1970-01-01 00:00:00 UTC. The value of $mese_start is 11. So that timestamp is 1970-01-01 00:00:11 UTC, and January has 31 days.
If you want to use $mese_start as a month number rather than a timestamp, you can use mktime() to create a timestamp from a particular date:
$ts = mktime(0, 0, 0, $mese_start);
echo 'giorni mese: '.date('t', $ts).' - mese start: '.$mese_start;
The second argument of date is interpreted as a Unix timestamp, not a month. You are passing "11" which equals some time on January 1st, 1970. And January has 31 days.
You could either construct a valid timestamp for November or use cal_days_in_month:
echo cal_days_in_month(CAL_GREGORIAN, 11, 2018); // 30

converting negative integer to datetime gmt-3 and mktime - php

EDITED:
THIS PART IS WHAT I NEED TO SOLVE:
I have a negative integer like: -10800 and I wish to convert this at my local time, which is Buenos Aires (gmt -3).
I'm using an online converter to check what date it is so I can check the results: www.4webhelp.net and it throws that -10800 is Wednesday, December 31st 1969, 18:00:00 (GMT -3) but I believe this is not correct. I was told the negative number is in my timezone which is Buenos Aires.
I also want to create from date to string using the same time format. How can I do this?
THIS PART IS SOLVED:
Among the things I tryied in order to do this, a new doubt came up when learning about mktime:
I was trying to know which is the last day for february:
$lastday = mktime(0, 0, 0, 2, 0, 2015);
echo strftime("Last day is: %d", $lastday);
And this throws that february has 31 days which is incorrect. Why is that so?
If day is 0, then PHP takes the last day of the previous month, so
$lastday = mktime(0, 0, 0, 2, 0, 2015);
Gives 31st January 2015
(0th day of month 2, effectively)
As per the PHP docs
day
The number of the day relative 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).
(my emphasis)
EDIT
If you want the last day of February, use
$lastday = mktime(0, 0, 0, 2, 1, 2015);
echo 'Last day is: ', date("t", $lastday);

Get day of the week for last 7 days?

I need the names of the day (Monday, Tuesday, Wednesday, Thuesday, Friday, Saturday, Today).
I know this is a newby question and PHP has a date() function. But I tried and can't figure out how...
According to the PHP Manual at http://php.net/manual/en/function.date.php, just use "l" as the format parameter to get the full name of the day.
So 23rd Mar 2014 is a Sunday, as echoed by
<?php
echo date ("l", mktime(0, 0, 0, 3, 23, 2014));
// Echoes Sunday
?>
To get past 7, 6, 5 or 10000 days (or number of days in the future) from the current day, according the information at this page, just use negative or positive integers in a string in the strtotime function:
<?php
$backcount = -4;
echo date ("l", strtotime("$backcount day"));
// Executed on 23 Mar 2014 will give Wednesday
?>
Knowing this, you can apply a for loop to get what you need. And if want "Today" instead of the full name of the current day, just add an if condition to handle the situation where the backcount variable is zero.
Achieving this using the DateTime Class and its format method.
The below code's output changes every day.. Since today is Sunday it starts from Monday , Tuesday... If you run this code on Tuesday , you will be getting output as Thursday , Friday , Saturday .. so on.
<?php
for($i=1;$i<=7;$i++) //<--- Since we know total days in a week is 7.
{
$date = new DateTime(); //<-- Grabs today's datetime
$date->add(new DateInterval('P'.$i.'D')); //<--- Passes the current value of $i to add days..
echo $date->format('l')."<br>";
}
OUTPUT :
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Working Demo
you can use jddayofweek to retrieve day of week, it has 3 mode for string containing the day of week, string containing the abbreviated day of week and int represent number of day in week
for($i=0;$i<7;$i++){
$x=jddayofweek($i,2);
var_dump($x);
}

PHP - If date is less than next January

I'm to write a function that will return a specific day if it's between two dates... I've been trying to use mktime, but it keeps returning December?
Essentially, I'm trying to do this:
$now = date('F d, Y');
if($now [is Between July of last year and January of next year] ) {
//Output last day of January in this year
} elseif($now [is Between January of this year and July of this year]) {
//Output last day of July for next year
}
I'm a little confused on whether I need to be using mktime or strtotime? To determine January of next year, I tried below, but it returned December, 2012?
$jan = date("F,Y", mktime(0, 0, 0, 1, 0, $year+1));
Day 0 of January 2012 is actually December 31st of 2011.
PHP's months are 1-based. Try
$jan = date("F,Y", mktime(0, 0, 0, 1, 1, $year+1));
^--- 1st, not 0th
instead.
The day parameter should be 1 instead of 0. See http://php.net/manual/en/function.mktime.php for details.
date("F,Y", mktime(0, 0, 0, 1, 1, $year+1));
The day param in mktime should be 1 instead of 0:
mktime(0, 0, 0, 1, 1, $year+1);
Otherwise it will think it's "January 0th", which gets translated to "January 1st minus 1 day" = "December 31 from the previous year".
You can actually use this behaviour to add and substract days (or anything really) to dates, like this:
mktime(0, 0, 0, 1, 67, 2012); //returns the correct date for the 67th day of 2012

Categories