tempora 0.2.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 829bad4acfece329fa910614c27da039a46933e2da7246d091df30fd1463cee5
4
- data.tar.gz: 6d2d1e27e904b76d6f2661fb8328b8a3bceb83c142ffe376f76d261e66fdea07
3
+ metadata.gz: 1af2de3467a21cc28a33db0590f6934e0892cd6fca23f51183b16252b5f91016
4
+ data.tar.gz: d0365bb120ea9e0a42e768382136efff98ab25d88343c3876db913ceafd00a93
5
5
  SHA512:
6
- metadata.gz: ff6c9aec13bd9eb4ce86085043887f750101a722d64a30d6b8af43e7e52962632e91b8dbb74561cf0df02d05acb7928234ab892eafbe3fe1930bbe6f05cf64cb
7
- data.tar.gz: '08cc00d8bbac916783277803a0ef3279a7db353bd3a9e5743d2a0576824939e0b1b1039bea1143120068cf995060ac4bb0d827b553d73a2a368e902d69bbd40a'
6
+ metadata.gz: 5d21b7f7290f12435d5e77aae4221022dfa0db3b242ad3506edf9bdd446866bc1db576759ea91f5517c8a0b988f159d42517ddd1656beca618384cb46e66de0b
7
+ data.tar.gz: efbab1ef415bfb7eaa6ffd6877e07d16efe49219a3376437e451cf4a75c3c6076b2d8fc0f908042d0394fe2392ae144a2ef3859153fd120e3deda523c0192493
data/lib/month.rb CHANGED
@@ -2,49 +2,51 @@ require_relative 'timeperiod'
2
2
  require_relative 'tempora/initialization'
3
3
  require_relative 'tempora/has_weeks'
4
4
 
5
- class Month < TimePeriod
6
- extend Initialization
7
- include HasWeeks
5
+ module Tempora
6
+ class Month < TimePeriod
7
+ extend Initialization
8
+ include HasWeeks
8
9
 
9
- def initialize(year, month)
10
- @year = Integer(year)
11
- @number = Integer(month).clamp(1, 12)
10
+ def initialize(year, month)
11
+ @year = Integer(year)
12
+ @number = Integer(month).clamp(1, 12)
12
13
 
13
- @start_date = Date.new(@year, @number, 1)
14
- @end_date = Date.new(@year, @number, -1)
15
- end
14
+ @start_date = Date.new(@year, @number, 1)
15
+ @end_date = Date.new(@year, @number, -1)
16
+ end
16
17
 
17
- def id(seperator="-")
18
- "#{year}#{seperator}#{number.to_s.rjust(2, '0')}"
19
- end
18
+ def id(seperator="-")
19
+ "#{year}#{seperator}#{number.to_s.rjust(2, '0')}"
20
+ end
20
21
 
21
- def to_s
22
- "#{month_name} #{year}"
23
- end
22
+ def to_s
23
+ "#{month_name} #{year}"
24
+ end
24
25
 
25
- def month_name
26
- Date::MONTHNAMES[number]
27
- end
26
+ def month_name
27
+ Date::MONTHNAMES[number]
28
+ end
28
29
 
29
- def month_abbr
30
- Date::ABBR_MONTHNAMES[number]
31
- end
30
+ def month_abbr
31
+ Date::ABBR_MONTHNAMES[number]
32
+ end
32
33
 
33
- def next
34
- self.class.from(start_date.next_month) # @start_date >> 1
35
- end
34
+ def next
35
+ self.class.from(start_date.next_month) # @start_date >> 1
36
+ end
36
37
 
37
- def prev
38
- self.class.from(start_date.prev_month) # @start_date << 1
39
- end
38
+ def prev
39
+ self.class.from(start_date.prev_month) # @start_date << 1
40
+ end
40
41
 
41
- alias_method :month, :number
42
- alias_method :succ, :next
43
- alias_method :pred, :prev
42
+ alias_method :month, :number
43
+ alias_method :succ, :next
44
+ alias_method :pred, :prev
44
45
 
45
- private
46
+ private
46
47
 
