timecop: TimeCop handles timezones incorrectly

I am not sure why this issue was closed but I am following up with the suggestion to allow for handling of UTC dates. If this cannot happen by default, perhaps it can be done with an option of sorts.

In our case, the current logic leads to specs that pass during the day and fail during the night.

Here is an example:

it 'returns all reports generated on a certain date' do
    Timecop.freeze 1.day.ago do
      create_list :report, 4, name: '1.day.ago'
    end

    Report.generated_on(1.day.ago).count.should == 4
end

The intent of the spec couldn’t be clearer. It is difficult for me to agree with any default logic in Timecop that leads to inconsistent behavior in such a simple case.

About this issue

  • Original URL
  • State: closed
  • Created 12 years ago
  • Reactions: 6
  • Comments: 32 (9 by maintainers)

Most upvoted comments

Hey, All!

I was reading through this (a bit, it’s quite long!) via a co-worker and wanted to present a solution we have for this instance.

Timecop.freeze(Time.parse('Tue Aug 28 06:00:00 CDT 2018').utc)

We like this because it clear about your starting point for freezing. We want to be able to say “At this time in UTC relative to our local time (CDT), freeze time”.

In an ideal world we can set the timezone from within the Timecop interface without having to get Rails involved. We don’t do all of our work in Rails and keeping the two (Ruby, Rails) separate seems like a preferred position.

Hopefully this helps.

I’m under GMT-3 and the other developer is under GMT-4. We are using VCR to record some requests with the timestamp in the querystring (HMAC).

If we use Timecop.freeze it doesn’t preserve my timezone, raising VCR errors VCR::Errors::UnhandledHTTPRequestError.

Here is an example:

    context 'using Timecop.freeze' do
      before do
        now = Time.new(2013, 8, 16, 10, 55, 14, '-03:00')
        Timecop.freeze(now)
       end

      it 'requests ... ' do
        now = Time.now
        # WRONG, it should be -0300
        # => 2013-08-16 09:55:14 -0400
      end
   end 

    context 'using Time.stub' do
      before do
        now = Time.new(2013, 8, 16, 10, 55, 14, '-03:00')
        Time.stub(now: now)
      end

     it 'requests ... ' do
        now = Time.now
        # it is correct ;)
        => 2013-08-16 10:55:14 -0300
     end
   end