beginning_of_fortnight 1.0.0
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.
- data/lib/beginning_of_fortnight.rb +189 -0
- metadata +62 -0
@@ -0,0 +1,189 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Simon Baird
|
3
|
+
# Source:: https://github.com/simonbaird/beginning_of_fortnight
|
4
|
+
# License:: 'BSD-new' where the copyright holder is Simon Baird
|
5
|
+
#
|
6
|
+
# Extends ActiveSupport to provide these methods for Time and Date objects:
|
7
|
+
# * beginning_of_fortnight
|
8
|
+
# * end_of_fortnight
|
9
|
+
# * next_fortnight
|
10
|
+
#
|
11
|
+
# These methods should work similarly to beginning_of_week, end_of_week and next_week.
|
12
|
+
#
|
13
|
+
# This gem requires that you have a version of activesupport that defines beginning_of_week.
|
14
|
+
#
|
15
|
+
# =Installation
|
16
|
+
#
|
17
|
+
# sudo gem install beginning_of_fortnight
|
18
|
+
#
|
19
|
+
# =Usage
|
20
|
+
#
|
21
|
+
# ===Basic usage
|
22
|
+
#
|
23
|
+
# require 'rubygems'
|
24
|
+
# require 'beginning_of_fortnight'
|
25
|
+
#
|
26
|
+
# now = Time.now
|
27
|
+
# puts now.beginning_of_fortnight
|
28
|
+
# puts now.end_of_fortnight
|
29
|
+
#
|
30
|
+
# ===Explicitly setting a reference date
|
31
|
+
#
|
32
|
+
# require 'rubygems'
|
33
|
+
# require 'beginning_of_fortnight'
|
34
|
+
#
|
35
|
+
# now = Time.now
|
36
|
+
#
|
37
|
+
# # Globally define fortnights such that this date is the first half of a fortnight
|
38
|
+
# ref_date = Time.parse('13-Oct-2010')
|
39
|
+
# BeginningOfFortnight.reference_date = ref_date
|
40
|
+
#
|
41
|
+
# puts now.beginning_of_fortnight # uses ref_date
|
42
|
+
#
|
43
|
+
# # Change your mind...
|
44
|
+
# BeginningOfFortnight.reference_date = Time.parse('20-Oct-2010')
|
45
|
+
# puts now.beginning_of_fortnight # should be different
|
46
|
+
#
|
47
|
+
# # You can also pass in a single use reference date if you want to mix it up
|
48
|
+
# other_ref_date = Time.parse('27-Oct-2010')
|
49
|
+
# puts now.beginning_of_fortnight(other_ref_date)
|
50
|
+
#
|
51
|
+
#
|
52
|
+
|
53
|
+
begin
|
54
|
+
# Try to load just the time components
|
55
|
+
# (Only possible in ActiveRecord 3.0)
|
56
|
+
require 'active_support/time'
|
57
|
+
rescue LoadError
|
58
|
+
# Presume we must have ActiveRecord 2.x so require the whole lot of active_support
|
59
|
+
# (Decided it's not worth the effort to try to cherry pick just the time components)
|
60
|
+
require 'active_support'
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Just a namespace and an accessor for the reference
|
65
|
+
# date used to define fortnight boundaries.
|
66
|
+
#
|
67
|
+
#--
|
68
|
+
# (Maybe this could use cattr_accessor. Not sure if it's worth it).
|
69
|
+
#++
|
70
|
+
#
|
71
|
+
module BeginningOfFortnight
|
72
|
+
#
|
73
|
+
# Fairly arbitrary choice of reference date
|
74
|
+
#
|
75
|
+
DEFAULT_REF_DATE = Time.at(0)
|
76
|
+
|
77
|
+
#
|
78
|
+
# Provide an accessor for @@reference_date. Uses the default value if not set.
|
79
|
+
#
|
80
|
+
def self.reference_date
|
81
|
+
(@@reference_date ||= DEFAULT_REF_DATE).to_time
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# The 'reference_date' here is used to define where the fortnight boundary should be.
|
86
|
+
# The way it works is that the reference_date is specified such that it falls in the first
|
87
|
+
# half of the fortnightly period.
|
88
|
+
#
|
89
|
+
# You can just ignore this it will use a default value but if you want to be explicit then
|
90
|
+
# set a date, for example:
|
91
|
+
#
|
92
|
+
# # Define fortnight boundary
|
93
|
+
# BeginningOfFortnight.reference_date = Time.parse('13-Oct-2010')
|
94
|
+
#
|
95
|
+
# # A date should work also
|
96
|
+
# BeginningOfFortnight.reference_date = Date.new(2010,10,13)
|
97
|
+
#
|
98
|
+
def self.reference_date=(reference_date)
|
99
|
+
@@reference_date = reference_date
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
#
|
105
|
+
# These methods should work similar to beginning_of_week and friends.
|
106
|
+
#
|
107
|
+
# In all these methods, if the optional argument <tt>reference_date</tt>
|
108
|
+
# is not given then the default reference date is used. See
|
109
|
+
# BeginningOfFortnight#reference_date.
|
110
|
+
#
|
111
|
+
# reference_date can be a Date or a Time object.
|
112
|
+
#
|
113
|
+
#--
|
114
|
+
# ActiveRecord 2.x puts these methods in a big long name space,
|
115
|
+
# ie ActiveSupport::CoreExtensions::Time::Calculations
|
116
|
+
# ActiveSupport 3.x just adds methods directly to Time.
|
117
|
+
# Will try the 3.x approach and hopefully it will work okay in 2.x also.
|
118
|
+
#++
|
119
|
+
#
|
120
|
+
class Time
|
121
|
+
#
|
122
|
+
# The beginning of the fortnight.
|
123
|
+
#
|
124
|
+
def beginning_of_fortnight(reference_date=nil)
|
125
|
+
# Can pass in a reference date, otherwise use the configured default
|
126
|
+
reference_date ||= BeginningOfFortnight.reference_date
|
127
|
+
|
128
|
+
# The to_time is in case reference_date is passed in as a Date object
|
129
|
+
reference_week = reference_date.to_time.beginning_of_week
|
130
|
+
|
131
|
+
# How many weeks since reference week?
|
132
|
+
weeks_since_reference = ((self - reference_week) / 1.week).to_i
|
133
|
+
|
134
|
+
#
|
135
|
+
# If the reference time is later than self, ie in the future,
|
136
|
+
# then we flip the odd/even test here.
|
137
|
+
#
|
138
|
+
# Some explanation:
|
139
|
+
#
|
140
|
+
# In this diagram, '|' is a fortnight boundary, '+' is a week boundary and R is the reference week.
|
141
|
+
# R
|
142
|
+
# | a + b | c + d |
|
143
|
+
#
|
144
|
+
# The value of weeks_since_reference for dates at a, b, c and d is as follows:
|
145
|
+
# When self is earlier than reference_date:
|
146
|
+
# a (in first half) : -1, hence odd weeks_since_reference is in first half
|
147
|
+
# b (in second half): 0, hence even weeks_since_reference is in second half (because -0.5.to_i is 0 for example)
|
148
|
+
# When self is later than reference_date:
|
149
|
+
# c (in first half) : 0, hence even weeks_since_reference is in first half
|
150
|
+
# d (in second half): 1, hence odd weeks_since_reference is in second half
|
151
|
+
#
|
152
|
+
in_first_half = (reference_week > self ? weeks_since_reference.odd? : weeks_since_reference.even?)
|
153
|
+
|
154
|
+
# The value of in_first_half decides which week to use
|
155
|
+
(in_first_half ? self : self - 1.week).beginning_of_week
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# The end of the fortnight.
|
160
|
+
#
|
161
|
+
def end_of_fortnight(reference_date=nil)
|
162
|
+
(beginning_of_fortnight(reference_date) + 1.week).end_of_week
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# The start of the fortnight after this one.
|
167
|
+
#
|
168
|
+
def next_fortnight(reference_date=nil)
|
169
|
+
beginning_of_fortnight(reference_date) + 2.weeks
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# The Date methods are defined dynamically.
|
175
|
+
#
|
176
|
+
# See:
|
177
|
+
# * Time#beginning_of_fortnight
|
178
|
+
# * Time#end_of_fortnight
|
179
|
+
# * Time#next_fortnight
|
180
|
+
#
|
181
|
+
class Date
|
182
|
+
# Going to be lazy here... in a good way (?)
|
183
|
+
# Redoing the in_first_half logic for Date objects is not quite trivial
|
184
|
+
[:beginning_of_fortnight, :end_of_fortnight, :next_fortnight].each do |method|
|
185
|
+
define_method(method) do |*args|
|
186
|
+
self.to_time.send(method,*args).to_date
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: beginning_of_fortnight
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Simon Baird
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-03-16 00:00:00 +10:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Extends ActiveSupport to provides beginning/end_of_fortnight methods similar to beginning/end_of_week
|
22
|
+
email: simon.baird@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- lib/beginning_of_fortnight.rb
|
31
|
+
has_rdoc: true
|
32
|
+
homepage: http://github.com/simonbaird/beginning_of_fortnight
|
33
|
+
licenses: []
|
34
|
+
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.3.6
|
58
|
+
signing_key:
|
59
|
+
specification_version: 3
|
60
|
+
summary: beginning_of_fortnight for ActiveSupport
|
61
|
+
test_files: []
|
62
|
+
|