-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue with addSeconds and RFC dates after upgrade to 1.22.1 #871
Comments
I think this is related to, or caused by the same core issue as, #863 |
The issue I'm experiencing seems to be coming from the new implementation of the /**
* Consider the timezone when modifying the instance.
*
* @param string $modify
*
* @return static
*/
public function modify($modify)
{
if ($this->local) {
return parent::modify($modify);
}
$timezone = $this->getTimezone();
$this->setTimezone('UTC');
$instance = parent::modify($modify);
$this->setTimezone($timezone);
return $instance;
} I still haven't quite figured out how setting the timezone to UTC before the operation and back after is causing a problem, or why it's necessary, really. Regardless, after this operation, the unix timestamp returned will be for the original TIME in UTC, then adjusted for your time zone. |
See #862 (comment) |
Thanks @lucasmichot. I'm not sure these issues are related, unfortunately. I pulled down your pull request branch and am experiencing the same problem. We're using the RFC3339 format, rather than the ISO8601. I understand these formats are closely related, but from what I can tell the portion of code affected by your change isn't what's causing my issue. The updates to the If it's of any value, the "timezone" object that gets pulled and reset in my test case is: object(DateTimeZone)[2]
public 'timezone_type' => int 1
public 'timezone' => string '-07:00' (length=6) Appears to be valid with the : still in tact. |
Hi @lucasmichot ... I tried @Ovsyanka's branch from #884 and am experiencing the same results. I see his change and it looks like it should work. However my code is not going in to his if statement that just calls the parent's modify method. Instead it still falls in to the else block and goes through the UTC adjustment causing this 'bug'. Let me know if I can provide a test, or the crude code snippet i'm using on my side. |
Hey @jakelehner , yes can you provide your failing test? |
Problem is, that when you set timezone using 'HH:MM' notation then something going wrong in the DateTime object. After you modify object it returns wrong time for some formats (i dont know exactly which). But, after you run ->getTimestamp method all become normal; I suppose testcase can be like that:
|
….php?id=72338) Problem is, that when you set timezone using 'HH:MM' notation then DateTime object returns wrong time for some formats. I dont know all of it, but surely for 'U' format. I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it returns right values. So i added call to getTimestamp() method in setTimezone().
….net/bug.php?id=72338) Problem is, that when you set timezone using 'HH:MM' notation then DateTime object returns wrong time for some formats. I dont know all of it, but surely for 'U' format. I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it returns right values. So i added call to getTimestamp() method in setTimezone().
Here is a crude test I put together. This passes on 1.21 but fails on 1.22.1. $rfc3339Time = "2017-01-28T12:00:00-07:00";
$rfc3339TimeAssert = "2017-01-28T12:00:10-07:00";
$unixTimestampAssert = 1485630010;
$timeObj = new Carbon($rfc3339Time);
$timeObj->addSeconds(10);
$this->assertEquals($timeObj->toRfc3339String(), $rfc3339TimeAssert, "Invalid RFC3339 string after time addition.");
$this->assertEquals($timeObj->timestamp, $unixTimestampAssert, "Invalid unix timestamp after conversion."); The first assertion will pass (retrieving the RFC string), but the second assertion (converting to unix timestamp) will fail. |
It seems great to illustrate your initial problem, but i think that there may be enought to have only my test for base problem i desribed. |
This error doesn't appear in 1.21 because it was introduced in commit 5394301. Before this commit there was not setTimezone methods in modify. |
Doesn't matter to me which test is used as long as the use case is covered. I was posting per request of @lucasmichot and for completeness. Noted regarding commit 5394301. I noticed the same but you seem to have more of an understanding as to the reasons behind the change. |
….net/bug.php?id=72338) Problem is, that when you set timezone using 'HH:MM' notation then DateTime object returns wrong time for some formats. I dont know all of it, but surely for 'U' format. I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it returns right values. So i added call to getTimestamp() method in setTimezone().
Yeah, it is quite complicated case =) Let see what @lucasmichot will say about tests. And i just clarify that your test passed in previous versions because there no hidden calls to setTimezone function. After that commit, the setTimezone method calls in ->modify() and this bug showing up. |
You can vote to this bug on php bug tracker, but i dont know if it would make any difference ) |
….net/bug.php?id=72338) Problem is, that when you set timezone using 'HH:MM' notation then DateTime object returns wrong time for some formats. I dont know all of it, but surely for 'U' format. I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it returns right values. So i added call to getTimestamp() method in setTimezone().
….net/bug.php?id=72338) Problem is, that when you set timezone using 'HH:MM' notation then DateTime object returns wrong time for some formats. I dont know all of it, but surely for 'U' format. I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it returns right values. So i added call to getTimestamp() method in setTimezone().
….net/bug.php?id=72338) The problem is, that $date->setTimezone($tz) with $tz in 'HH:MM' notation (["timezone_type"]=>int(1)) put DateTime object on inconsistent state. It looks like internal timestamp becomes changed and it affects to such functions: * $date->modify() uses changed timestamp and result is wrong * $date->setTimezone($tz) settle this changed timestamp, even in case if $tz is not in 'HH:MM' format * $date->format('U') returns changed timestamp I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it behavior looks right in such cases described above. So i added call to getTimestamp() in setTimezone().
I made the pull-request #900 fixing this issue. |
@Ovsyanka, I can confirm this pull request addresses the issue stated in this thread. |
….net/bug.php?id=72338) The problem is, that $date->setTimezone($tz) with $tz in 'HH:MM' notation (["timezone_type"]=>int(1)) put DateTime object on inconsistent state. It looks like internal timestamp becomes changed and it affects to such functions: * $date->modify() uses changed timestamp and result is wrong * $date->setTimezone($tz) settle this changed timestamp, even in case if $tz is not in 'HH:MM' format * $date->format('U') returns changed timestamp I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it behavior looks right in such cases described above. So i added call to getTimestamp() in setTimezone().
….net/bug.php?id=72338) The problem is, that $date->setTimezone($tz) with $tz in 'HH:MM' notation (["timezone_type"]=>int(1)) put DateTime object on inconsistent state. It looks like internal timestamp becomes changed and it affects to such functions: * $date->modify() uses changed timestamp and result is wrong * $date->setTimezone($tz) settle this changed timestamp, even in case if $tz is not in 'HH:MM' format * $date->format('U') returns changed timestamp I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it behavior looks right in such cases described above. So i added call to getTimestamp() in setTimezone().
….net/bug.php?id=72338) The problem is, that $date->setTimezone($tz) with $tz in 'HH:MM' notation (["timezone_type"]=>int(1)) put DateTime object on inconsistent state. It looks like internal timestamp becomes changed and it affects to such functions: * $date->modify() uses changed timestamp and result is wrong * $date->setTimezone($tz) settle this changed timestamp, even in case if $tz is not in 'HH:MM' format * $date->format('U') returns changed timestamp I founded the workaround: if you run DateTime::getTimestamp() method after setting such timezone, internal structure of DateTime seems fixed - it behavior looks right in such cases described above. So i added call to getTimestamp() in setTimezone(). (cherry picked from commit e583800)
Fixing #871, workaround of php bug [72338](https://bugs.php.net/bug.php?id=72338)
This issue was solved in v1.23. |
We use RFC3339 format in our API, and store dates in unix timestamp in our database.
After upgrading Carbon to 1.22.1, I'm seeing an bug with converting Carbon dates back to timestamp after doing any math on the object:
Carbon 1.21
Carbon 1.22.1
It appears as if I'm losing the timezone reference after doing
addSeconds()
, but only for converting to UNIX timestamp. The RFC conversion still works as expected.Can anyone else confirm or comment?
The text was updated successfully, but these errors were encountered: