merch_calendar 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +71 -0
- data/LICENSE +19 -0
- data/README.md +93 -0
- data/Rakefile +7 -0
- data/lib/merch_calendar/configurable.rb +28 -0
- data/lib/merch_calendar/configuration.rb +13 -0
- data/lib/merch_calendar/date_calculator.rb +103 -0
- data/lib/merch_calendar/merch_week.rb +224 -0
- data/lib/merch_calendar/util.rb +160 -0
- data/lib/merch_calendar/version.rb +3 -0
- data/lib/merch_calendar.rb +12 -0
- data/merch_calendar.gemspec +26 -0
- data/spec/merch_calendar/configurable_spec.rb +19 -0
- data/spec/merch_calendar/configuration_spec.rb +17 -0
- data/spec/merch_calendar/date_calculator_spec.rb +52 -0
- data/spec/merch_calendar/merch_week_spec.rb +175 -0
- data/spec/merch_calendar/util_spec.rb +105 -0
- data/spec/merch_calendar_spec.rb +58 -0
- data/spec/spec_helper.rb +17 -0
- metadata +145 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 94429998c8a78882cafaba7e479b5a8af2e75b08
|
|
4
|
+
data.tar.gz: d1ece80b55e67aa6dd9236888095770f13a7aedb
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 505cbc69d351c12bb201d6d720c2504542a2d4f3998983bf006580a89fb9c72b4cd63e5b18ae301d69c7cb17a38938b8e9ccd819bf1ca9e15f49915eb05cc458
|
|
7
|
+
data.tar.gz: caad2d4f70d937baaf692eca58f46829644c318a9436b9bb14029f62182c520f3ad2a8c009b261fedec3861122221c5da46108d215abc7c2de10060d091951f1
|
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.1.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
merch_calendar (0.0.1)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://www.rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
coderay (1.1.0)
|
|
10
|
+
coveralls (0.8.1)
|
|
11
|
+
json (~> 1.8)
|
|
12
|
+
rest-client (>= 1.6.8, < 2)
|
|
13
|
+
simplecov (~> 0.10.0)
|
|
14
|
+
term-ansicolor (~> 1.3)
|
|
15
|
+
thor (~> 0.19.1)
|
|
16
|
+
diff-lcs (1.2.5)
|
|
17
|
+
docile (1.1.5)
|
|
18
|
+
domain_name (0.5.24)
|
|
19
|
+
unf (>= 0.0.5, < 1.0.0)
|
|
20
|
+
http-cookie (1.0.2)
|
|
21
|
+
domain_name (~> 0.5)
|
|
22
|
+
json (1.8.2)
|
|
23
|
+
method_source (0.8.2)
|
|
24
|
+
mime-types (2.5)
|
|
25
|
+
netrc (0.10.3)
|
|
26
|
+
pry (0.10.1)
|
|
27
|
+
coderay (~> 1.1.0)
|
|
28
|
+
method_source (~> 0.8.1)
|
|
29
|
+
slop (~> 3.4)
|
|
30
|
+
rake (10.4.2)
|
|
31
|
+
rest-client (1.8.0)
|
|
32
|
+
http-cookie (>= 1.0.2, < 2.0)
|
|
33
|
+
mime-types (>= 1.16, < 3.0)
|
|
34
|
+
netrc (~> 0.7)
|
|
35
|
+
rspec (3.2.0)
|
|
36
|
+
rspec-core (~> 3.2.0)
|
|
37
|
+
rspec-expectations (~> 3.2.0)
|
|
38
|
+
rspec-mocks (~> 3.2.0)
|
|
39
|
+
rspec-core (3.2.2)
|
|
40
|
+
rspec-support (~> 3.2.0)
|
|
41
|
+
rspec-expectations (3.2.0)
|
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
43
|
+
rspec-support (~> 3.2.0)
|
|
44
|
+
rspec-mocks (3.2.1)
|
|
45
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
46
|
+
rspec-support (~> 3.2.0)
|
|
47
|
+
rspec-support (3.2.2)
|
|
48
|
+
simplecov (0.10.0)
|
|
49
|
+
docile (~> 1.1.0)
|
|
50
|
+
json (~> 1.8)
|
|
51
|
+
simplecov-html (~> 0.10.0)
|
|
52
|
+
simplecov-html (0.10.0)
|
|
53
|
+
slop (3.6.0)
|
|
54
|
+
term-ansicolor (1.3.0)
|
|
55
|
+
tins (~> 1.0)
|
|
56
|
+
thor (0.19.1)
|
|
57
|
+
tins (1.5.1)
|
|
58
|
+
unf (0.1.4)
|
|
59
|
+
unf_ext
|
|
60
|
+
unf_ext (0.0.7.1)
|
|
61
|
+
|
|
62
|
+
PLATFORMS
|
|
63
|
+
ruby
|
|
64
|
+
|
|
65
|
+
DEPENDENCIES
|
|
66
|
+
coveralls
|
|
67
|
+
merch_calendar!
|
|
68
|
+
pry
|
|
69
|
+
rake
|
|
70
|
+
rspec (>= 3.0.0)
|
|
71
|
+
simplecov
|
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2015 Stitch Fix
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Merch Calendar
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/stitchfix/merch_calendar)
|
|
4
|
+
[](https://codeclimate.com/github/stitchfix/merch_calendar)
|
|
5
|
+
[](https://coveralls.io/r/stitchfix/merch_calendar)
|
|
6
|
+
|
|
7
|
+
This gem allows for finding retail/merchandising weeks for a given date, along with manipulating the retail calendar. This gem is used at [StitchFix](http://www.stitchfix.com/).
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
$ gem install merch_calendar
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Add the following line to your `Gemfile`:
|
|
16
|
+
```ruby
|
|
17
|
+
gem "merch_calendar"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
```ruby
|
|
23
|
+
# NOTE: Configuration will be added soon, but is currently NOT available.
|
|
24
|
+
MerchCalendar.configure do |config|
|
|
25
|
+
# The month that Q1 begins. The default is 8 (August)
|
|
26
|
+
config.quarter_start_month = 8
|
|
27
|
+
end
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
For converting a date into a `MerchWeek` object.
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
merch_week = MerchCalendar::MerchWeek.from_date("2014-01-01")
|
|
36
|
+
puts merch_week.year # 2013 (the merch year associated with this date)
|
|
37
|
+
puts merch_week.month # 12 (the julian month that the date falls in)
|
|
38
|
+
puts merch_week.week # 5 (the week number within the month)
|
|
39
|
+
puts merch_week.year_week # 48 (the week number within the year)
|
|
40
|
+
puts merch_week.quarter # 2
|
|
41
|
+
|
|
42
|
+
puts merch_week.start_of_week # <Date: 2013-12-29>
|
|
43
|
+
puts merch_week.end_of_week # <Date>
|
|
44
|
+
|
|
45
|
+
puts merch_week.start_of_month # <Date>
|
|
46
|
+
puts merch_week.end_of_month # <Date>
|
|
47
|
+
|
|
48
|
+
puts merch_week.start_of_quarter # <Date>
|
|
49
|
+
puts merch_week.end_of_quarter # <Date>
|
|
50
|
+
|
|
51
|
+
puts merch_week.start_of_year # <Date>
|
|
52
|
+
puts merch_week.end_of_year # <Date>
|
|
53
|
+
|
|
54
|
+
# Formatting
|
|
55
|
+
puts merch_week.to_s # "Dec W5"
|
|
56
|
+
puts merch_week.to_s(:short) # "Dec W5"
|
|
57
|
+
puts merch_week.to_s(:long) # "2013:48 Dec W5"
|
|
58
|
+
puts merch_week.to_s(:elasticsearch) # "2013-12w05"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This can also be used on the `MerchCalendar` module. All `start_` and `end_` methods can be called, along with a few additional ones.
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
# All examples below return a Date object for the start of May within the 2014 merch year
|
|
65
|
+
MerchCalendar.start_of_month(2014, 5)
|
|
66
|
+
MerchCalendar.start_of_month(2014, month: 5)
|
|
67
|
+
MerchCalendar.start_of_month(2014, julian_month: 5)
|
|
68
|
+
|
|
69
|
+
# This is the same as May, because "Merch" months are shifted by 1.
|
|
70
|
+
# i.e. month 1 is actually February
|
|
71
|
+
# You probably will never use this, but it is available.
|
|
72
|
+
MerchCalendar.start_of_month(2014, merch_month: 4)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Other useful methods:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
# 52 or 53 (depending on leap year)
|
|
79
|
+
MerchCalendar.weeks_in_year(2015)
|
|
80
|
+
|
|
81
|
+
# returns an array of MerchWeek objects for each week within the provided month
|
|
82
|
+
MerchCalendar.weeks_for_month(2014, 1)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Documentation
|
|
86
|
+
You can view the documentation for this gem on [RubyDoc.info](http://www.rubydoc.info/github/stitchfix/merch_calendar/master).
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
## Roadmap
|
|
90
|
+
* Support for 4-4-5 calendars
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
MerchCalendar is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module MerchCalendar
|
|
2
|
+
class << self
|
|
3
|
+
|
|
4
|
+
attr_writer :configuration
|
|
5
|
+
|
|
6
|
+
# Returns the global configuration object
|
|
7
|
+
#
|
|
8
|
+
# @return [Configuration]
|
|
9
|
+
def configuration
|
|
10
|
+
@configuration ||= Configuration.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Used in initializers to set the global configuration
|
|
14
|
+
#
|
|
15
|
+
# @return [void]
|
|
16
|
+
def configure
|
|
17
|
+
yield(configuration)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Resets the configuration to default values
|
|
21
|
+
#
|
|
22
|
+
# @return [void]
|
|
23
|
+
def reset_config!
|
|
24
|
+
@configuration = Configuration.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module MerchCalendar
|
|
2
|
+
|
|
3
|
+
# @api private
|
|
4
|
+
class DateCalculator
|
|
5
|
+
|
|
6
|
+
def end_of_year(year)
|
|
7
|
+
year_end = Date.new (year + 1), 1, -1
|
|
8
|
+
wday = (year_end.wday + 1) % 7
|
|
9
|
+
|
|
10
|
+
if wday > 3
|
|
11
|
+
year_end += 7 - wday
|
|
12
|
+
elsif wday > 0
|
|
13
|
+
year_end -= wday
|
|
14
|
+
end
|
|
15
|
+
year_end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# The day after last years' end date
|
|
19
|
+
def start_of_year(year)
|
|
20
|
+
end_of_year(year - 1) + 1
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# The starting date of a given month
|
|
24
|
+
# THIS IS THE MERCH MONTH
|
|
25
|
+
# 1 = feb
|
|
26
|
+
#
|
|
27
|
+
def start_of_month(year, merch_month)
|
|
28
|
+
# 91 = number of days in a single 4-5-4 set
|
|
29
|
+
start = start_of_year(year) + ((merch_month - 1) / 3).to_i * 91
|
|
30
|
+
|
|
31
|
+
case merch_month
|
|
32
|
+
when 2,5,8,11
|
|
33
|
+
# 28 = 4 weeks
|
|
34
|
+
start = start + 28
|
|
35
|
+
when 3,6,9,12
|
|
36
|
+
# The 5 week months
|
|
37
|
+
# 63 = 4 weeks + 5 weeks
|
|
38
|
+
start = start + 63
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
start
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def end_of_month(year, merch_month)
|
|
45
|
+
if merch_month == 12
|
|
46
|
+
end_of_year(year)
|
|
47
|
+
else
|
|
48
|
+
start_of_month(year, merch_month + 1) - 1
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Return the starting date for a particular quarter
|
|
53
|
+
def start_of_quarter(year, quarter)
|
|
54
|
+
case quarter
|
|
55
|
+
when 1
|
|
56
|
+
start_of_month(year, 7)
|
|
57
|
+
when 2
|
|
58
|
+
start_of_month(year, 10)
|
|
59
|
+
when 3
|
|
60
|
+
start_of_month(year, 1)
|
|
61
|
+
when 4
|
|
62
|
+
start_of_month(year, 4)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Return the ending date for a particular quarter
|
|
67
|
+
def end_of_quarter(year, quarter)
|
|
68
|
+
case quarter
|
|
69
|
+
when 1
|
|
70
|
+
end_of_month(year, 9)
|
|
71
|
+
when 2
|
|
72
|
+
end_of_month(year, 12)
|
|
73
|
+
when 3
|
|
74
|
+
end_of_month(year, 3)
|
|
75
|
+
when 4
|
|
76
|
+
end_of_month(year, 6)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Return the number of weeks in a particular year
|
|
81
|
+
def weeks_in_year(year)
|
|
82
|
+
((start_of_year(year + 1) - start_of_year(year)) / 7).to_i
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def merch_to_julian(merch_month)
|
|
86
|
+
if merch_month == 12
|
|
87
|
+
1
|
|
88
|
+
else
|
|
89
|
+
merch_month + 1
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def julian_to_merch(julian_month)
|
|
94
|
+
if julian_month == 1
|
|
95
|
+
12
|
|
96
|
+
else
|
|
97
|
+
julian_month - 1
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
module MerchCalendar
|
|
2
|
+
|
|
3
|
+
# Represents the Merch Week for a specified date.
|
|
4
|
+
class MerchWeek
|
|
5
|
+
|
|
6
|
+
MONTHS = %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).freeze
|
|
7
|
+
|
|
8
|
+
# The Julian date that is being represented
|
|
9
|
+
#
|
|
10
|
+
# @!attribute [r] date
|
|
11
|
+
# @return [Date] the date for this merch week
|
|
12
|
+
attr_reader :date
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
|
|
16
|
+
# Locates the +MerchWeek+ for a given Julian date.
|
|
17
|
+
#
|
|
18
|
+
# @overload from_date(String)
|
|
19
|
+
# @param [String] julian_date a julian date in the format of +YYYY-MM-DD+
|
|
20
|
+
# @overload from_date(Date)
|
|
21
|
+
# @param [Date] julian_date a +Date+ object
|
|
22
|
+
#
|
|
23
|
+
# @return [MerchWeek]
|
|
24
|
+
def from_date(julian_date)
|
|
25
|
+
MerchWeek.new Date.parse("#{julian_date}")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns an array of merch weeks for a month, or a specific week.
|
|
29
|
+
#
|
|
30
|
+
# @overload find(year, julian_month)
|
|
31
|
+
# Returns an array of +MerchWeek+s for a given month
|
|
32
|
+
# @param year [Fixnum] the merch year to locate
|
|
33
|
+
# @param julian_month [Fixnum] the month to find merch months for
|
|
34
|
+
# @return [Array<MerchWeek>]
|
|
35
|
+
# @overload find(year, julian_month, week_number)
|
|
36
|
+
# @param year [Fixnum] the merch year to locate
|
|
37
|
+
# @param julian_month [Fixnum] the month to find merch months for
|
|
38
|
+
# @param week_number [Fixnum] the specific week number.
|
|
39
|
+
# @return [MerchWeek] the specific merch week
|
|
40
|
+
def find(year, julian_month, week_number=nil)
|
|
41
|
+
if week_number.nil?
|
|
42
|
+
MerchCalendar.weeks_for_month(year, julian_month)
|
|
43
|
+
else
|
|
44
|
+
MerchCalendar.weeks_for_month(year, julian_month)[week_number-1]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns the +MerchWeek+ for today's date
|
|
49
|
+
#
|
|
50
|
+
# @return [MerchWeek]
|
|
51
|
+
def today
|
|
52
|
+
MerchWeek.from_date Date.today
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Pass in a date, make sure it is a valid date object
|
|
59
|
+
# @private
|
|
60
|
+
def initialize(date, options = {})
|
|
61
|
+
@date = date
|
|
62
|
+
|
|
63
|
+
# Placeholders. These should be populated by functions if nil
|
|
64
|
+
# week_start: nil, week_end: nil, week_number: nil
|
|
65
|
+
@start_of_year = options[:start_of_year]
|
|
66
|
+
@end_of_year = options[:end_of_year]
|
|
67
|
+
|
|
68
|
+
@start_of_week = options[:start_of_week]
|
|
69
|
+
@end_of_week = options[:end_of_week]
|
|
70
|
+
@week = options[:week]
|
|
71
|
+
|
|
72
|
+
@start_of_month = options[:start_of_month]
|
|
73
|
+
@end_of_month = options[:end_of_month]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# What week it is within the year from 1-53
|
|
77
|
+
#
|
|
78
|
+
# @return [Fixnum] The week number of the year, from 1-53
|
|
79
|
+
def year_week
|
|
80
|
+
@year_week ||= (((date-start_of_year)+1)/7.0).ceil
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# This returns the "merch month" number for a date
|
|
84
|
+
# Merch months are shifted by one. Month 1 is Feb
|
|
85
|
+
#
|
|
86
|
+
# @return [Fixnum]
|
|
87
|
+
def merch_month
|
|
88
|
+
# TODO: This is very inefficient, but less complex than strategic guessing
|
|
89
|
+
# maybe switch to a binary search or something
|
|
90
|
+
@merch_month ||= (1..12).detect do |num|
|
|
91
|
+
date_calc.end_of_month(start_of_year.year, num) >= date && date >= date_calc.start_of_month(start_of_year.year, num)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# The merch year
|
|
96
|
+
#
|
|
97
|
+
# @return [Fixnum]
|
|
98
|
+
def year
|
|
99
|
+
start_of_year.year
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# The julian month that this merch week falls in
|
|
103
|
+
#
|
|
104
|
+
# @return [Fixnum]
|
|
105
|
+
def month
|
|
106
|
+
@month ||= date_calc.merch_to_julian(merch_month)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# The specific quarter this week falls in
|
|
110
|
+
#
|
|
111
|
+
# @return [Fixnum]
|
|
112
|
+
def quarter
|
|
113
|
+
case merch_month
|
|
114
|
+
when 7,8,9
|
|
115
|
+
return 1
|
|
116
|
+
when 10,11,12
|
|
117
|
+
return 2
|
|
118
|
+
when 1,2,3
|
|
119
|
+
return 3
|
|
120
|
+
else
|
|
121
|
+
return 4
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Returns the date of the start of this week
|
|
126
|
+
#
|
|
127
|
+
# @return [Date]
|
|
128
|
+
def start_of_week
|
|
129
|
+
@start_of_week ||= (start_of_month + (7 * (week - 1)))
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Returns the date of the end of this week
|
|
133
|
+
#
|
|
134
|
+
# @return [Date]
|
|
135
|
+
def end_of_week
|
|
136
|
+
@end_of_week ||= (start_of_week + 6)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# the number of the week within the given month
|
|
140
|
+
# will be between 1 and 5
|
|
141
|
+
#
|
|
142
|
+
# @return [Fixnum]
|
|
143
|
+
def week
|
|
144
|
+
@week ||= (((date-start_of_month)+1)/7.0).ceil
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# The date of the start of the corresponding merch year
|
|
148
|
+
#
|
|
149
|
+
# @return [Date]
|
|
150
|
+
def start_of_year
|
|
151
|
+
@start_of_year ||= year_start_date
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# The end date of the corresponding merch year
|
|
155
|
+
#
|
|
156
|
+
# @return [Date]
|
|
157
|
+
def end_of_year
|
|
158
|
+
@end_of_year ||= date_calc.end_of_year(year)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# The start date of the merch month
|
|
162
|
+
#
|
|
163
|
+
# @return [Date]
|
|
164
|
+
def start_of_month
|
|
165
|
+
@start_of_month ||= date_calc.start_of_month(year, merch_month)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# The end date of the merch month
|
|
169
|
+
#
|
|
170
|
+
# @return [Date]
|
|
171
|
+
def end_of_month
|
|
172
|
+
@end_of_month ||= date_calc.end_of_month(year, merch_month)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# The merch season this date falls under.
|
|
176
|
+
# Returns a string of +Fall/Winter+ or +Spring/Summer+
|
|
177
|
+
#
|
|
178
|
+
# @return [String]
|
|
179
|
+
def season
|
|
180
|
+
case merch_month
|
|
181
|
+
when 1,2,3,4,5,6
|
|
182
|
+
"Spring/Summer"
|
|
183
|
+
when 7,8,9,10,11,12
|
|
184
|
+
"Fall/Winter"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Outputs a text representation of this merch week
|
|
189
|
+
#
|
|
190
|
+
# Format keys:
|
|
191
|
+
# * +:short+ (default) "Dec W5"
|
|
192
|
+
# * +:long+ "2012:48 Dec W5"
|
|
193
|
+
# * +:elasticsearch+ (default) "2012-12w05"
|
|
194
|
+
#
|
|
195
|
+
# @param format [Symbol] the format identifier to return. Default is +:short+
|
|
196
|
+
#
|
|
197
|
+
# @return [Date]
|
|
198
|
+
def to_s(format = :short)
|
|
199
|
+
case format
|
|
200
|
+
when :elasticsearch
|
|
201
|
+
sprintf("%04d-%02dw%02d", year, month, week)
|
|
202
|
+
when :long
|
|
203
|
+
"#{year}:#{year_week} #{self.to_s(:short)}"
|
|
204
|
+
else
|
|
205
|
+
"#{MONTHS[month - 1]} W#{week}"
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
private
|
|
210
|
+
|
|
211
|
+
def year_start_date
|
|
212
|
+
start_date = date_calc.start_of_year(date.year)
|
|
213
|
+
if start_date > date
|
|
214
|
+
start_date = date_calc.start_of_year(date.year - 1)
|
|
215
|
+
end
|
|
216
|
+
start_date
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def date_calc
|
|
220
|
+
@date_calc ||= DateCalculator.new
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
end
|
|
224
|
+
end
|