PHP's strtotime() does not add to dates as I expected - php

I think I am correct in saying that strtotime(2023) will return the number of seconds from 1 Jan 1970 to 1 Jan 2023.
I thought I could then add a year to that value like this: strtotime('+1 year', strtotime(2023)). I assume that the the number of seconds added would take into account whether it is a leap year or not and even whether any leap seconds need to be accounted for. However I am not sure if that assumption is correct.
If my assumptions were correct then the value should be the same as strtotime(2024). When I do it I find the ouputs are not the same.
The code I have run and the output is shown below:
<?php
$tsFrom = strtotime(2023);
$tsTo = strtotime('+1 year', $tsFrom);
echo $tsTo;
echo ' | ';
echo strtotime(2024);
// output:
// 1705436580 | 1673900640
I ran the code on the sandbox at https://onlinephp.io/
I tried putting the argument to strtotime() in quotes as I know normally it would take a string but that makes no difference to the output.
I would like to know where I am going wrong

strtotime(date('Y-m-d', strtotime(' + 1 years')))
or
strtotime(date('2022-01-16', strtotime(' + 1 years')))

Related

PHP DateTime unexpected result when adding interval string from Postgres timestamptz

I'm getting incorrect results when adding an interval in a DateTime input string.
Some strings work, some don't. Obviously adding zero shouldn't put the result 5 days in the future and truncate the time. Yikes.
$dtTestStr='2018-09-05 10:25:00-04 + 0 year 0 mon 0 day 00:00:00';
$myFubar=new DateTime($dtTestStr);
echo $dtTestStr. ' is now '.$myFubar->format('Y-m-d H:i:s');
// '2018-09-05 10:25:00-04 + 0 year 0 mon 0 day 00:00:00 is now 2018-09-10 00:00:00'
First of all, you need to use 'month' or 'months' instead of 'mon' and once you eliminate that problem, you have another error. It doesn't know what to do with those zeros. I also removed an extra ) at the end of your echo statement.
You want it to look like this:
$dtTestStr='2018-09-05 10:25:00-04 + 0 year 0 months 0 day 0 hour 0 minute 0 seconds';
$myFubar=new DateTime($dtTestStr);
echo $dtTestStr . ' is now ' . $myFubar->format('Y-m-d H:i:s');
Here's a sandbox link: Sandbox
The DateTime class thinks that you are asking for the Monday (mon) that follows September 5th, 2018. The following monday is the 10th.
Spelling out month or months will fix your typo.
To be clear, you don't need to assign all those zeroed intervals.
Here's some informative reading regarding several different ways to modify your time data.
Adding minutes to date time in PHP

PHP DATE ignoring day number 'z' and jumps to ELSE

I'm trying to piece together a script that will output a unique message every day of the year, so obviously this would be 365 messages. The code that I'm testing sadly jumps straight to else, rather than respecting the date 'z'. I suspect that it’s a problem with my code, here’s what I've attempted so far:
<?php
$date = date('z');
if($date == "41"){
echo "Test Message One";
}
elseif($date == "42"){
echo "Test Message Two";
}
else{
echo "Sadly your script does not work";
}
?>
Please note that date('z') is indexed at 0 instead of 1 (as I learned the hard the way). You will have to add +1 to your day of the year.
$date = date('z') + 1;
There is nothing wrong with the code as such but more so with the assignment of the day numbers within the code, thanks to Michael Berkowsk, Mark Baker and putvande for pointing this out. Rather than calculating the day numbers you need in your head it's advisable to use Google or epoch day numbers.
Notably it's important to note that php date starts from 0 to 365, this means:
Jan 1st = 0
Jan 2nd = 01
If your want to Jan 1st = 1, Jan 2nd = 2 and so forth simply edit your code to look something like this:
$date = date('z') + 1; credit to Err for this.

php - Year Changed To The Current Year After Date Being Substituted