47
- def self.initialization_parameter(date)
48
- [date.year, date.month]
48
+ def self.initialization_parameter(date)
49
+ [date.year, date.month]
50
+ end
49
51
  end
50
- end
52
+ end
data/lib/quarter.rb CHANGED
@@ -3,46 +3,48 @@ require_relative 'tempora/initialization'
3
3
  require_relative 'tempora/has_months'
4
4
  require_relative 'tempora/has_weeks'
5
5
 
6
- class Quarter < TimePeriod
7
- extend Initialization
8
- include HasMonths
9
- include HasWeeks
6
+ module Tempora
7
+ class Quarter < TimePeriod
8
+ extend Initialization
9
+ include HasMonths
10
+ include HasWeeks
10
11
 
11
- def initialize(year, quarter)
12
- @year = Integer(year)
13
- @number = Integer(quarter).clamp(1,4)
12
+ def initialize(year, quarter)
13
+ @year = Integer(year)
14
+ @number = Integer(quarter).clamp(1,4)
14
15
 
15
- start_month = (quarter - 1) * 3 + 1
16
- @start_date = Date.new(year, start_month, 1)
17
- @end_date = @start_date.next_month(3).prev_day
18
- end
16
+ start_month = (quarter - 1) * 3 + 1
17
+ @start_date = Date.new(year, start_month, 1)
18
+ @end_date = @start_date.next_month(3).prev_day
19
+ end
19
20
 
20
- def id(seperator="-")
21
- "#{year}#{seperator}Q#{number}"
22
- end
21
+ def id(seperator="-")
22
+ "#{year}#{seperator}Q#{number}"
23
+ end
23
24
 
24
- def to_s
25
- "Q#{number} #{year}"
26
- end
25
+ def to_s
26
+ "Q#{number} #{year}"
27
+ end
27
28
 
28
- def next
29
- self.class.from(start_date >> 3)
30
- end
29
+ def next
30
+ self.class.from(start_date >> 3)
31
+ end
31
32
 
32
- def prev
33
- self.class.from(start_date << 3)
34
- end
33
+ def prev
34
+ self.class.from(start_date << 3)
35
+ end
35
36
 
36
- alias_method :succ, :next
37
- alias_method :pred, :prev
37
+ alias_method :succ, :next
38
+ alias_method :pred, :prev
38
39
 
39
- private
40
+ private
40
41
 
41
- def self.initialization_parameter(date)
42
- [date.year, quarter_from_date(date)]
43
- end
42
+ def self.initialization_parameter(date)
43
+ [date.year, quarter_from_date(date)]
44
+ end
44
45
 
45
- def self.quarter_from_date(date)
46
- ((date.month - 1) / 3) + 1
46
+ def self.quarter_from_date(date)
47
+ ((date.month - 1) / 3) + 1
48
+ end
47
49
  end
48
- end
50
+ end
@@ -0,0 +1,11 @@
1
+ module Tempora
2
+ module HasDays
3
+ def days
4
+ range.to_a
5
+ end
6
+
7
+ def each_day(&block)
8
+ range.each(&block)
9
+ end
10
+ end
11
+ end
@@ -1,9 +1,11 @@
1
- module HasMonths
2
- def months
3
- Month.from(start_date)..Month.from(end_date)
4
- end
1
+ module Tempora
2
+ module HasMonths
3
+ def months
4
+ Month.from(start_date)..Month.from(end_date)
5
+ end
5
6
 
6
- def each_month(&block)
7
- months.each(&block)
7
+ def each_month(&block)
8
+ months.each(&block)
9
+ end
8
10
  end
9
- end
11
+ end
@@ -1,11 +1,13 @@
1
1
  require 'week'
2
2
 
3
- module HasWeeks
4
- def weeks
5
- Week.from(start_date)..Week.from(end_date)
6
- end
3
+ module Tempora
4
+ module HasWeeks
5
+ def weeks
6
+ Week.from(start_date)..Week.from(end_date)
7
+ end
7
8
 
