$new_date = date('Y-m-d', strtotime("+2 days"));
or
$new_date = date('Y-m-d', strtotime("+48 hours"));
Are they same or different
Are they same or different
They are quite different. Objectively speaking, 2 days does not always equal 48 hours.
Consider crossing a daylight-savings boundary.
For example, 2019-04-07T02:00:00+1100 (AEDT -> AEST)
$twoDays = new DateInterval('P2D');
$fortyEightHours = new DateInterval('PT48H');
$ref = new DateTimeImmutable('2019-04-07T01:00:00',
new DateTimeZone('Australia/Melbourne'));
echo 'Reference: ', $ref->format('r'), PHP_EOL;
echo 'Plus 2 days: ', $ref->add($twoDays)->format('r'), PHP_EOL;
echo 'Plus 48 hours: ', $ref->add($fortyEightHours)->format('r'), PHP_EOL;
This produces
Reference: Sun, 07 Apr 2019 01:00:00 +1100
Plus 2 days: Tue, 09 Apr 2019 01:00:00 +1000
Plus 48 hours: Tue, 09 Apr 2019 00:00:00 +1000
Note, HHVM produces a different result for some reason
Demo ~ https://3v4l.org/L4tKo
This list of common date / time related falsehoods is worth checking out ~ https://github.com/kdeldycke/awesome-falsehood#dates-and-time
It's worth pointing out that using the same reference date and manipulating it with strtotime() produces different results to those above.
Demo ~ https://3v4l.org/O6MTd
I suspect this is because its relative time calculations aren't as nuanced as DateInterval.
Semantically they are different, as demonstrated by Phil in the other answer. This means that in some other libraries that account for this the difference is real.
However, the implementation of strtotime() does not take this into account, so given your example, it makes no difference.
I was interested if it can be followed up through source code, so here goes:
Implementation of strtotime() does this:
strtotime() starts, calling timelib_strtotime() to create the initial ts construct
timelib_strtotime() calls scan() to parse the string
it reads the string you've given to it, and one of the tokens it gets is your +2 days or +48 hours, which is considered as relativetext.
for relativetext, among other things, timelib_set_relative() is called
in timelib_set_relative() it does a lookup from using timelib_lookup_relunit(), which uses timelib_relunit_lookup array, finding that you've provided either a construct with type TIMELIB_DAY, value 1, multiplier 2, or construct TIMELIB_HOUR, value 1, multiplier 24
It saves the information from previous call to s->time->relative construct
this construct gets passed on, until strtotime calls timelib_update_ts with it (and with timezone info!)
in timelib_update_ts we call do_adjust_relative() to act on it. We do it without using time zone parameter, which I would think is the critical mistake
do_adjust_relative() calls timelib_do_normalize()
timelib_do_normalize() for hours does do_range_limit(0, 24, 24, &time->h, &time->d), increasing days and decreasing hours if hours are over the hardcoded limit which is 24, and for days does do_range_limit_days(), increasing months and decreasing days if we are over the limit, taking into account leap time (but NOT time zones!).
on returning to timelib_update_ts, we call do_adjust_timezone with timezone parameter, but at this point we've already made all the adjustments and we know no more if it was done with +48 hours or with +2 days. Thus it makes no difference.
TLDR: strtotime() does not take time zones into account when doing the conversion, so in that function it makes no difference, even though it really should.
Related
I need help.. Is this right?
Start Date: Mar 16, 2014
End Date: Mar 19, 2014
Results: 2 Days
$plantEnd = get_the_author_meta('plantEnd', $sellerID );
$plantStart = get_the_author_meta('plantStart', $sellerID );
$future = $plantEnd;
$d = new DateTime($future);
echo $d->diff(new DateTime())->format('%a').' Days';
Why does it says 2 days? Isn't it 3 days? Im confused..
Since you aren't actually using $plantStart in your code and instead using the current time, you're basically getting a difference between now (the time the script was run, on server's time zone) and the start of Mar 19, 2014 (0h:0m:0s). So what you are really getting is something like 2 days 5 hours 3 minutes 25 seconds (depending on when you run it vs. server time.
for example, when I run this locally:
$d->diff(new DateTime())->format('%d:%H:%i:%s');
I get 2:04:59:25
So there's more to it than just getting that "2" returned.. you're just not formatting for it.
And again, you aren't actually using the $plantStart anywhere either. So if you were to do this:
<?php
$plantEnd = '2014-03-19';//get_the_author_meta('plantEnd', $sellerID );
$plantStart = '2014-03-16'; //get_the_author_meta('plantStart', $sellerID );
$future = $plantEnd;
$d = new DateTime($future);
echo $d->diff(new DateTime($plantStart))->format('%d:%H:%i:%s');
?>
You will see it outputs 3:00:0:0 (or you could continue to just use %d and get the "3"). This is because $plantStart (presumably - based on your post) just specifies yyyy-mm-dd, so passing just the yyyy-mm-dd value will put the hh:mm:ss at 0:0:0 (beginning of day) , so it will be a full day's calculation, which has the effect of "rounding up" to the whole day increment.
I have a feeling that it's actually 2 days, someodd hours, and someodd minutes, or something to that effect. Because you're formatting to just do days, you're losing the nuances. I'd change the code to say "2.4 days" (and for the life of me I can't remember how I did this in the past...)
EDIT: in the past I have simply used date() instead of DateTime().
I did a little research, and you might want format('%d')." Days";
function DateFormat($dt)
{
return $newDate = date("d/m/Y", strtotime($dt));
}
$cr='2014-02-31';
echo DateFormat($cr);
Input: $cr='2014-02-31';
Output: 03/03/2014
I am passing 2014-02-31 and getting output 03/03/2014.
Please help me out.
PHP's date functions work with dates not strings. And that's an important distinction. Strings are just a bunch of characters in a specified order. Dates have months, days, years, hours, minutes, seconds, timezones, etc. When PHP works with dates it takes all of them into consideration.
So when you pass Feb 31 to a PHP date function it is going to try to make sense of it as a date and not a string. This means it isn't just going to take that date cut it up into bits and then rearrange them as you are expecting. It is going to turn that date into a date representation it can work with and then manipulate it.
As we all know, February does not have 31 days. As a result of the invalid date, PHP is trying to be helpful and taking three days after last day in February of that year (since Feb only has 28 days this year) and giving you that date.
The issue is February most years only has 28 days. 2/31 would be logically translated to 3/3. On a leap year you'd get 3/4...
The strtotime() method as it needs to be very flexible to be able to handle stuff without borking like:
strtotime('2014 February + 31 day - 1 year');
And no I don't think it should error out. When you have a well formed date string, PHP has a deceptively named method called checkdate() you could use:
$crappy_date='2014-02-31';
$date_parts = explode('-', $crappy_date);
$valid = checkdate($date_parts[1], $date_parts[2], $date_parts[0]);
I'm setting up a configuration file for a website, which will be read using the parse_ini_file method. One of the options is number of seconds prior to some action. I tried setting the value to 60*60*24*3 to get three day's worth of seconds:
[mailer]
; Number of seconds before trial expiration an email should be sent
seconds = 60*60*24*3;
but the variable is just read into php as the string "60*60*24*3". I don't want to use eval, for security reasons. Is there any way to make this (a) easier to use and (b) more intuitive to read than by simply listing the number of seconds to a given date?
You can use supported date and time formats to make a human-readable string, which may then be used to initialize and calculate the difference in seconds:
$diff = "3 days 5 hours 10 seconds";
$now = strtotime('2010-04-01 00:00:00'); // No leap year funny business
$then = strtotime($diff, $now);
$diff = $then - $now;
echo "
Now: " . date('r', $now) . "
Then: " . date('r', $then) . "
Diff (seconds): $diff";
https://ignite.io/code/51338967ec221e0d3b000000
Note: The concern about leap year is whether it will calculate the seconds correctly (add/remove a day?). If this is possible, it should be tested independently.
The above outputs:
Now: Thu, 01 Apr 2010 00:00:00 +0000
Then: Sun, 04 Apr 2010 05:00:10 +0000
Diff (seconds): 277210
Which would then let you do:
[mailer]
; Period before trial expiration an email should be sent.
; Use PHP-supported time statements in an expression to
; specify an interval, such as 3 days, or 72 hours, etc.
; See: http://www.php.net/manual/en/datetime.formats.php
expires = 3 days;
As I noted in the comments, you can also use DateTimeInterval::createFromString() with DateTime::diff to do the same thing.
I will note as well that getting the string formatted correctly, while not difficult, can sometimes be trickier than you might think. For simple strings like 3 days that's not hard, but 3d doesn't work. So the time that is calculated should be validated, and an error provided to the person setting the configuration if what was entered is not a valid expression, or is "out of bounds" to what was expected (in the past maybe?).
rename your ini to php and write it this way
# Number of seconds before trial expiration an email should be sent
$cfg['somesection']['someparam'] = 'foo';
...
$cfg['mailer']['seconds'] = 60*60*24*3;
or use a screen calculator to do the math and paste result as a value.
Either I'm losing my mind, or I've not got the faintest idea what I'm doing. I'm leaning towards the latter.
I'm trying to convert this: 1316826000, which I'm pretty confident should be Sat, 24 Sep 2011 01:00:00 GMT
http://www.onlineconversion.com/unix_time.htm confirms this.
http://www.unixtimestamp.com/index.php tells me 09 / 23 / 11 # 8:00:00pm EST, so far so good. I happen to be in EST, this is the result I'd like to get back from PHP.
When I do date('l, M d, Y, h:ia', $iTime), I get: Friday, Sep 23, 2011, 12:00am, a full 20 hours off.
I've confirmed the server's time is correct using date('c'). date('c') output is: 2012-05-19T03:19:20+00:00. The server is in the central time zone, where it is currently 10:20pm. May 18.
echo date_default_timezone_get() outputs "GMT" (set somewhere else in the script using date_default_timezone_set('GMT'))
What am I missing? Nothing I've read so far can explain how I'm getting a result 20 hours behind what it should be. Were it an hour fast or slow, I could at least wrap my head around it being some sort of DST idiotry, but 20? Crazyness! Thanks for reading!
Check what your php.ini says for date.timezone.
In unix it is usually here: /etc/php.ini
Then use a proper timezone recognized by PHP:
http://www.php.net/manual/en/timezones.php
date.timezone = 'America/New_York'
Then reload your web server.
Unix time just means the number of seconds since epoch. Has nothing to do with timezones. Timezones simply add or subtract 1 hour (3600 seconds) from the unix time for each zone you move away from GMT.
An example:
$userTimezone = new DateTimeZone('America/New_York');
$gmtTimezone = new DateTimeZone('GMT');
$myDateTime = new DateTime('2014-01-22 11:44', $gmtTimezone);
$offset = $userTimezone->getOffset($myDateTime);
echo $offset;
That will output: -14400 or 4 hours. Which is the difference between New York and GMT
Using some Java code with the Joda-Time 2.3 library, as I don't know PHP…
long m = 1316826000L;
DateTime dateTimeUtc = new DateTime( m * 1000L, DateTimeZone.UTC );
DateTime dateTimeNewYork = dateTimeUtc.toDateTime( DateTimeZone.forID( "America/New_York" ) );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeNewYork: " + dateTimeNewYork );
I can tell you that 1316826000 seconds from the beginning of 1970 UTC/GMT (Unix Epoch) is…
dateTimeUtc: 2011-09-24T01:00:00.000Z
dateTimeNewYork: 2011-09-23T21:00:00.000-04:00
So, as the commenter stated, it would be 8 PM in EST but EST was not in effect on that day. DST (Daylight Saving Time) (idiocy, as you correctly noted) was in effect until November 9 of that year (2011). So the time of day is pushed forward one hour, to 9 PM.
In GMT/UTC, that means 1 AM in the morning of the next day.
Standard time in east coast US is 5 hours behind UTC/GMT. With DST it is 4 hours behind UTC/GMT (one hour closer).
Where you got confused:
Your time format/conversion in incorrect.I can't help with that as I don't know PHP.
You should be using a competent date-time library for this kind of work.Date-time work is complicated, tricky, confusing, and error-prone.This question discusses possibilities of Joda-Time (for Java) sorts of libraries for PHP.
You used three-letter time zone codes. Avoid these.Those codes are neither standardized nor unique -- there are common duplicates. Instead, use proper time zone names. In your case of east coast US, "America/New_York". Furthermore, in this case you confused the time zone area and rules (east coast US) with a particular application of those rules (EST). Saying "America/New_York" means "whatever time zone rules were in effect on that date, whereas saying "EST" (if interpreted to mean Eastern Standard Time in US) means "UTC-05:00". So either (a) use a time zone name such as "America/New_York", or (b) use a specific offset such as "-05:00".
I've got kind of a tricky question, I already searched every related question on Stackoverflow and neither solved my conundrum, although I think I'm running in circles, so here's the question:
I've got this code:
$val = (strtotime('2010-03-22 10:05:00')-strtotime('2010-03-22 09:00:00'))
This returns correctly $val = 3900 (3600 seconds = 1 hour, 300 seconds = 5 mins)
But doing this:
echo date("H:i",$val)."<br>";
returns 02:05
even doing this:
echo date("H:i",3900)."<br>";
returns 02:05 (just to be naively sure)
Doing this:
echo date("H:i eTO",3900)."<br>";
returns
02:05 System/LocaltimeCET+0100
Which is correct, my timezone is CET and is +1.
What's going on? Is date() correcting the timezone for some reason? Or am I doing anything wrong?
This is happening because using date(, ) returns epoch (00:00:00 01 January 1970 UTC) + the number of seconds in the timestamp. It will localise itself to your timezone, so if you provided it with a timestamp of 0 it would return 01:00:00 01 January 1970 UTC+1.
Yes, it is correcting the timezone. When you do
$val = (strtotime('2010-03-22 10:05:00')-strtotime('2010-03-22 09:00:00'))
, what's stored in $val is a timestamp for 01:05, 1 Jan 1970 UTC. See Wikipedia's article on Unix Time.
If you're working with the difference between two timestamps, I'd suggest using DateTime::diff (requires PHP 5.3).
I did this:
date_default_timezone_set('Europe/Helsinki');
Which is GMT+02:00
and the result was:
03:05 Europe/HelsinkiEET+0200
So, it IS actually correcting for timezone, the explanation now I found to be pretty simple (I had an epiphany): date() counts seconds FROM "1 Jan 1970 GMT" so actually 3900 in my timezone and example is correctly "02:05" from that date...
Self learning +1 -_-'
This is actually the right behavior, because date works with local time, and you are on GMT +1. You give it a timestamp (3900) which is 1/1/1970 1:05 and it just ads 1 to get it to your timezone.
If this is your intended use, than you can just subtract the GMT offset of your machine to get the right value.