I am trying to set publish date based on user choice and give it interval in a loop. But after it is substituted with the intervals, the year changed to the current year.
Here is the sample of my code:
$datestart = "2012-03-06";
$datenow = date("$datestart H:i:s", current_time( 'timestamp' ));
$newpostdate1 = $datenow + strtotime("0 years 0 months 1 days 0 hours 0 minutes 0 seconds");
$newpostdate = date("Y-m-d H:i:s", $newpostdate1);
echo $datenow . " " . $newpostdate;
$datenow Will return 2012-03-06 16:19:33 while $newpostdate return the current date plus 1 day i.e: 2014-03-15 17:02:23.
Why $newpostdate returning the current date plus next 1 day instead of 2012-04-06 16:19:33 ?
..because what you're doing doesn't do what you think it does.
First, you set $datenow to a string (not a date object), with value "2012-03-06 " + the current time (assuming that's what current_time returns).
Then you call strtotime with the value "1 days" (well, your string has a bunch of other zero-valued fields, but they don't change the result), which returns the current time + 24 hours as a number (the number of seconds since 1970).
Then you take that value and add it with + to the above string. This causes the string to be interpreted as a number, so it turns into 2012 (and the rest of the string is ignored). So the result is a timestamp representing the current time + one day + 2,012 seconds - or one day, 33 minutes and 32 seconds from the time the code is run. Which you then format as a string.
You could use John Conde's solution to get a more meaningful result. (I assume your real problem is different, else why not just start out by setting the string to '2012-03-07' in the first place?)
The first parameter of date() is the format you want the timestamp passed as the second parameter to be displayed as. So basically you are using date() incorrectly.
I think this is what you are looking for:
$date = new DateTime($datestart);
$date->modify('+1 day');
echo $date->format(Y-m-d H:i:s);

Can't get previous month from DateTime in PHP- Is this a (pretty big) bug?

I need to create functions in PHP that let me step up/down given datetime units. Specifically, I need to be able to move to the next/previous month from the current one.
I thought I could do this using DateTime::add/sub(P1M). However, when trying to get the previous month, it messes up if the date value = 31- looks like it's actually trying to count back 30 days instead of decrementing the month value!:
$prevMonth = new DateTime('2010-12-31');
Try to decrement the month:
$prevMonth->sub(new DateInterval('P1M')); // = '2010-12-01'
$prevMonth->add(DateInterval::createFromDateString('-1 month')); // = '2010-12-01'
$prevMonth->sub(DateInterval::createFromDateString('+1 month')); // = '2010-12-01'
$prevMonth->add(DateInterval::createFromDateString('previous month')); // = '2010-12-01'
This certainly seems like the wrong behavior. Anyone have any insight?
Thanks-
NOTE: PHP version 5.3.3
(Credit actually belongs to Alex for pointing this out in the comments)
The problem is not a PHP one but a GNU one, as outlined here:
Relative items in date strings
The key here is differentiating between the concept of 'this date last month', which, because months are 'fuzzy units' with different numbers of dates, is impossible to define for a date like Dec 31 (because Nov 31 doesn't exist), and the concept of 'last month, irrespective of date'.
If all we're interested in is the previous month, the only way to gaurantee a proper DateInterval calculation is to reset the date value to the 1st, or some other number that every month will have.
What really strikes me is how undocumented this issue is, in PHP and elsewhere- considering how much date-dependent software it's probably affecting.
Here's a safe way to handle it:
/*
Handles month/year increment calculations in a safe way,
avoiding the pitfall of 'fuzzy' month units.
Returns a DateTime object with incremented month/year values, and a date value == 1.
*/
function incrementDate($startDate, $monthIncrement = 0, $yearIncrement = 0) {
$startingTimeStamp = $startDate->getTimestamp();
// Get the month value of the given date:
$monthString = date('Y-m', $startingTimeStamp);
// Create a date string corresponding to the 1st of the give month,
// making it safe for monthly/yearly calculations:
$safeDateString = "first day of $monthString";
// Increment date by given month/year increments:
$incrementedDateString = "$safeDateString $monthIncrement month $yearIncrement year";
$newTimeStamp = strtotime($incrementedDateString);
$newDate = DateTime::createFromFormat('U', $newTimeStamp);
return $newDate;
}
Easiest way to achieve this in my opinion is using mktime.
Like this:
$date = mktime(0,0,0,date('m')-1,date('d'),date('Y'));
echo date('d-m-Y', $date);
Greetz Michael
p.s mktime documentation can be found here: http://nl2.php.net/mktime
You could go old school on it and just use the date and strtotime functions.
$date = '2010-12-31';
$monthOnly = date('Y-m', strtotime($date));
$previousMonth = date('Y-m-d', strtotime($monthOnly . ' -1 month'));
(This maybe should be a comment but it's to long for one)
Here is how it works on windows 7 Apache 2.2.15 with PHP 5.3.3:
<?php $dt = new DateTime('2010-12-31');
$dt->sub(new DateInterval('P1M'));
print $dt->format('Y-m-d').'<br>';
$dt->add(DateInterval::createFromDateString('-1 month'));
print $dt->format('Y-m-d').'<br>';
$dt->sub(DateInterval::createFromDateString('+1 month'));
print $dt->format('Y-m-d').'<br>';
$dt->add(DateInterval::createFromDateString('previous month'));
print $dt->format('Y-m-d').'<br>'; ?>
2010-12-01
2010-11-01
2010-10-01
2010-09-01
So this does seem to confirm it's related to the GNU above.
Note: IMO the code below works as expected.
$dt->sub(new DateInterval('P1M'));
Current month: 12
Last month: 11
Number of Days in 12th month: 31
Number of Days in 11th month: 30
Dec 31st - 31 days = Nov 31st
Nov 31st = Nov 1 + 31 Days = 1st of Dec (30+1)

Find out date of nth week's monday in PHP?

I have a simple situation where I have a user supplied week number X, and I need to find out that week's monday's date (e.g. 12 December). How would I achieve this? I know year and week.
Some code based mainly on previous proposals:
$predefinedYear = 2009;
$predefinedWeeks = 47;
// find first mоnday of the year
$firstMon = strtotime("mon jan {$predefinedYear}");
// calculate how much weeks to add
$weeksOffset = $predefinedWeeks - date('W', $firstMon);
// calculate searched monday
$searchedMon = strtotime("+{$weeksOffset} week " . date('Y-m-d', $firstMon));
An idea to get you started:
take first day of year
add 7 * X days
use strtodate, passing in "last Monday" and the date calculated above.
May need to add one day to the above.
Depending on the way you are calculating week numbers and the start of the week this may sometimes be out. (i.e. if the monday in the first week of the year was actually in the previous year!)
TEST THIS THOROUGHLY - but I've used a similar approach for similar calcualtions in the past.
This will solve the problem for you. It mainly derives from Mihail Dimitrov's answer, but simplifies and condenses this somewhat. It can be a one-line solution if you really want it to be.
function getMondaysDate($year, $week) {
if (!is_numeric($year) || !is_numeric($week)) {
return null;
// or throw Exception, etc.
}
$timestamp = strtotime("+$week weeks Monday January $year");
$prettyDate = date('d M Y');
return $prettyDate;
}
A couple of notes:
As above, strtotime("Monday January $year") will give you the timestamp of the first Monday of the year.
As above +X weeks will increment a specified date by that many weeks.
You can validate this by trying:
date('c',strtotime('Sunday Jan 2018'));
// "2018-01-07T00:00:00+11:00" (or whatever your timezone is)
date('c',strtotime('+1 weeks Sunday Jan 2018'));
// "2018-01-14T00:00:00+11:00" (or whatever your timezone is)
date('c',strtotime('+52 weeks Sunday Jan 2018'));
// "2019-01-06T00:00:00+11:00"
Due to reputation restriction i can't post multiple links
for details check
http://php.net/manual/en/function.date.php and http://php.net/manual/en/function.mktime.php
you can use something like this :
use mktime to get a timestamp of the week : $stamp = mktime(0,0,0,0,<7*x>,) {used something similar a few years back, so i'm not sure it works like this}
and then use $wDay = date('N',$stamp). You now have the day of the week, the timestamp of the monday should be
mktime(0,0,0,0,<7*x>-$wDay+1,) {the 'N' parameter returns 1 for monday, 6 for sunday}
hope this helps
//To calculate 12 th Monday from this Monday(2014-04-07)
$n_monday=12;
$cur_mon=strtotime("next Monday");
for($i=1;$i<=$n_monday;$i++){
echo date('Y-m-d', $cur_mon);
$cur_mon=strtotime(date('Y-m-d', strtotime("next Monday",$cur_mon)));
}
Out Put
2014-04-07
2014-04-14
2014-04-21
2014-04-28
2014-05-05
2014-05-12
2014-05-19
2014-05-26
2014-06-02
2014-06-09
2014-06-16
2014-06-23

Categories