8
- def each_week(&block)
9
- weeks.each(&block)
9
+ def each_week(&block)
10
+ weeks.each(&block)
11
+ end
10
12
  end
11
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tempora
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
data/lib/tempora.rb CHANGED
@@ -10,5 +10,6 @@ require_relative "quarter"
10
10
 
11
11
  module Tempora
12
12
  class Error < StandardError; end
13
- # Your code goes here...
14
13
  end
14
+
15
+ Object.send(:include, Tempora)
data/lib/timeperiod.rb CHANGED
@@ -1,53 +1,53 @@
1
1
  require 'date'
2
+ require_relative 'tempora/has_days'
2
3
 
3
- class TimePeriod
4
- include Comparable
4
+ module Tempora
5
+ class TimePeriod
6
+ include Comparable
7
+ include HasDays
5
8
 
6
- attr_reader :start_date, :end_date, :year, :number
9
+ attr_reader :start_date, :end_date, :year, :number
7
10
 
8
- def initialize(start_date, end_date)
9
- @start_date = start_date
10
- @end_date = end_date
11
- end
11
+ def initialize(start_date, end_date)
12
+ @start_date = start_date
13
+ @end_date = end_date
14
+ end
12
15
 
13
- def range
14
- start_date..end_date
15
- end
16
+ def range
17
+ start_date..end_date
18
+ end
16
19
 
17
- def duration
18
- (end_date - start_date).to_i + 1
19
- end
20
-
21
- def days
22
- range.to_a
23
- end
20
+ def duration
21
+ (end_date - start_date).to_i + 1
22
+ end
24
23
 
25
- def each_day(&block)
26
- range.each(&block)
27
- end
24
+ def contains?(date)
25
+ range.cover?(date)
26
+ end
28
27
 
29
- def contains?(date)
30
- range.cover?(date)
31
- end
28
+ def overlaps?(other)
29
+ range.overlap?(other.range)
30
+ end
32
31
 
33
- def overlaps?(other)
34
- range.overlap?(other.range)
35
- end
36
-
37
- def intersection(other)
38
- return nil unless overlaps?(other)
32
+ def intersection(other)
33
+ return nil unless overlaps?(other)
39
34
 
40
- new_start = [start_date, other.start_date].max
41
- new_end = [end_date, other.end_date].min
35
+ new_start = [start_date, other.start_date].max
36
+ new_end = [end_date, other.end_date].min
42
37
 
43
- TimePeriod.new(new_start, new_end)
44
- end
38
+ TimePeriod.new(new_start, new_end)
39
+ end
45
40
 
46
- def <=>(other)
47
- start_date <=> other.start_date
48
- end
41
+ def shift(days)
42
+ TimePeriod.new(@start_date + days, @end_date + days)
43
+ end
44
+
45
+ def <=>(other)
46
+ start_date <=> other.start_date
47
+ end
49
48
 
50
- alias_method :begin, :start_date
51
- alias_method :end, :end_date
52
- alias_method :length, :duration
49
+ alias_method :begin, :start_date
50
+ alias_method :end, :end_date
51
+ alias_method :length, :duration
52
+ end
53
53
  end
data/lib/week.rb CHANGED
@@ -1,39 +1,41 @@
1
1
  require_relative 'timeperiod'
2
2
  require_relative 'tempora/initialization'
3
3
 
4
- class Week < TimePeriod
5
- extend Initialization
4
+ module Tempora
5
+ class Week < TimePeriod
6
+ extend Initialization
6
7
 
7
- def initialize(year, week)
8
- @year = Integer(year)
9
- @number = Integer(week)
8
+ def initialize(year, week)
9
+ @year = Integer(year)
10
+ @number = Integer(week)
10
11
 
11
- @start_date = Date.commercial(@year, @number, 1)
12
- @end_date = start_date + 6
13
- end
12
+ @start_date = Date.commercial(@year, @number, 1)
13
+ @end_date = start_date + 6
14
+ end
14
15
 
