smart-period 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fd14ecdd3ede7c4ca9abb4fa8c06abf1a6cf07cc518492f964e607ae43a723ce
4
+ data.tar.gz: 3245f5e367c91c2d20afa9ca6a90e86f00371a962436fd98a59d3ff97f6307ad
5
+ SHA512:
6
+ metadata.gz: 6ca42e1a8a26268ffeb33d04965c4494ffb4b334992e59289ff5c56dedc19ee110a8a2a9f0798cadb69337ea1df8d8670a6ca975058fb8c05ddf5103bd3ff0dd
7
+ data.tar.gz: 5d728d18e9870ba11c348d3b137cf737f36c9ea57c31df0eb98ae9a3e986a431a0aa503d4784fa0214f2bc6d64e11614b91f523e826feec58625a37382b6bb20
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in period.gemspec
4
+
5
+ gemspec
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ period (0.1.4)
5
+ activesupport (= 5.2.3)
6
+ i18n (= 1.6.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (5.2.3)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 0.7, < 2)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
16
+ concurrent-ruby (1.1.6)
17
+ i18n (1.6.0)
18
+ concurrent-ruby (~> 1.0)
19
+ minitest (5.14.1)
20
+ rake (10.5.0)
21
+ thread_safe (0.3.6)
22
+ tzinfo (1.2.7)
23
+ thread_safe (~> 0.1)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 2.0)
30
+ rake (~> 10.0)
31
+ period!
32
+
33
+ BUNDLED WITH
34
+ 2.0.1
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 billau_l
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # Period
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/period`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'period'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install period
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/period.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ task default: :spec
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'test'
7
+ end
8
+
9
+ desc 'Run tests'
10
+ task default: :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'period'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
Binary file
@@ -0,0 +1,6 @@
1
+ class Numeric
2
+ def quarters
3
+ ActiveSupport::Duration.months(self * 3)
4
+ end
5
+ alias :quarter :quarters
6
+ end
@@ -0,0 +1,70 @@
1
+ require_relative 'period/version.rb'
2
+ require 'active_support/all'
3
+ require 'i18n'
4
+
5
+ require_relative 'period/free_period.rb'
6
+ require_relative 'period/day.rb'
7
+ require_relative 'period/week.rb'
8
+ require_relative 'period/month.rb'
9
+ require_relative 'period/quarter.rb'
10
+ require_relative 'period/year.rb'
11
+
12
+ module Period
13
+ def self.new(range)
14
+ Period::FreePeriod.new(range)
15
+ end
16
+
17
+ def self.env_time
18
+ (Time.zone || Time)
19
+ end
20
+
21
+ class << self
22
+ %i[day week month quarter year].each do |period|
23
+ define_method "last_#{period}" do
24
+ date = env_time.now.send(period == :day ? 'yesterday' : "last_#{period}")
25
+ Object.const_get("Period::#{period.capitalize}").new(date)
26
+ end
27
+
28
+ define_method "this_#{period}" do
29
+ Object.const_get("Period::#{period.capitalize}").new(env_time.now)
30
+ end
31
+
32
+ define_method "next_#{period}" do
33
+ date = env_time.now.send(period == :day ? 'tomorrow' : "next_#{period}")
34
+ Object.const_get("Period::#{period.capitalize}").new(date)
35
+ end
36
+
37
+ define_method period.to_s do
38
+ Object.const_get("Period::#{period.capitalize}")
39
+ end
40
+ end
41
+
42
+ alias yesterday last_day
43
+ alias tomorrow next_day
44
+ alias today this_day
45
+
46
+ def method_missing(method_name, *arguments, &block)
47
+ super unless method_name.match?(/(last|next)_\d+_(day|week|month|quarter|year)s?(_from_now)?/)
48
+ last_next, count, klass = method_name.to_s.split('_')
49
+ klass = klass.singularize
50
+
51
+ case last_next
52
+ when 'last'
53
+ from = env_time.now
54
+ from -= 1.send(klass) unless method_name.match?(/from_now$/)
55
+ from = from.send("beginning_of_#{klass}")
56
+ to = count.to_i.send(klass).ago.send("end_of_#{klass}")
57
+ when 'next'
58
+ from = env_time.now
59
+ from += 1.send(klass) unless method_name.match?(/from_now$/)
60
+ from = from.send("beginning_of_#{klass}")
61
+ to = count.to_i.send(klass).from_now.send("end_of_#{klass}")
62
+ end
63
+ self.new(from..to)
64
+ end
65
+
66
+ def respond_to_missing?(method_name, include_private = false)
67
+ method_name.match?(/(last|next)_\d+_(day|week|month|quarter|year)s?(_from_now)?/) || super
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,4 @@
1
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
2
+ # @note This module define all period of time, who include the current period
3
+ module Period::BelongsTo
4
+ end
@@ -0,0 +1,12 @@
1
+ module Period
2
+ module BelongsTo
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide access to the month of the
5
+ # FreePeriod
6
+ module Month
7
+ def month
8
+ Period::Month.new(iso_date)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Period
2
+ module BelongsTo
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide access to the quarter of the
5
+ # FreePeriod
6
+ module Quarter
7
+ def quarter
8
+ Period::Quarter.new(iso_date)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Period
2
+ module BelongsTo
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide access to the week of the
5
+ # FreePeriod
6
+ module Week
7
+ def week
8
+ Period::Week.new(iso_date)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Period
2
+ module BelongsTo
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide access to the year of the
5
+ # FreePeriod
6
+ module Year
7
+ def year
8
+ Period::Year.new(iso_date)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'standard_period.rb'
2
+ require_relative 'belongs_to.rb'
3
+ require_relative 'belongs_to/week.rb'
4
+ require_relative 'belongs_to/month.rb'
5
+ require_relative 'belongs_to/quarter.rb'
6
+ require_relative 'belongs_to/year.rb'
7
+
8
+ class Period::Day < Period::StandardPeriod
9
+ include Period::BelongsTo::Week
10
+ include Period::BelongsTo::Month
11
+ include Period::BelongsTo::Quarter
12
+ include Period::BelongsTo::Year
13
+
14
+ def strftime(format)
15
+ from.strftime(format)
16
+ end
17
+
18
+ def to_s(format: '%d/%m/%Y')
19
+ strftime(format)
20
+ end
21
+
22
+ def i18n(&block)
23
+ return yield(from, to) if block.present?
24
+
25
+ I18n.t(:default_format,
26
+ scope: i18n_scope,
27
+ wday: I18n.l(from, format: '%A').capitalize,
28
+ day: from.day,
29
+ month: I18n.l(from, format: '%B').capitalize,
30
+ year: from.year)
31
+ end
32
+ end
@@ -0,0 +1,107 @@
1
+ require_relative 'has_many.rb'
2
+ require_relative 'has_many/days.rb'
3
+ require_relative 'has_many/weeks.rb'
4
+ require_relative 'has_many/months.rb'
5
+ require_relative 'has_many/quarters.rb'
6
+ require_relative 'has_many/years.rb'
7
+
8
+ I18n.load_path << 'locales/fr.yml'
9
+ I18n.load_path << 'locales/en.yml'
10
+
11
+ class Period::FreePeriod < Range
12
+ include Comparable
13
+
14
+ include Period::HasMany::Days
15
+ include Period::HasMany::Weeks
16
+ include Period::HasMany::Months
17
+ include Period::HasMany::Quarters
18
+ include Period::HasMany::Years
19
+
20
+ def initialize(range)
21
+ from = range.first
22
+ to = range.last
23
+
24
+ from = time_parse(range.first, I18n.t(:start_date_is_invalid, scope: %i[period free_period])).beginning_of_day
25
+ to = time_parse(range.last, I18n.t(:end_date_is_invalid, scope: %i[period free_period])).end_of_day
26
+
27
+ raise ::ArgumentError, I18n.t(:start_is_greater_than_end, scope: %i[period free_period]) if from > to
28
+
29
+ super(from, to, range.exclude_end?)
30
+ end
31
+
32
+ alias from first
33
+ alias beginning first
34
+
35
+ alias to last
36
+ alias end last
37
+
38
+ def next
39
+ raise NotImplementedError
40
+ end
41
+ alias succ next
42
+
43
+ def prev
44
+ raise NotImplementedError
45
+ end
46
+
47
+ def self.from_date(_date)
48
+ raise NotImplementedError
49
+ end
50
+
51
+ def include?(other)
52
+ if other.class.in?([DateTime, Time, ActiveSupport::TimeWithZone])
53
+ from.to_i <= other.to_i && other.to_i <= to.to_i
54
+ elsif other.is_a? Date
55
+ super(Period::Day.new(other))
56
+ elsif other.class.ancestors.include?(Period::FreePeriod)
57
+ super(other)
58
+ else
59
+ raise ArgumentError, I18n.t(:incomparable_error, scope: :free_period)
60
+ end
61
+ end
62
+
63
+ def <=>(other)
64
+ if other.is_a?(ActiveSupport::Duration) || other.is_a?(Numeric)
65
+ to_i <=> other.to_i
66
+ elsif self.class != other.class
67
+ raise ArgumentError, I18n.t(:incomparable_error, scope: :free_period)
68
+ else
69
+ (from <=> other)
70
+ end
71
+ end
72
+
73
+ def to_i
74
+ days.count.days
75
+ end
76
+
77
+ def -(other)
78
+ self.class.new((from - other)..(to - other))
79
+ end
80
+
81
+ def to_s(format: '%d %B %Y')
82
+ I18n.t(:default_format,
83
+ scope: %i[period free_period],
84
+ from: I18n.l(from, format: format),
85
+ to: I18n.l(to, format: format))
86
+ end
87
+
88
+ def i18n(&block)
89
+ return yield(from, to) if block.present?
90
+
91
+ to_s
92
+ end
93
+
94
+ private
95
+
96
+ def time_parse(time, msg)
97
+ if time.class.in? [String, Date]
98
+ Period.env_time.parse(time.to_s)
99
+ elsif time.class.in? [Time, ActiveSupport::TimeWithZone]
100
+ time
101
+ else
102
+ raise ::ArgumentError, msg
103
+ end
104
+ rescue StandardError
105
+ raise ::ArgumentError, msg
106
+ end
107
+ end
@@ -0,0 +1,16 @@
1
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
2
+ # @note This module define all period of time, who are include in the current period
3
+ module Period
4
+ module HasMany
5
+ def itterate(to,klass)
6
+ ret = []
7
+ curr = from
8
+ # Handle timezone with to_date
9
+ while curr.to_date <= to.to_date
10
+ ret << klass.new(curr.to_date)
11
+ curr = curr.send("next_#{klass._period}")
12
+ end
13
+ ret
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Period
2
+ module HasMany
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide access to the days of the
5
+ # FreePeriod
6
+ module Days
7
+ include Period::HasMany
8
+
9
+ def days
10
+ @days ||= itterate(to, Period::Day)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Period
2
+ module HasMany
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide itterable access to the months of
5
+ # the FreePeriod
6
+ module Months
7
+ include Period::HasMany
8
+
9
+ def months
10
+ @months ||= itterate(to, Period::Month)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Period
2
+ module HasMany
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide itterable access to the quarters of
5
+ # the FreePeriod
6
+ module Quarters
7
+ include Period::HasMany
8
+
9
+ def quarters
10
+ @quarters ||= itterate(to, Period::Quarter)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ module Period
2
+ module HasMany
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide itterable access to the weeks of
5
+ # the FreePeriod
6
+ module Weeks
7
+ # TODO, rewrite this to respect ISO %V %G
8
+ def weeks
9
+ @weeks ||= []
10
+ return @weeks if @weeks.present?
11
+ curr = from
12
+ while curr <= to
13
+ week = Period::Week.new(curr)
14
+ @weeks << week if week.iso_date.in?(self)
15
+ curr = curr.next_week
16
+ end
17
+
18
+ @weeks
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ module Period
2
+ module HasMany
3
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
4
+ # @note when include this module provide itterable access to the years of
5
+ # the FreePeriod
6
+ module Years
7
+ include Period::HasMany
8
+
9
+ def years
10
+ @years ||= itterate(to, Period::Month)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'standard_period.rb'
2
+ require_relative 'has_many.rb'
3
+ require_relative 'has_many/days.rb'
4
+ require_relative 'has_many/weeks.rb'
5
+ require_relative 'belongs_to.rb'
6
+ require_relative 'belongs_to/quarter.rb'
7
+ require_relative 'belongs_to/year.rb'
8
+
9
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
10
+ # @note One of the StandardPeriod defined in the gem
11
+ module Period
12
+ class Month < Period::StandardPeriod
13
+ include Period::HasMany::Days
14
+ include Period::HasMany::Weeks
15
+
16
+ include Period::BelongsTo::Quarter
17
+ include Period::BelongsTo::Year
18
+
19
+ def strftime(format)
20
+ from.strftime(format)
21
+ end
22
+
23
+ def to_s(format: '%m/%Y')
24
+ strftime(format)
25
+ end
26
+
27
+ def i18n(&block)
28
+ return yield(from, to) if block.present?
29
+
30
+ I18n.t(:default_format,
31
+ scope: i18n_scope,
32
+ month: I18n.l(from, format: '%B').capitalize,
33
+ year: from.year)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ require_relative 'standard_period.rb'
2
+ require_relative 'has_many.rb'
3
+ require_relative 'has_many/days.rb'
4
+ require_relative 'has_many/weeks.rb'
5
+ require_relative 'has_many/months.rb'
6
+ require_relative 'belongs_to.rb'
7
+ require_relative 'belongs_to/year.rb'
8
+
9
+ module Period
10
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
11
+ # @note One of the StandardPeriod defined in the gem
12
+ class Quarter < Period::StandardPeriod
13
+ include Period::HasMany::Days
14
+ include Period::HasMany::Weeks
15
+ include Period::HasMany::Months
16
+
17
+ include Period::BelongsTo::Year
18
+
19
+ def strftime(format)
20
+ format = format.gsub(':quarter', quarter_nb.to_s)
21
+ from.strftime(format)
22
+ end
23
+
24
+ def quarter_nb
25
+ @quarter_nb ||= (from.month / 3.0).ceil
26
+ end
27
+
28
+ def to_s
29
+ i18n
30
+ end
31
+
32
+ def i18n(&block)
33
+ return yield(from, to) if block.present?
34
+
35
+ I18n.t(:default_format,
36
+ scope: i18n_scope,
37
+ quarter_nb: quarter_nb,
38
+ year: from.year)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,66 @@
1
+ require_relative 'has_many.rb'
2
+ require_relative 'has_many/days.rb'
3
+ require_relative 'has_many/weeks.rb'
4
+ require_relative 'has_many/months.rb'
5
+ require_relative 'has_many/quarters.rb'
6
+ require_relative 'has_many/years.rb'
7
+
8
+ module Period
9
+ class StandardPeriod < Period::FreePeriod
10
+ def initialize(object)
11
+ time = time_parse(object, I18n.t(:date_is_invalid, scope: %i[period standard_period]) )
12
+ super(time.send("beginning_of_#{_period}")..time.send("end_of_#{_period}"))
13
+ end
14
+
15
+ def next
16
+ self.class.new(from.send("next_#{_period}"))
17
+ end
18
+ alias succ next
19
+
20
+ def prev
21
+ self.class.new(from.send("prev_#{_period}"))
22
+ end
23
+
24
+ def _period
25
+ self.class._period
26
+ end
27
+
28
+ def self._period
29
+ name.split('::').last.downcase
30
+ end
31
+
32
+ def to_i
33
+ 1.send(_period)
34
+ end
35
+
36
+ def -(duration)
37
+ self.class.new(from - duration)
38
+ end
39
+
40
+ def +(duration)
41
+ self.class.new(to + duration)
42
+ end
43
+
44
+ def ==(other)
45
+ raise ArgumentError unless other.class.ancestors.include?(Period::FreePeriod)
46
+
47
+ from == other.from && to == other.to
48
+ end
49
+
50
+ def iso_date
51
+ from
52
+ end
53
+
54
+ def to_s
55
+ raise NotImplementedError
56
+ end
57
+
58
+ def i18n
59
+ raise NotImplementedError
60
+ end
61
+
62
+ def i18n_scope
63
+ [:period, :standard_period, _period]
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,3 @@
1
+ module Period
2
+ VERSION = '1.0.0'.freeze
3
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'standard_period.rb'
2
+ require_relative 'has_many.rb'
3
+ require_relative 'has_many/days.rb'
4
+ require_relative 'belongs_to.rb'
5
+ require_relative 'belongs_to/week.rb'
6
+ require_relative 'belongs_to/month.rb'
7
+ require_relative 'belongs_to/quarter.rb'
8
+ require_relative 'belongs_to/year.rb'
9
+
10
+ module Period
11
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
12
+ # @note One of the StandardPeriod defined in the gem
13
+ class Week < Period::StandardPeriod
14
+ include Period::HasMany::Days
15
+
16
+ include Period::BelongsTo::Month
17
+ include Period::BelongsTo::Quarter
18
+ include Period::BelongsTo::Year
19
+
20
+ def strftime(format)
21
+ from.strftime(format)
22
+ end
23
+
24
+ def to_s(format: '%V - %G')
25
+ strftime(format)
26
+ end
27
+
28
+ def i18n(&block)
29
+ return yield(from, to) if block.present?
30
+
31
+ I18n.t(:default_format,
32
+ scope: i18n_scope,
33
+ week: strftime('%V'),
34
+ year: strftime('%G'))
35
+ end
36
+
37
+ def iso_date
38
+ from + 3.days
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'standard_period.rb'
2
+ require_relative 'has_many.rb'
3
+ require_relative 'has_many/days.rb'
4
+ require_relative 'has_many/weeks.rb'
5
+ require_relative 'has_many/months.rb'
6
+ require_relative 'has_many/quarters.rb'
7
+
8
+ module Period
9
+ # @author Lucas Billaudot <billau_l@modulotech.fr>
10
+ # @note One of the StandardPeriod defined in the gem
11
+ class Year < Period::StandardPeriod
12
+ include Period::HasMany::Days
13
+ include Period::HasMany::Weeks
14
+ include Period::HasMany::Months
15
+ include Period::HasMany::Quarters
16
+
17
+ def strftime(format)
18
+ from.strftime(format)
19
+ end
20
+
21
+ def to_s(format: '%Y')
22
+ strftime(format)
23
+ end
24
+
25
+ def i18n(&block)
26
+ return yield(from, to) if block.present?
27
+
28
+ I18n.t(:default_format,
29
+ scope: i18n_scope,
30
+ year: from.year)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ en:
2
+ period:
3
+ free_period:
4
+ default_format: From the %{from} to the %{to} included
5
+ start_date_is_invalid: The start date is invalid
6
+ end_date_is_invalid: The end date is invalid
7
+ start_is_greater_than_end: The start date is greater than the end date
8
+ incomparable_error: Cannot compare Arguments
9
+ standard_period:
10
+ date_is_invalid: The date is invalid
11
+ day:
12
+ default_format: '%{wday} %{day} %{month} %{year}'
13
+ week:
14
+ default_format: Week %{week} of %{year}
15
+ month:
16
+ default_format: '%{month} %{year}'
17
+ quarter:
18
+ default_format: '%{quarter_nb} quarter %{year}'
19
+ year:
20
+ default_format: '%{year}'
@@ -0,0 +1,20 @@
1
+ fr:
2
+ period:
3
+ free_period:
4
+ default_format: Du %{from} au %{to} inclus
5
+ start_date_is_invalid: Date de début invalide
6
+ end_date_is_invalid: Date de fin invalide
7
+ start_is_greater_than_end: Date de début supérieur à la date de fin
8
+ incomparable_error: Les arguments ne sont pas comparables
9
+ must_implement_to_datetime: L'argument doit repondre a "to_datetime"
10
+ standard_period:
11
+ day:
12
+ default_format: '%{wday} %{day} %{month} %{year}'
13
+ week:
14
+ default_format: Semaine %{week} de l'année %{year}
15
+ month:
16
+ default_format: '%{month} %{year}'
17
+ quarter:
18
+ default_format: '%{quarter_nb} semestre %{year}'
19
+ year:
20
+ default_format: '%{year}'
@@ -0,0 +1,42 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'period/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'smart-period'
7
+ spec.version = Period::VERSION
8
+ spec.authors = ['billau_l']
9
+ spec.email = ['billau_l@modulotech.fr']
10
+
11
+ spec.summary = 'Write a short summary, because RubyGems requires one.'
12
+ spec.description = 'Write a longer description or delete this line.'
13
+ # spec.homepage = "Put your gem's website or public repo URL here."
14
+ spec.license = 'MIT'
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ # if spec.respond_to?(:metadata)
19
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
20
+ #
21
+ # spec.metadata["homepage_uri"] = spec.homepage
22
+ # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
23
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
24
+ # else
25
+ # raise "RubyGems 2.0 or newer is required to protect against " \
26
+ # "public gem pushes."
27
+ # end
28
+
29
+ # Specify which files should be added to the gem when it is released.
30
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+ spec.bindir = 'exe'
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = %w[lib locals]
37
+
38
+ spec.add_runtime_dependency 'activesupport', '5.2.3'
39
+ spec.add_runtime_dependency 'i18n', '1.6.0'
40
+ spec.add_development_dependency 'bundler', '~> 2.0'
41
+ spec.add_development_dependency 'rake', '~> 10.0'
42
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smart-period
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - billau_l
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-12-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: i18n
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Write a longer description or delete this line.
70
+ email:
71
+ - billau_l@modulotech.fr
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/console
83
+ - bin/setup
84
+ - lib/.DS_Store
85
+ - lib/numeric.rb
86
+ - lib/period.rb
87
+ - lib/period/belongs_to.rb
88
+ - lib/period/belongs_to/month.rb
89
+ - lib/period/belongs_to/quarter.rb
90
+ - lib/period/belongs_to/week.rb
91
+ - lib/period/belongs_to/year.rb
92
+ - lib/period/day.rb
93
+ - lib/period/free_period.rb
94
+ - lib/period/has_many.rb
95
+ - lib/period/has_many/days.rb
96
+ - lib/period/has_many/months.rb
97
+ - lib/period/has_many/quarters.rb
98
+ - lib/period/has_many/weeks.rb
99
+ - lib/period/has_many/years.rb
100
+ - lib/period/month.rb
101
+ - lib/period/quarter.rb
102
+ - lib/period/standard_period.rb
103
+ - lib/period/version.rb
104
+ - lib/period/week.rb
105
+ - lib/period/year.rb
106
+ - locales/en.yml
107
+ - locales/fr.yml
108
+ - period.gemspec
109
+ homepage:
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ - locals
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubygems_version: 3.1.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Write a short summary, because RubyGems requires one.
133
+ test_files: []