Class: Date

Inherits:
Object
  • Object
show all
Defined in:
lib/date_helper/date.rb

Overview

encoding: utf-8

Extension for Date to calculate a forward date with compressed syntax

Copyright 2021 Stephan Wenzel <[email protected]>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Instance Method Summary collapse

Instance Method Details

#adjust(epoch, pos, ref = self) ⇒ Object

calculate time adjustmentfor pos in epoch (_F_irst, _M_id, _L_ast, _W_orking day) epoch: D - day: W - Monday epoch: W - week: F - Monday, M - Wednesday, L - Friday, W - Monday epoch: M - month: F - 1st, M - 15th, L - last, W - Monday epoch: Y - year: F - 01/01, M - 06/30, L - 12/31, W - Monday epoch: q - quarter: W - Monday



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/date_helper/date.rb', line 169

def adjust( epoch, pos, ref=self )

  case epoch
  when "D"
    case pos
    when "W"
      # if saturday or sunday, fall back to last monday, then add one week for monday coming up
      (wday % 6) != 0 ? self : monday.advance(:days => 7)
    else
      self
    end #case
    
  when "W", "C"
    # week
    case pos
    when "F"
      # Monday
      monday < ref ? advance( :weeks => 1).monday : monday
      
    when "M"
      # Wednesday = Monday + 2 days
      monday.advance(:days => 2) < ref ? advance( :weeks => 1).monday.advance(:days => 2) : monday.advance(:days => 2)
      
    when "L"
      # Friday = Monday + 4 days
      monday.advance(:days => 4) < ref ? advance( :weeks => 1).monday.advance(:days => 4) : monday.advance(:days => 4)
      
    when "W"
    # if saturday or sunday, fall back to last monday, then add one week for monday coming up
      (wday % 6) != 0 ? self : monday.advance(:days => 7)
      
    else
      self
    end #case
    
  when "M"
    # month
    case pos
    when "F"
      # 1st
      change(:day => 1) < ref ? advance( :months => 1).beginning_of_month.change(:day => 1) : change(:day => 1)
      
    when "M"
      # 15th 
      change(:day => 15) < ref ? advance( :months => 1).beginning_of_month.change(:day => 15) : change(:day => 15)
      
    when "L"
      # last day
      end_of_month
      
    when "W"
    # if saturday or sunday, fall back to last monday, then add one week for monday coming up
      (wday % 6) != 0 ? self : monday.advance(:days => 7)
    else
      self
    end #case
    
  when "Y"
    # year
    case pos
    when "F"
      # Jan. 1st
      beginning_of_year < ref ? advanve(:years => 1).beginning_of_year : beginning_of_year
      
    when "M"
      # Jun. 30th
      change(:month => 5, :day => 30) < ref ? advance(:years => 1).change(:month => 5, :day => 30) : change(:month => 5, :day => 30)
      
    when "L"
      # Dec. 31st
      change(:month => 12, :day => 31)
      
    when "W"
    # if saturday or sunday, fall back to last monday, then add one week for monday coming up
      (wday % 6) != 0 ? self : monday.advance(:days => 7)
    else
      self
    end #case
    
  when "q"
    case pos
    when "F"
      # Jan. 1st
      beginning_of_quarter < ref ? advance( :months => 3).beginning_of_quarter : beginning_of_quarter
      
    when "M"
      # mid quarter
      beginning_of_quarter.advance(:months => 1).advance(:days => 14) < ref ? advance(:quarters => 1).beginning_of_quarter.advance(:months => 1).advance(:days => 14) : beginning_of_quarter.advance(:months => 1).advance(:days => 14)
      
    when "L"
      # end quarter
      end_of_quarter
      
    when "W"
    # if saturday or sunday, fall back to last monday, then add one week for monday coming up
      (wday % 6) != 0 ? self : monday.advance(:days => 7)
    else
      self
    end #case
    
  else
    self
  end #case epoch
end

#calc(rule) ⇒ Object

calc



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/date_helper/date.rb', line 84

def calc( rule )

  new_date = nil
  new_rule = nil
  
  if rule.present?
  
    m = parse_rule( rule )
    
    if m['mockswitch']
    
      # mockswitch does not calculate anything
      # mockswitch is removed from new_rule, however
      new_rule = unmock( rule, m )
      
    elsif self <= Date.today || m['force']
    
      if( m['epoch'] && m['num'] )
      
        new_date = move(   m['epoch'], m['num'] )
        new_date = new_date.adjust( m['epoch'], m['pos'], self )
        new_date = new_date.adjust("D", "W", new_date) if m["workingday"] # adjust working day
        
        if m['killswitch']
          new_rule  = "" 
        else
          new_rule  = rule
        end
        
      end #if
    end #if
  end #if
  
  [new_date, new_rule]
  
end

#forward(rule) ⇒ Object

forward



124
125
126
# File 'lib/date_helper/date.rb', line 124

def forward( rule )
  calc( rule ).first
end

#move(epoch, num) ⇒ Object

calculate num times advance of epoch epoch: D - n days epoch: W - n weeks epoch: M - n months epoch: Y - n years

epoch: C - n calendar weeks (absolute, within this year, not relative) epoch: m - n mondays epoch: q - q quarters



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/date_helper/date.rb', line 139

def move( epoch, num )
  case epoch  
  when "D"
      self + num.to_i
  when "W"
      self + num.to_i * 7
  when "M"
      self >> num.to_i
  when "Y"
      self >> num.to_i * 12
  when "m"
      (self + num.to_i * 7).monday 
  when "q"
      (self >> num.to_i * 3).beginning_of_quarter
  when "C"
      # calendar week 1 is the week containing Jan. 4th
      change(:month => 1, :day => 4).advance( :weeks => (num.to_i - 1))
  else
    self
  end #case
end