Comments (20)
I can confirm that the test cases you have supplied do in fact fail. I am not certain yet whether or not I think they are valid test cases though. I'll be taking a deeper look into these issues later this week.
-John
from timecop.
The problem is when I freeze or travel, DateTime.now always returns an UTC time (offset is 0) with local values in individual fields (year, hour, etc.). Whereas standard DateTime.now returns a true local time (local values in individual fields and local offset).
The problem arises when you convert DateTime.now to another timezone (or even the local timezone). The individual fields are changed according to the new timezone. But since the individual values were already local, the converted time is wrong.
I've added another test in the branch to illustrate this.
from timecop.
@piglop thanks for following up with more information. This will be helpful.
from timecop.
I found a solution and made a single commit from master here : http://github.com/piglop/timecop/commit/7478f7ff28f2b5ea4b5476622c5de36bf7edca9f
I also added a fix for the problem with Time.utc here : http://github.com/piglop/timecop/commit/550183c5fb9fca7ac4351e16dc1cae4469c292cb
from timecop.
@piglop it's taken me a couple of extra days to get around to this. I'll be able to review these patches this weekend and hopefully get them merged in.
Thanks again.
-John
from timecop.
Should be fixed with http://github.com/piglop/timecop/commit/607af97d9d352b6b7e077658d2b759704d9749ba
from timecop.
Commited : http://github.com/jtrupiano/timecop/commit/d74af87729f8488fad2344e40810928216228702
from timecop.
Included in 0.3.2 release
from timecop.
I haven't studied the code changes, but timecop 0.3.2 has definitely broken in terms of how Time.now works when freezing. For example, here's a tiny "test" to illustrate:
it "should behave" do
puts "Time (local) at start is: #{Time.now}"
puts "Time (UTC) at start is : #{Time.now.utc}"
Timecop.freeze(3.hours.from_now) do
puts "Time (local) after timecop added 3 hours: #{Time.now.utc}"
puts "Time (UTC) after timecop added 3 hours : #{Time.now.utc}"
end
end
If I run that with Timecop 0.3.1, I get:
Time (local) at start is: Mon Oct 26 13:40:39 -0700 2009
Time (UTC) at start is : Mon Oct 26 20:40:39 UTC 2009
Time (local) after timecop added 3 hours: Mon Oct 26 23:40:39 UTC 2009
Time (UTC) after timecop added 3 hours : Mon Oct 26 23:40:39 UTC 2009
But, if I run that with Timecop 0.3.2, I get:
Time (local) at start is: Mon Oct 26 13:41:30 -0700 2009
Time (UTC) at start is : Mon Oct 26 20:41:30 UTC 2009
Time (local) after timecop added 3 hours: Mon Oct 26 16:41:30 UTC 2009
Time (UTC) after timecop added 3 hours : Mon Oct 26 16:41:30 UTC 2009
So, now, time has gone backwards. In both cases my local timezone has been changed to UTC. What it's doing in 0.3.2 appears to be that it's adding 3 hours to the "Time.now" result, and not taking into account the Time zone.
from timecop.
@chris thanks for the report. If you have a free moment and can add a failing test to the test suite, I'd really appreciate it.
In the meantime, I suspect you'll get away with 0.3.1. It will probably be several days before I can get around to this.
from timecop.
While I was trying to write a test case for this problem, I discovered the current test suite fails since DST shift.
Indeed, in the new tests, we check that DateTime.now returns a local time, i.e. a DateTime with the current local offset. But when we create a DateTime in summer while we're in winter, the local offset should not be the same.
And I couldn't find a way to get the local offset at a specific time with the DateTime class. It may be possible with the Time class.
I couldn't write a test case for chris's problem, but I could reproduce it in a Rails environment.
I won't have a lot of time to check these problems this week.
from timecop.
I'm looking into it. I'm starting to think it's a conflict with Rails though. I forked the code, added a test case and it behaves properly when using simple math to add 3 hours to the time. So, I'm going to look into whether it's Rails' extensions for doing things like "3.hours.from_now" and if that messes with it. Like you guys, I'm pretty busy, and Timecop 0.3.1 works for me, so I'm not sure when I'll resolve this.
from timecop.
So I've had some time to really dig into this.
@chris, I think I have your issues worked out. I'll be releasing a prerelease version of timecop in a couple of days that I'll want you to try out for me. If you care to try my latest release candidate before I get the prerelease version sorted out, you can pull it down from a new branch named 'rewind'.
@piglop, there is a separate problem related to the patch you originally submitted. You had noticed behavior where traveling to times/datetimes in a different timezone were losing the timezone information, causing that time to be represented as UTC. Your patch corrected this, but at the same time underscored a new issue that I don't think we can solve.
The problem lies in the fact that a DateTime is incapable of representing DST properly. A DateTime only carries an offset (e.g. +0200), but this is not enough information for us to know if this particular DateTime instance should be subject to DST. Different timezones exist within the same offset, and some observe DST while others do not.
Due to this limitation, you can end up with the following test case failing:
t = DateTime.parse("2009-10-11 00:38:00 +0200")
assert_equal "+02:00", t.zone
Timecop.freeze(t) do
assert_equal t, DateTime.now.new_offset(t.offset)
end
I have pushed a new branch "rewind" to GitHub where you can see this test currently failing.
As a result of this finding, I am seriously considering removing the ability to pass a DateTime instance to Timecop calls. My concern is that this is simply too little known (that DateTime's cannot represent DST) and will cause many people headaches if we allow them to do so.
I'm curious what your thoughts are.
from timecop.
The gemspec in the 'rewind' branch now specifies a prerelease version (0.3.3.rc1). I'd really appreciate it if you guys (@chris and @piglop) could give it a try with your respective problems and report back to me.
from timecop.
Note that if you had previously installed 0.3.3 that it will take precedence over 0.3.3.rc1. I'm still getting the hang of this prerelease workflow...
from timecop.
I have released 0.3.4.rc1 as a prerelease gem. You can install it via: gem install/update --prerelease timecop
from timecop.
Hey guys,
I found some other problems with 0.3.4.rc1 that I think I've fixed.
Can you take a moment to try upgrading to timecop 0.3.4.rc2 on your respective projects and let me know if I've introduced any regressions? It is a prerelease gem so you'll need to specify that when installing the gem: gem install timecop --pre -v0.3.4.rc2
This is just for verification purposes. Your projects should not depend on this version of the gem. If no regressions are found I will then officially release version 0.3.4 at which point you should upgrade your projects' dependencies.
Thanks for your help.
-John
from timecop.
@jtrupiano not sure this is exactly the same bug, but you've fixed mine in your prerelease gem.
I have a rails app with the timezone set to Eastern. My box is running Central
In 0.3.2:
require 'timecop'
>> time = Time.local(2000, 1, 1)
=> Sat Jan 01 00:00:00 -0600 2000
>> Timecop.freeze(time)
=> Sat, 01 Jan 2000 00:00:00 EST -05:00
>> Time.now
=> Sat, 01 Jan 2000 00:00:00 EST -05:00
Note it's an hour off. In 0.3.4.rc2 it is correct.
from timecop.
0.3.4.rc2 is working in all my current tests. It does still change the local time zone to be UTC (from whatever it previously was) though. e.g. (output from my same example above):
Time (local) at start is: Tue Dec 01 21:13:45 -0800 2009
Time (UTC) at start is : Wed Dec 02 05:13:45 UTC 2009
Time (local) after timecop added 3 hours: Wed Dec 02 08:13:45 UTC 2009
Time (UTC) after timecop added 3 hours : Wed Dec 02 08:13:45 UTC 2009
from timecop.
@JerryVos excellent. Your issue is one of the issues I have been trying to solve since 0.3.1.
@chris can you show me a sample session from either irb or script/console? Specifically I want to know which set of arguments you're passing to Timecop.freeze or Timecop.travel.
from timecop.
Related Issues (20)
- Can we please have a new release HOT 1
- Date.strptime patch causes error HOT 2
- `Date.strptime` breaks for "Feb 2021", "%B %Y" on the 31st of the month HOT 3
- Time is not reset after block when thread_safe is enabled. HOT 1
- Date.parse returns wrong date if only date is specified HOT 1
- How to start the console? HOT 4
- Is call to Timecop.travel(some random time) atomic in nature? HOT 1
- Time#travel should be side-effect free and not resume system clock HOT 10
- .
- Timecop.thread_safe = true by default HOT 1
- Timecop handles GMT/UTC Time objects incorrectly HOT 2
- Doesn't work for `Rails.cache` with `expires_in` HOT 2
- ruby 3.1 support
- Date.strptime returns wrong month for %Y HOT 6
- %W is not handled properly HOT 1
- Ruby 2.5 seems to work? HOT 4
- Using timecop with psych 4.0.5, behavior differs between the test environment and other environments HOT 3
- Timecop.scale to mock existing times HOT 2
- Timecop.freeze not working with expect().to receive HOT 3
- Test
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from timecop.