rubymotion-community / motion-support

Commonly useful extensions to the standard library for RubyMotion
MIT License
132 stars 28 forks source link

Date to epoch time conversion issue #18

Open kapso opened 10 years ago

kapso commented 10 years ago
(main)> today = Date.today
=> Thu, 30 Jan 2014

(main)> Time.at(today.to_time.to_i)
=> 2014-01-30 02:19:38 -0800

(main)> tomorrow = Date.today + 1.day
=> Fri, 31 Jan 2014

(main)> Time.at(tomorrow.to_time.to_i)
=> 2014-01-30 16:00:00 -0800
markrickert commented 10 years ago

Could this have to do with the Date bug that was fixed in 2.20? http://hipbyte.myjetbrains.com/youtrack/issue/RM-378

kapso commented 10 years ago

Possible, I opened a ticket with HipByte.

markrickert commented 10 years ago

Looks like it's the Time.at() method that's to blame for not taking into account the timezone offset. tomorrow.to_time.to_i returns the correct unix timestamp, but in GMT instead of local timezone:

(main)> today = Date.today
=> Thu, 30 Jan 2014

(main)> Time.at(today.to_time.to_i)
=> 2014-01-30 15:26:31 -0500

(main)> tomorrow = Date.today + 1.day
=> Fri, 31 Jan 2014

(main)> Time.at(tomorrow.to_time.to_i)
=> 2014-01-30 19:00:00 -0500

(main)> tomorrow.to_time.to_i
=> 1391126400

1391126400 is Fri, 31 Jan 2014 00:00:00 GMT, which technically IS 2014-01-30 19:00:00 -0500 as Time.at(tomorrow.to_time.to_i) indicated.

Unfortunately, TIme.zone isn't implemented in motion-support, otherwise we could just do Time.zone.at(tomorrow.to_time.to_i) like we would in rails. I agree this is an issue, but maybe not a rubymotion bug?

Watson1978 commented 10 years ago

Maybe, I think you could solve this issue if you would use Time.local instead of Time.utc in https://github.com/tkadauke/motion-support/blob/a1a32478fb142d372691e404bc71a66632ed92a6/motion/_stdlib/date.rb#L16

markrickert commented 10 years ago

Good call, @Watson1978.

I made this change locally and it seems to mitigate the issue:

(main)> today = Date.today
=> Fri, 31 Jan 2014
(main)> Time.at(today.to_time.to_i)
=> 2014-01-31 10:40:49 -0500
(main)> tomorrow = Date.today + 1.day
=> Sat, 01 Feb 2014
(main)> Time.at(tomorrow.to_time.to_i)
=> 2014-02-01 00:00:00 -0500
(main)> tomorrow.to_time.to_i
=> 1391230800
(main)> Date.tomorrow == Time.at(tomorrow.to_time.to_i)
=> true

1391230800 is Sat, 01 Feb 2014 05:00:00 GMT - Midnight tomorrow my local time.

I ran the tests with this change and got:

Bacon::Error: Sat, 26 Feb 2005.==(Sun, 27 Feb 2005) failed
    spec.rb:698:in `satisfy:': weeks_ago - should be calculated correctly
    spec.rb:712:in `method_missing:'
    spec.rb:314:in `block in run_spec_block'
    spec.rb:438:in `execute_block'
    spec.rb:314:in `run_spec_block'
    spec.rb:329:in `run'

Bacon::Error: Mon, 23 Oct 2006.==(Mon, 30 Oct 2006) failed
    spec.rb:698:in `satisfy:': next_week - should be calculated correctly
    spec.rb:712:in `method_missing:'
    spec.rb:314:in `block in run_spec_block'
    spec.rb:438:in `execute_block'
    spec.rb:314:in `run_spec_block'
    spec.rb:329:in `run'

Bacon::Error: 2005-02-26 10:10:10 -0500.==(2005-02-27 10:10:10 -0500) failed
    spec.rb:698:in `satisfy:': weeks_ago - should be calculated correctly
    spec.rb:712:in `method_missing:'
    spec.rb:314:in `block in run_spec_block'
    spec.rb:438:in `execute_block'
    spec.rb:314:in `run_spec_block'
    spec.rb:329:in `run'

Bacon::Error: 2006-10-23 00:00:00 -0400.==(2006-10-30 00:00:00 -0500) failed
    spec.rb:698:in `satisfy:': next_week - should be calculated correctly
    spec.rb:712:in `method_missing:'
    spec.rb:314:in `block in run_spec_block'
    spec.rb:438:in `execute_block'
    spec.rb:314:in `run_spec_block'
    spec.rb:329:in `run'

Bacon::Error: 60.0.==(60.00001) failed
    spec.rb:698:in `satisfy:': seconds_since_midnight - should calculate correctly
    spec.rb:712:in `method_missing:'
    spec.rb:314:in `block in run_spec_block'
    spec.rb:438:in `execute_block'
    spec.rb:314:in `run_spec_block'
    spec.rb:329:in `run'

1654 specifications (2826 requirements), 5 failures, 0 errors

Without the change I only have the last error:

Bacon::Error: 60.0.==(60.00001) failed
    spec.rb:698:in `satisfy:': seconds_since_midnight - should calculate correctly
    spec.rb:712:in `method_missing:'
    spec.rb:314:in `block in run_spec_block'
    spec.rb:438:in `execute_block'
    spec.rb:314:in `run_spec_block'
    spec.rb:329:in `run'

1654 specifications (2830 requirements), 1 failures, 0 errors

So there's obviously some issues with changing that to .local. What say you, @tkadauke?

tkadauke commented 10 years ago

Well, that's hard for me to follow at the moment since I'm on a RubyMotion break. But I can say that I intentionally removed a lot of timezone stuff when porting ActiveSupport to RubyMotion, since an iOS app rarely needs support for more than one time zone at any given time.

Also, the last error looks like it's a rounding issue. I'm fairly certain it can be fixed pretty easily.