mirror of https://github.com/rails/rails
Merge pull request #5339 from gregolsen/week_start_config
week_start option added to rails app config
This commit is contained in:
commit
5428de1efd
|
@ -1,5 +1,7 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* `Date.beginning_of_week` thread local and `beginning_of_week` application config option added (default is Monday). *Innokenty Mikhailov*
|
||||
|
||||
* An optional block can be passed to `config_accessor` to set its default value
|
||||
|
||||
class User
|
||||
|
|
|
@ -9,6 +9,29 @@ class Date
|
|||
include DateAndTime::Calculations
|
||||
|
||||
class << self
|
||||
attr_accessor :beginning_of_week_default
|
||||
|
||||
# Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
|
||||
# If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
|
||||
# If no config.beginning_of_week was specified, returns :monday.
|
||||
def beginning_of_week
|
||||
Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
|
||||
end
|
||||
|
||||
# Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
|
||||
#
|
||||
# This method accepts any of the following day symbols:
|
||||
# :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
|
||||
def beginning_of_week=(week_start)
|
||||
Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
|
||||
end
|
||||
|
||||
# Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.
|
||||
def find_beginning_of_week!(week_start)
|
||||
raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.keys.include?(week_start)
|
||||
week_start
|
||||
end
|
||||
|
||||
# Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
|
||||
def yesterday
|
||||
::Date.current.yesterday
|
||||
|
|
|
@ -109,10 +109,11 @@ module DateAndTime
|
|||
alias :at_beginning_of_year :beginning_of_year
|
||||
|
||||
# Returns a new date/time representing the given day in the next week.
|
||||
# Default is :monday.
|
||||
# Week is assumed to start on +start_day+, default is
|
||||
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
||||
# DateTime objects have their time set to 0:00.
|
||||
def next_week(day = :monday)
|
||||
first_hour{ weeks_since(1).beginning_of_week.days_since(DAYS_INTO_WEEK[day]) }
|
||||
def next_week(start_day = Date.beginning_of_week)
|
||||
first_hour{ weeks_since(1).beginning_of_week.days_since(days_span(start_day)) }
|
||||
end
|
||||
|
||||
# Short-hand for months_since(1).
|
||||
|
@ -131,10 +132,11 @@ module DateAndTime
|
|||
end
|
||||
|
||||
# Returns a new date/time representing the given day in the previous week.
|
||||
# Default is :monday.
|
||||
# Week is assumed to start on +start_day+, default is
|
||||
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
||||
# DateTime objects have their time set to 0:00.
|
||||
def prev_week(day = :monday)
|
||||
first_hour{ weeks_ago(1).beginning_of_week.days_since(DAYS_INTO_WEEK[day]) }
|
||||
def prev_week(start_day = Date.beginning_of_week)
|
||||
first_hour{ weeks_ago(1).beginning_of_week.days_since(days_span(start_day)) }
|
||||
end
|
||||
alias_method :last_week, :prev_week
|
||||
|
||||
|
@ -157,31 +159,44 @@ module DateAndTime
|
|||
alias_method :last_year, :prev_year
|
||||
|
||||
# Returns the number of days to the start of the week on the given day.
|
||||
# Default is :monday.
|
||||
def days_to_week_start(start_day = :monday)
|
||||
# Week is assumed to start on +start_day+, default is
|
||||
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
||||
def days_to_week_start(start_day = Date.beginning_of_week)
|
||||
start_day_number = DAYS_INTO_WEEK[start_day]
|
||||
current_day_number = wday != 0 ? wday - 1 : 6
|
||||
(current_day_number - start_day_number) % 7
|
||||
end
|
||||
|
||||
# Returns a new date/time representing the start of this week on the given day.
|
||||
# Default is :monday.
|
||||
# DateTime objects have their time set to 0:00.
|
||||
def beginning_of_week(start_day = :monday)
|
||||
# Week is assumed to start on +start_day+, default is
|
||||
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
||||
# +DateTime+ objects have their time set to 0:00.
|
||||
def beginning_of_week(start_day = Date.beginning_of_week)
|
||||
result = days_ago(days_to_week_start(start_day))
|
||||
acts_like?(:time) ? result.midnight : result
|
||||
end
|
||||
alias :at_beginning_of_week :beginning_of_week
|
||||
alias :monday :beginning_of_week
|
||||
|
||||
# Returns Monday of this week assuming that week starts on Monday.
|
||||
# +DateTime+ objects have their time set to 0:00.
|
||||
def monday
|
||||
beginning_of_week(:monday)
|
||||
end
|
||||
|
||||
# Returns a new date/time representing the end of this week on the given day.
|
||||
# Default is :monday (i.e end of Sunday).
|
||||
# Week is assumed to start on +start_day+, default is
|
||||
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
||||
# DateTime objects have their time set to 23:59:59.
|
||||
def end_of_week(start_day = :monday)
|
||||
def end_of_week(start_day = Date.beginning_of_week)
|
||||
last_hour{ days_since(6 - days_to_week_start(start_day)) }
|
||||
end
|
||||
alias :at_end_of_week :end_of_week
|
||||
alias :sunday :end_of_week
|
||||
|
||||
# Returns Sunday of this week assuming that week starts on Monday.
|
||||
# +DateTime+ objects have their time set to 23:59:59.
|
||||
def sunday
|
||||
end_of_week(:monday)
|
||||
end
|
||||
|
||||
# Returns a new date/time representing the end of the month.
|
||||
# DateTime objects will have a time set to 23:59:59.
|
||||
|
@ -209,5 +224,9 @@ module DateAndTime
|
|||
result = yield
|
||||
acts_like?(:time) ? result.end_of_day : result
|
||||
end
|
||||
|
||||
def days_span(day)
|
||||
(DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -169,8 +169,9 @@ class Time
|
|||
beginning_of_day..end_of_day
|
||||
end
|
||||
|
||||
# Returns a Range representing the whole week of the current time. Week starts on start_day (default is :monday, i.e. end of Sunday).
|
||||
def all_week(start_day = :monday)
|
||||
# Returns a Range representing the whole week of the current time.
|
||||
# Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
|
||||
def all_week(start_day = Date.beginning_of_week)
|
||||
beginning_of_week(start_day)..end_of_week(start_day)
|
||||
end
|
||||
|
||||
|
|
|
@ -27,6 +27,15 @@ module ActiveSupport
|
|||
Time.zone_default = zone_default
|
||||
end
|
||||
|
||||
# Sets the default week start
|
||||
# If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
|
||||
initializer "active_support.initialize_beginning_of_week" do |app|
|
||||
require 'active_support/core_ext/date/calculations'
|
||||
beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week)
|
||||
|
||||
Date.beginning_of_week_default = beginning_of_week_default
|
||||
end
|
||||
|
||||
initializer "active_support.set_configs" do |app|
|
||||
app.config.active_support.each do |k, v|
|
||||
k = "#{k}="
|
||||
|
|
|
@ -101,6 +101,15 @@ module DateAndTimeBehavior
|
|||
assert_equal date_time_init(2006,11,1,0,0,0), date_time_init(2006,10,23,0,0,0).next_week(:wednesday)
|
||||
end
|
||||
|
||||
def test_next_week_with_default_beginning_of_week_set
|
||||
with_bw_default(:tuesday) do
|
||||
assert_equal Time.local(2012, 3, 28), Time.local(2012, 3, 21).next_week(:wednesday)
|
||||
assert_equal Time.local(2012, 3, 31), Time.local(2012, 3, 21).next_week(:saturday)
|
||||
assert_equal Time.local(2012, 3, 27), Time.local(2012, 3, 21).next_week(:tuesday)
|
||||
assert_equal Time.local(2012, 4, 02), Time.local(2012, 3, 21).next_week(:monday)
|
||||
end
|
||||
end
|
||||
|
||||
def test_next_month_on_31st
|
||||
assert_equal date_time_init(2005,9,30,15,15,10), date_time_init(2005,8,31,15,15,10).next_month
|
||||
end
|
||||
|
@ -121,6 +130,15 @@ module DateAndTimeBehavior
|
|||
assert_equal date_time_init(2006,11,15,0,0,0), date_time_init(2006,11,23,0,0,0).prev_week(:wednesday)
|
||||
end
|
||||
|
||||
def test_prev_week_with_default_beginning_of_week
|
||||
with_bw_default(:tuesday) do
|
||||
assert_equal Time.local(2012, 3, 14), Time.local(2012, 3, 21).prev_week(:wednesday)
|
||||
assert_equal Time.local(2012, 3, 17), Time.local(2012, 3, 21).prev_week(:saturday)
|
||||
assert_equal Time.local(2012, 3, 13), Time.local(2012, 3, 21).prev_week(:tuesday)
|
||||
assert_equal Time.local(2012, 3, 19), Time.local(2012, 3, 21).prev_week(:monday)
|
||||
end
|
||||
end
|
||||
|
||||
def test_prev_month_on_31st
|
||||
assert_equal date_time_init(2004,2,29,10,10,10), date_time_init(2004,3,31,10,10,10).prev_month
|
||||
end
|
||||
|
@ -151,6 +169,18 @@ module DateAndTimeBehavior
|
|||
assert_equal 3, date_time_init(2011,11,9,0,0,0).days_to_week_start(:sunday)
|
||||
end
|
||||
|
||||
def test_days_to_week_start_with_default_set
|
||||
with_bw_default(:friday) do
|
||||
assert_equal 6, Time.local(2012,03,8,0,0,0).days_to_week_start
|
||||
assert_equal 5, Time.local(2012,03,7,0,0,0).days_to_week_start
|
||||
assert_equal 4, Time.local(2012,03,6,0,0,0).days_to_week_start
|
||||
assert_equal 3, Time.local(2012,03,5,0,0,0).days_to_week_start
|
||||
assert_equal 2, Time.local(2012,03,4,0,0,0).days_to_week_start
|
||||
assert_equal 1, Time.local(2012,03,3,0,0,0).days_to_week_start
|
||||
assert_equal 0, Time.local(2012,03,2,0,0,0).days_to_week_start
|
||||
end
|
||||
end
|
||||
|
||||
def test_beginning_of_week
|
||||
assert_equal date_time_init(2005,1,31,0,0,0), date_time_init(2005,2,4,10,10,10).beginning_of_week
|
||||
assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,11,28,0,0,0).beginning_of_week #monday
|
||||
|
@ -183,4 +213,24 @@ module DateAndTimeBehavior
|
|||
assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,2,22,10,10,10).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_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
|
||||
end
|
||||
end
|
||||
|
||||
def test_sunday_with_default_beginning_of_week_set
|
||||
with_bw_default(:wednesday) do
|
||||
assert_equal date_time_init(2012,9,23,23,59,59, Rational(999999999, 1000)), date_time_init(2012,9,19,0,0,0).sunday
|
||||
end
|
||||
end
|
||||
|
||||
def with_bw_default(bw = :monday)
|
||||
old_bw = Date.beginning_of_week
|
||||
Date.beginning_of_week = bw
|
||||
yield
|
||||
ensure
|
||||
Date.beginning_of_week = old_bw
|
||||
end
|
||||
end
|
||||
|
|
|
@ -135,6 +135,8 @@ NOTE. The `config.asset_path` configuration is ignored if the asset pipeline is
|
|||
|
||||
* `config.time_zone` sets the default time zone for the application and enables time zone awareness for Active Record.
|
||||
|
||||
* `config.beginning_of_week` sets the default beginning of week for the application. Accepts a valid week day symbol (e.g. `:monday`).
|
||||
|
||||
* `config.whiny_nils` enables or disables warnings when a certain set of methods are invoked on `nil` and it does not respond to them. Defaults to true in development and test environments.
|
||||
|
||||
### Configuring Assets
|
||||
|
@ -696,6 +698,8 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
|
|||
|
||||
* `active_support.initialize_time_zone` Sets the default time zone for the application based on the `config.time_zone` setting, which defaults to "UTC".
|
||||
|
||||
* `active_support.initialize_beginning_of_week` Sets the default beginnig of week for the application based on `config.beginning_of_week` setting, which defaults to `:monday`.
|
||||
|
||||
* `action_dispatch.configure` Configures the `ActionDispatch::Http::URL.tld_length` to be set to the value of `config.action_dispatch.tld_length`.
|
||||
|
||||
* `action_view.cache_asset_ids` Sets `ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids` to `false` when Active Support loads, but only if `config.cache_classes` is too.
|
||||
|
|
|
@ -13,7 +13,7 @@ module Rails
|
|||
:railties_order, :relative_url_root, :secret_token,
|
||||
:serve_static_assets, :ssl_options, :static_cache_control, :session_options,
|
||||
:time_zone, :reload_classes_only_on_change,
|
||||
:queue, :queue_consumer
|
||||
:queue, :queue_consumer, :beginning_of_week
|
||||
|
||||
attr_writer :log_level
|
||||
attr_reader :encoding
|
||||
|
@ -31,6 +31,7 @@ module Rails
|
|||
@session_store = :cookie_store
|
||||
@session_options = {}
|
||||
@time_zone = "UTC"
|
||||
@beginning_of_week = :monday
|
||||
@log_level = nil
|
||||
@middleware = app_middleware
|
||||
@generators = app_generators
|
||||
|
|
|
@ -445,6 +445,28 @@ module ApplicationTests
|
|||
end
|
||||
end
|
||||
|
||||
test "valid beginning of week is setup correctly" do
|
||||
add_to_config <<-RUBY
|
||||
config.root = "#{app_path}"
|
||||
config.beginning_of_week = :wednesday
|
||||
RUBY
|
||||
|
||||
require "#{app_path}/config/environment"
|
||||
|
||||
assert_equal :wednesday, Rails.application.config.beginning_of_week
|
||||
end
|
||||
|
||||
test "raises when an invalid beginning of week is defined in the config" do
|
||||
add_to_config <<-RUBY
|
||||
config.root = "#{app_path}"
|
||||
config.beginning_of_week = :invalid
|
||||
RUBY
|
||||
|
||||
assert_raise(ArgumentError) do
|
||||
require "#{app_path}/config/environment"
|
||||
end
|
||||
end
|
||||
|
||||
test "config.action_controller.perform_caching = false" do
|
||||
make_basic_app do |app|
|
||||
app.config.action_controller.perform_caching = false
|
||||
|
|
Loading…
Reference in New Issue