15
- def id(seperator="-")
16
- "#{year}#{seperator}W#{format('%02d', number)}"
17
- end
16
+ def id(seperator="-")
17
+ "#{year}#{seperator}W#{format('%02d', number)}"
18
+ end
18
19
 
19
- def to_s
20
- "Week #{number}, #{year}"
21
- end
20
+ def to_s
21
+ "Week #{number}, #{year}"
22
+ end
22
23
 
23
- def next
24
- self.class.from(start_date + 7)
25
- end
24
+ def next
25
+ self.class.from(start_date + 7)
26
+ end
26
27
 
27
- def prev
28
- self.class.from(start_date - 7)
29
- end
28
+ def prev
29
+ self.class.from(start_date - 7)
30
+ end
30
31
 
31
- alias_method :succ, :next
32
- alias_method :pred, :prev
32
+ alias_method :succ, :next
33
+ alias_method :pred, :prev
33
34
 
34
- private
35
+ private
35
36
 
36
- def self.initialization_parameter(date)
37
- [date.cwyear, date.cweek]
37
+ def self.initialization_parameter(date)
38
+ [date.cwyear, date.cweek]
39
+ end
38
40
  end
39
41
  end
data/lib/year.rb CHANGED
@@ -3,34 +3,36 @@ require_relative 'tempora/initialization'
3
3
  require_relative 'tempora/has_months'
4
4
  require_relative 'tempora/has_weeks'
5
5
 
6
- class Year < TimePeriod
7
- extend Initialization
8
- include HasWeeks
9
- include HasMonths
6
+ module Tempora
7
+ class Year < TimePeriod
8
+ extend Initialization
9
+ include HasWeeks
10
+ include HasMonths
10
11
 
11
- def initialize(year)
12
- @year = Integer(year)
12
+ def initialize(year)
13
+ @year = Integer(year)
13
14
 
14
- @start_date = Date.new(@year, 1, 1)
15
- @end_date = Date.new(@year, 12, 31)
16
- end
15
+ @start_date = Date.new(@year, 1, 1)
16
+ @end_date = Date.new(@year, 12, 31)
17
+ end
17
18
 
18
- def id
19
- year
20
- end
19
+ def id
20
+ year
21
+ end
21
22
 
22
- def to_s
23
- year.to_s
24
- end
23
+ def to_s
24
+ year.to_s
25
+ end
25
26
 
26
- def next
27
- self.class.new(year + 1)
28
- end
27
+ def next
28
+ self.class.new(year + 1)
29
+ end
29
30
 
30
- def prev
31
- self.class.new(year - 1)
32
- end
31
+ def prev
32
+ self.class.new(year - 1)
33
+ end
33
34
 
34
- alias_method :succ, :next
35
- alias_method :pred, :prev
35
+ alias_method :succ, :next
36
+ alias_method :pred, :prev
37
+ end
36
38
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tempora
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Power
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-15 00:00:00.000000000 Z
10
+ date: 2025-02-16 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Tempora is a lightweight Ruby library for handling months, weeks, quarters,
13
13
  and years with intuitive date-based calculations and range support.
@@ -20,10 +20,10 @@ files:
20
20
  - LICENSE.txt
21
21
  - README.md
22
22
  - Rakefile
23
- - lib/_timespan.rb
24
23
  - lib/month.rb
25
24
  - lib/quarter.rb
26
25
  - lib/tempora.rb
26
+ - lib/tempora/has_days.rb
27
27
  - lib/tempora/has_months.rb
28
28
  - lib/tempora/has_weeks.rb
29
29
  - lib/tempora/initialization.rb
