Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Allow calculation of seconds until end_of_days, and conversion of time to end_of_days` #8563

Closed
wants to merge 1 commit into from
@robertjwhitney

Hey does anyone have time to sanity-check this for me real quick?

@tenderlove
Owner

:+1: :shipit:

@guilleiguaran

:shipit: asap please, probably we will need to do an urgent release for this

@abimaelmartell

this is one of the greatest features i been waiting for :+1:

@pixeltrix
Owner

Needs a test for negative values :trollface:

@robertjwhitney

@pixeltrix I was considering that, but after consulting my references was unable to find a valid use-case.

@rmoriz

I suggest a more flexible solution using an AbstractApocalypseDateFactory-pattern that includes every known "end of days" date with a convenient interface.

So if you could work this out until Friday that would be great, mmmkay!

@mstum

The nice thing about this feature is that the date can be easily changed to 01/19/2038 03:14:07 UTC which is a more accurate, almost literal end of time. So it's extensible, which is great :thumbsup:

@pixeltrix
Owner

@robertjwhitney can you use DCI to inject the end date - thanks!

@tmilewski
alias :schwarzenegger, :end_of_days

@mikesax

Do we also want distance_of_time_in_words_to_end_of_days?

Does this go under ActionView::Helpers::DateHelper or do we need a new ActionView::Apocalypse module?

activesupport/test/core_ext/date_ext_test.rb
@@ -78,6 +78,10 @@ def test_end_of_year
assert_equal Date.new(2008,12,31).to_s, Date.new(2008,2,22).end_of_year.to_s
end
+ def test_end_of_days
+ atter_Equal Date.new(2012,12,21).to_s, Date.new(2012,12,19).end_of_days.to_s

atter_Equal...

whoops!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@envygeeks

@mikesax I don't think I could live without a helper like that. I like my pretty "You'll die 2 days from now" output.

@parndt

I feel like this should have been implemented using Concerns in any way possible.

@rmoriz

@mikesax +1. Can you build it threat-save?

@ereslibre

You made my day, guys.

@davidcelis

Are we sure this is threadsafe?

@rmoriz

@robertjwhitney time-zone awareness is missing. From my understanding, an apocalypse will be held synchronized.

@omarqureshi

are you sure the Mayans used EST?

@radar

@davidcelis I don't think that should be of such a large concern for such a short-lived feature.

:shipit:

@robzolkos

Will this be compatible with turbo links?

@sobrinho

I think we should add a "maya timezone" to the codebase first :shipit:

@davidcelis

The Solstice occurs at 11:11 AM GMT; we should fix this time discrepancy before merging

@parndt

@davidcelis do we know at which second?

@thiagofm

Can you add it to ruby-core? @tenderlove

@sobrinho

Maybe @headius and @evanphx should take a look too.

@tenderlove
Owner

Can you squash this so we can merge?

@halan

hurry

actionmailer/CHANGELOG.md
@@ -1,5 +1,8 @@
## Rails 4.0.0 (unreleased) ##
+* Allow calculation of seconds until end_of_days, and conversion of time to end_of_days.
+ *Robert Whitney*

This changelog should be in activesupport.

Whoops!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@leanucci

I had a funny joke involving tests without specs, but nah... :shipit:

@zenspider

Please merge. We can always revert later... OR CAN WE?

@guilleiguaran

GH reports "This pull request cannot be automatically merged.", can you rebase this?

@robertjwhitney

@sgerrand already fixed, thx.

@robertjwhitney

@tenderlove @davidcelis the change method doesn't seem to take time_zone as an option.

# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 73
def change(options)
  ::Time.send(
    utc? ? :utc_time : :local_time,
    options[:year]  || year,
    options[:month] || month,
    options[:day]   || day,
    options[:hour]  || hour,
    options[:min]   || (options[:hour] ? 0 : min),
    options[:sec]   || ((options[:hour] || options[:min]) ? 0 : sec),
    options[:usec]  || ((options[:hour] || options[:min] || options[:sec]) ? 0 : usec)
  )
end

So then I was looking at using in_time_zone("GMT") but realized Date doesn't have that method. Does something like this work?

def end_of_days
  result = acts_like?(:time) ? in_time_zone("GMT") : self
  result.change(:year => 2012, :month => 12, :day => 21, :hour => 11, :min => 11)
end

Or can you help me think of a better way to do this?

@tenderlove
Owner

@robertjwhitney this is probably good enough:

irb(main):001:0> Time.new(2012, 12, 21, 11, 11, 0, "+00:00")
=> 2012-12-21 11:11:00 +0000
irb(main):002:0> 

I assume the apocalypse will not change, so presumably you could just change the implementation to:

def end_of_days
  Time.new(2012, 12, 21, 11, 11, 0, "+00:00")
end

(I'm not sure if this works on 1.9.3, someone needs to test)

@sgerrand

@tenderlove @robertjwhitney Fine on 1.9.3:

irb(main):001:0> RUBY_VERSION
=> "1.9.3"
irb(main):002:0> Time.new(2012, 12, 21, 11, 11, 0, "+00:00")
=> 2012-12-21 11:11:00 +0000
irb(main):003:0>

:shipit: :exclamation:

@luke-gru

should we freeze this date object?

...active_support/core_ext/date_and_time/calculations.rb
@@ -213,6 +213,13 @@ def end_of_year
end
alias :at_end_of_year :end_of_year
+ # Returns a new date/time representing the end of life as we know it.
+ # DateTime objects will have a time set to 00:00:00
@frodsan
frodsan added a note

Can you add an example reflecting the end_of_days?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
activesupport/test/core_ext/time_with_zone_test.rb
@@ -501,6 +501,11 @@ def test_end_of_year
assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_year.inspect
end
+ def test_end_of_days
+ assert_equal "Fri, 31 Dec 1999 19:00:00 EST -5:00", @twz.inpsect

[TYPO] @twz.inspect

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lrz

Is there a chance we could have a pure-ruby implementation that does not use eval? I would like to incorporate the code into RubyMotion (as a NSDate category).

@rmoriz

I've contacted @dhh on twitter to take over this stale issue due to the importance and popularity :trollface:

@rishav

i think "freeze" is a good option.

@AlexanderZaytsev

I used Timecop.travel to test for negative values... YOU DON'T WANT TO KNOW WHAT I SAW.

@robertjwhitney

@tenderlove yeah but what if you were trying to operate on a Date? Are you saying the method should always return a Time?

@vjt

:smile: made my (before end of) day :dancers:

@philduffy

Mayans would be in CST (UTC-6). This pull request will lull us all into a fall sense of security when we don't die at the time represented in end_of_days, but rather one hour later.

@tenderlove
Owner

@robertjwhitney I think either will work, but you can just call to_date on the time.

@fightingmonk

@radar Surely @davidcelis question about thread safety is relevant, short-lived things always bring out the race conditions.

@shanepinnell

Will this go negative after EOD? So 1 day after EOD would be -1 EOD?

@robertjwhitney

@shanepinnell not sure that's a valid case.

activesupport/test/core_ext/date_and_time_behavior.rb
@@ -1,5 +1,4 @@
require 'abstract_unit'
-

We didn't need this line anyway

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@tenderlove
Owner

I think we're good now. Can you rebase?

@wuputah

I've been waiting 5125 years for this! :fireworks:

@davidcelis

@robertjwhitney could you please squash the commits into one for a cleaner history?

@robertjwhitney

@davidcelis good call. makes it nicer in case there are any survivors or people who don't get raptured.

activesupport/CHANGELOG.md
@@ -1,6 +1,10 @@
## Rails 4.0.0 (unreleased) ##
-* Remove surrogate unicode character encoding from `ActiveSupport::JSON.encode`
+* Allow calculation of seconds until end_of_days, and conversion of time to end_of_days.
+
+ *Robert Whitney*
+
+* Remove surrogate unicode character encoding from ActiveSupport::JSON.encode

This line shouldn't have changed. Also the indentation of the lines above are not correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ButuzGOL

Why this time 11:11:00 +0000 ?

@davidcelis

@ButuzGOL that was when the winter solstice was.

@all, it looks like we can close this pull request. False alarm.

@robertjwhitney

Thanks for your help on this :family: everybody. Looks like it might be awhile until this feature is necessary.

@guilleiguaran

@robertjwhitney Thanks for your contribution!

@allomov

Sometimes github misses Twitter button. My thumb up :+1:

@tenderlove
Owner

@robertjwhitney THANK YOU! :-D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 20, 2012
  1. @robertjwhitney
This page is out of date. Refresh to see the latest.
View
4 activesupport/CHANGELOG.md
@@ -1,5 +1,9 @@
## Rails 4.0.0 (unreleased) ##
+* Allow calculation of seconds until end_of_days, and conversion of time to end_of_days.
+
+ *Robert Whitney*
+
* Remove surrogate unicode character encoding from `ActiveSupport::JSON.encode`
The encoding scheme was broken for unicode characters outside the basic multilingual plane;
since json is assumed to be `UTF-8`, and we already force the encoding to `UTF-8`,
View
6 activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -77,6 +77,12 @@ def end_of_day
end
alias :at_end_of_day :end_of_day
+ # Converts Date to a Time reflecting the apocolypse (2012-12-21 11:11:00 GMT)
+ def end_of_days
+ Time.new(2012, 12, 21, 11, 11, 0, "+00:00")
+ end
+ alias :at_end_of_days :end_of_days
+
def plus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
other.since(self)
View
8 activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
@@ -213,6 +213,14 @@ def end_of_year
end
alias :at_end_of_year :end_of_year
+ # Returns a new date/time representing the end of life as we know it.
+ # DateTime objects will have a time set to 11:11:00 GMT
+ def end_of_days
+ result = Time.new(2012, 12, 21, 11, 11, 0, "+00:00")
+ acts_like?(:time) ? result : result.to_date
+ end
+ alias :at_end_of_days :end_of_days
+
private
def first_hour
View
13 activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -41,6 +41,13 @@ def seconds_until_end_of_day
end_of_day.to_i - to_i
end
+ # Returns the number of seconds until 2012-12-21 00:00:00
+ #
+ # DateTime.new(2012, 12, 19, 15, 51, 55).seconds_until_end_of_days # => 115685
+ def seconds_until_end_of_days
+ end_of_days.to_i - to_i
+ end
+
# Returns a new DateTime where one or more of the elements have been changed
# according to the +options+ parameter. The time options (<tt>:hour</tt>,
# <tt>:minute</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
@@ -112,6 +119,12 @@ def end_of_day
end
alias :at_end_of_day :end_of_day
+ # Returns a new DateTime representing the end of the world (2012-12-21 11:11:00 +00:00)
+ def end_of_days
+ DateTime.new(2012, 12, 21, 11, 11, 0, "+00:00")
+ end
+ alias :at_end_of_days :end_of_days
+
# Returns a new DateTime representing the start of the hour (hh:00:00).
def beginning_of_hour
change(:min => 0)
View
5 activesupport/test/core_ext/date_and_time_behavior.rb
@@ -214,6 +214,11 @@ def test_end_of_year
assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,12,31,10,10,10).end_of_year
end
+ def test_end_of_days
+ assert_equal Time.new(2012,12,21,11,11,00,"+00:00"), date_time_init(2012,12,19,3,35,30).end_of_days
+ assert_equal Time.new(2012,12,21,11,11,00,"+00:00"), date_time_init(2013,1,1,3,35,30).end_of_days
+ end
+
def test_monday_with_default_beginning_of_week_set
with_bw_default(:saturday) do
assert_equal date_time_init(2012,9,17,0,0,0), date_time_init(2012,9,18,0,0,0).monday
View
4 activesupport/test/core_ext/date_ext_test.rb
@@ -78,6 +78,10 @@ def test_end_of_year
assert_equal Date.new(2008,12,31).to_s, Date.new(2008,2,22).end_of_year.to_s
end
+ def test_end_of_days
+ assert_equal Time.new(2012,12,21,11,11,00,"+00:00").to_s, Date.new(2012,12,19).end_of_days.to_s
+ end
+
def test_end_of_month
assert_equal Date.new(2005,3,31), Date.new(2005,3,20).end_of_month
assert_equal Date.new(2005,2,28), Date.new(2005,2,20).end_of_month
View
8 activesupport/test/core_ext/date_time_ext_test.rb
@@ -69,6 +69,14 @@ def test_seconds_until_end_of_day
assert_equal 86399, DateTime.civil(2005,1,1,0,0,0).seconds_until_end_of_day
end
+ def test_seconds_until_end_of_days
+ assert_equal 0, DateTime.civil(2012,12,21,11,11,00).seconds_until_end_of_days
+ assert_equal 1, DateTime.civil(2012,12,21,11,10,59).seconds_until_end_of_days
+ assert_equal 60, DateTime.civil(2012,12,21,11,10,00).seconds_until_end_of_days
+ assert_equal 3660, DateTime.civil(2012,12,21,10,10,00).seconds_until_end_of_days
+ assert_equal 86399, DateTime.civil(2012,12,20,11,11,01).seconds_until_end_of_days
+ end
+
def test_beginning_of_day
assert_equal DateTime.civil(2005,2,4,0,0,0), DateTime.civil(2005,2,4,10,10,10).beginning_of_day
end
View
5 activesupport/test/core_ext/time_with_zone_test.rb
@@ -501,6 +501,11 @@ def test_end_of_year
assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_year.inspect
end
+ def test_end_of_days
+ assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+ assert_equal "Fri, 21 Dec 2012 11:11:00 EST -05:00", @twz.end_of_days.inspect
+ end
+
def test_beginning_of_month
assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
assert_equal "Wed, 01 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_month.inspect
Something went wrong with that request. Please try again.