data/lib/_timespan.rb DELETED
@@ -1,106 +0,0 @@
1
- require 'date'
2
-
3
- class TimeSpan
4
- include Comparable
5
-
6
- attr_reader :start_date, :end_date
7
-
8
- def initialize(start_date, end_date)
9
- @start_date = TimeSpan.from_date_like(start_date)
10
- @end_date = TimeSpan.from_date_like(end_date)
11
-
12
- raise ArgumentError, "start_date must be before end_date" if @start_date > @end_date
13
- end
14
-
15
- def self.from_date_like(date_like)
16
- if date_like.respond_to?(:year) && date_like.respond_to?(:month) && date_like.respond_to?(:day)
17
- Date.new(date_like.year, date_like.month, date_like.day)
18
- else
19
- raise ArgumentError, "Invalid date-like object: #{date_like.inspect}"
20
- end
21
- end
22
-
23
- def range
24
- @start_date..@end_date
25
- end
26
-
27
- def duration
28
- (@end_date - @start_date).to_i + 1
29
- end
30
-
31
- def overlaps?(other)
32
- @start_date <= other.end_date && @end_date >= other.start_date
33
- end
34
-
35
- def contains?(date)
36
- range.cover?(TimeSpan.from_date_like(date))
37
- end
38
-
39
- def shift(days)
40
- TimeSpan.new(@start_date + days, @end_date + days)
41
- end
42
-
43
- def intersection(other)
44
- return nil unless overlaps?(other)
45
-
46
- new_start = [@start_date, other.start_date].max
47
- new_end = [@end_date, other.end_date].min
48
-
49
- TimeSpan.new(new_start, new_end)
50
- end
51
-
52
- def <=>(other)
53
- start_date <=> other.start_date
54
- end
55
-
56
- def to_s
57
- "#{@start_date} to #{@end_date} (#{duration} days)"
58
- end
59
- end
60
- # 🔹 TimeSpan Class (For Any Date Range)
61
- #
62
- # This will handle custom periods, like fiscal years, school semesters, or project timelines.
63
- #
64
- # 🔹 How TimeSpan Works
65
- #
66
- # ✅ Define Any Custom Date Range
67
- # fiscal_year = TimeSpan.new(Date.new(2024, 4, 1), Date.new(2025, 3, 31))
68
- # puts fiscal_year.to_s
69
- # # => "2024-04-01 to 2025-03-31 (365 days)"
70
- # ✅ Check Overlaps
71
- # q2 = TimeSpan.new(Date.new(2024, 4, 1), Date.new(2024, 6, 30))
72
- # q3 = TimeSpan.new(Date.new(2024, 7, 1), Date.new(2024, 9, 30))
73
- # puts q2.overlaps?(q3) # => false
74
- # ✅ Check If a Date Falls Within the Range
75
- # semester = TimeSpan.new(Date.new(2024, 8, 1), Date.new(2024, 12, 15))
76
- # puts semester.contains?(Date.new(2024, 9, 10)) # => true
77
- # puts semester.contains?(Date.new(2025, 1, 1)) # => false
78
- # ✅ Shift Date Ranges
79
- # event = TimeSpan.new(Date.new(2024, 6, 10), Date.new(2024, 6, 15))
80
- # puts event.shift(7).to_s
81
- # # => "2024-06-17 to 2024-06-22 (6 days)"
82
- #
83
- # 🔹 Why TimeSpan is Useful
84
- #
85
- # ✅ Handles custom time ranges (fiscal years, semesters, event durations)
86
- # ✅ Works alongside Week, Month, Quarter, and Year
87
- # ✅ Supports overlapping checks and shifts
88
- #
89
- # 🔹 How intersection Works
90
- #
91
- # ✅ Two Overlapping Periods
92
- # t1 = TimeSpan.new(Date.new(2024, 3, 1), Date.new(2024, 3, 20))
93
- # t2 = TimeSpan.new(Date.new(2024, 3, 10), Date.new(2024, 3, 25))
94
- #
95
- # overlap = t1.intersection(t2)
96
- # puts overlap.to_s
97
- # # => "2024-03-10 to 2024-03-20 (11 days)"
98
- # ✅ No Overlap Returns nil
99
- # t3 = TimeSpan.new(Date.new(2024, 4, 1), Date.new(2024, 4, 10))
100
- # puts t1.intersection(t3)
101
- # # => nil
102
- # 🔹 Why intersection is Useful
103
- #
104
- # ✅ Find common time slots (e.g., two employees' available time)
105
- # ✅ Determine overlapping project phases
106
- # ✅ Works with any time period comparisons