tempora 0.2.0 → 0.2.2

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: 89b87271bfd8ca786ad770cdeb844a192d657363dcb55585edb5cc1b7d043714
4
+ data.tar.gz: 754ec4aad6c5c5ef115eea19ac6f01767d4cda2e8ba97cfb07aa72c4566d40d6
5
5
  SHA512:
6
- metadata.gz: ff6c9aec13bd9eb4ce86085043887f750101a722d64a30d6b8af43e7e52962632e91b8dbb74561cf0df02d05acb7928234ab892eafbe3fe1930bbe6f05cf64cb
7
- data.tar.gz: '08cc00d8bbac916783277803a0ef3279a7db353bd3a9e5743d2a0576824939e0b1b1039bea1143120068cf995060ac4bb0d827b553d73a2a368e902d69bbd40a'
6
+ metadata.gz: 6b75b131397179c4538cbe45bf10cec72ac8308d5e7b4297b2addbff3fd7fc707c0d96a70903d6fd8fe843138eb12b9051a9152b334ecb82fc31f90e1285d5b7
7
+ data.tar.gz: cb06dffbdb7f4f5df64732f689c230d52cc492040b6e78b1fbd814c50fe761bd0333d6b6d7520585c1102fcc8cec47108eebcf65d1cd30e3bde5cd84cdc72829
data/lib/month.rb CHANGED
@@ -2,49 +2,53 @@ 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
9
+
10
+ attr_reader :year, :number
8
11
 
9
- def initialize(year, month)
10
- @year = Integer(year)
11
- @number = Integer(month).clamp(1, 12)
12
+ def initialize(year, month)
13
+ @year = Integer(year)
14
+ @number = Integer(month).clamp(1, 12)
12
15
 
13
- @start_date = Date.new(@year, @number, 1)
14
- @end_date = Date.new(@year, @number, -1)
15
- end
16
+ @start_date = Date.new(@year, @number, 1)
17
+ @end_date = Date.new(@year, @number, -1)
18
+ end
16
19
 
17
- def id(seperator="-")
18
- "#{year}#{seperator}#{number.to_s.rjust(2, '0')}"
19
- end
20
+ def id(seperator="-")
21
+ "#{year}#{seperator}#{number.to_s.rjust(2, '0')}"
22
+ end
20
23
 
21
- def to_s
22
- "#{month_name} #{year}"
23
- end
24
+ def to_s
25
+ "#{month_name} #{year}"
26
+ end
24
27
 
25
- def month_name
26
- Date::MONTHNAMES[number]
27
- end
28
+ def month_name
29
+ Date::MONTHNAMES[number]
30
+ end
28
31
 
29
- def month_abbr
30
- Date::ABBR_MONTHNAMES[number]
31
- end
32
+ def month_abbr
33
+ Date::ABBR_MONTHNAMES[number]
34
+ end
32
35
 
33
- def next
34
- self.class.from(start_date.next_month) # @start_date >> 1
35
- end
36
+ def next
37
+ self.class.from(start_date.next_month) # @start_date >> 1
38
+ end
36
39
 
37
- def prev
38
- self.class.from(start_date.prev_month) # @start_date << 1
39
- end
40
+ def prev
41
+ self.class.from(start_date.prev_month) # @start_date << 1
42
+ end
40
43
 
41
- alias_method :month, :number
42
- alias_method :succ, :next
43
- alias_method :pred, :prev
44
+ alias_method :month, :number
45
+ alias_method :succ, :next
46
+ alias_method :pred, :prev
44
47
 
45
- private
48
+ private
46
49
 
47
- def self.initialization_parameter(date)
48
- [date.year, date.month]
50
+ def self.initialization_parameter(date)
51
+ [date.year, date.month]
52
+ end
49
53
  end
50
- end
54
+ end
data/lib/quarter.rb CHANGED
@@ -3,46 +3,50 @@ 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
11
+
12
+ attr_reader :year, :number
10
13
 
11
- def initialize(year, quarter)
12
- @year = Integer(year)
13
- @number = Integer(quarter).clamp(1,4)
14
+ def initialize(year, quarter)
15
+ @year = Integer(year)
16
+ @number = Integer(quarter).clamp(1,4)
14
17
 
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
18
+ start_month = (quarter - 1) * 3 + 1
19
+ @start_date = Date.new(year, start_month, 1)
20
+ @end_date = @start_date.next_month(3).prev_day
21
+ end
19
22
 
20
- def id(seperator="-")
21
- "#{year}#{seperator}Q#{number}"
22
- end
23
+ def id(seperator="-")
24
+ "#{year}#{seperator}Q#{number}"
25
+ end
23
26
 
24
- def to_s
25
- "Q#{number} #{year}"
26
- end
27
+ def to_s
28
+ "Q#{number} #{year}"
29
+ end
27
30
 
28
- def next
29
- self.class.from(start_date >> 3)
30
- end
31
+ def next
32
+ self.class.from(start_date >> 3)
33
+ end
31
34
 
32
- def prev
33
- self.class.from(start_date << 3)
34
- end
35
+ def prev
36
+ self.class.from(start_date << 3)
37
+ end
35
38
 
36
- alias_method :succ, :next
37
- alias_method :pred, :prev
39
+ alias_method :succ, :next
40
+ alias_method :pred, :prev
38
41
 
39
- private
42
+ private
40
43
 
41
- def self.initialization_parameter(date)
42
- [date.year, quarter_from_date(date)]
43
- end
44
+ def self.initialization_parameter(date)
45
+ [date.year, quarter_from_date(date)]
46
+ end
44
47
 
45
- def self.quarter_from_date(date)
46
- ((date.month - 1) / 3) + 1
48
+ def self.quarter_from_date(date)
49
+ ((date.month - 1) / 3) + 1
50
+ end
47
51
  end
48
- end
52
+ 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
@@ -0,0 +1,11 @@
1
+ module Tempora
2
+ module HasTime
3
+ def start_time
4
+ start_date.to_time
5
+ end
6
+
7
+ def end_time
8
+ end_date.next_day.to_time - 1
9
+ end
10
+ 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.2"
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,55 @@
1
1
  require 'date'
2
-
3
- class TimePeriod
4
- include Comparable
2
+ require_relative 'tempora/has_days'
3
+ require_relative 'tempora/has_time'
4
+
5
+ module Tempora
6
+ class TimePeriod
7
+ include Comparable
8
+ include HasDays
9
+ include HasTime
5
10
 
6
- attr_reader :start_date, :end_date, :year, :number
11
+ attr_reader :start_date, :end_date
7
12
 
8
- def initialize(start_date, end_date)
9
- @start_date = start_date
10
- @end_date = end_date
11
- end
12
-
13
- def range
14
- start_date..end_date
15
- end
13
+ def initialize(start_date, end_date)
14
+ @start_date = start_date
15
+ @end_date = end_date
16
+ end
16
17
 
17
- def duration
18
- (end_date - start_date).to_i + 1
19
- end
20
-
21
- def days
22
- range.to_a
23
- end
18
+ def range
19
+ start_date..end_date
20
+ end
24
21
 
25
- def each_day(&block)
26
- range.each(&block)
27
- end
22
+ def duration
23
+ (end_date - start_date).to_i + 1
24
+ end
28
25
 
29
- def contains?(date)
30
- range.cover?(date)
31
- end
26
+ def contains?(date)
27
+ range.cover?(date)
28
+ end
32
29
 
33
- def overlaps?(other)
34
- range.overlap?(other.range)
35
- end
30
+ def overlaps?(other)
31
+ range.overlap?(other.range)
32
+ end
36
33
 
37
- def intersection(other)
38
- return nil unless overlaps?(other)
34
+ def intersection(other)
35
+ return nil unless overlaps?(other)
39
36
 
40
- new_start = [start_date, other.start_date].max
41
- new_end = [end_date, other.end_date].min
37
+ new_start = [start_date, other.start_date].max
38
+ new_end = [end_date, other.end_date].min
42
39
 
43
- TimePeriod.new(new_start, new_end)
44
- end
40
+ TimePeriod.new(new_start, new_end)
41
+ end
45
42
 
46
- def <=>(other)
47
- start_date <=> other.start_date
48
- end
43
+ def shift(days)
44
+ TimePeriod.new(@start_date + days, @end_date + days)
45
+ end
46
+
47
+ def <=>(other)
48
+ start_date <=> other.start_date
49
+ end
49
50
 
50
- alias_method :begin, :start_date
51
- alias_method :end, :end_date
52
- alias_method :length, :duration
51
+ alias_method :begin, :start_date
52
+ alias_method :end, :end_date
53
+ alias_method :length, :duration
54
+ end
53
55
  end
data/lib/week.rb CHANGED
@@ -1,39 +1,43 @@
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
+ attr_reader :year, :number
10
9
 
11
- @start_date = Date.commercial(@year, @number, 1)
12
- @end_date = start_date + 6
13
- end
10
+ def initialize(year, week)
11
+ @year = Integer(year)
12
+ @number = Integer(week)
14
13
 
15
- def id(seperator="-")
16
- "#{year}#{seperator}W#{format('%02d', number)}"
17
- end
14
+ @start_date = Date.commercial(@year, @number, 1)
15
+ @end_date = start_date + 6
16
+ end
17
+
18
+ def id(seperator="-")
19
+ "#{year}#{seperator}W#{format('%02d', number)}"
20
+ end
18
21
 
19
- def to_s
20
- "Week #{number}, #{year}"
21
- end
22
+ def to_s
23
+ "Week #{number}, #{year}"
24
+ end
22
25
 
23
- def next
24
- self.class.from(start_date + 7)
25
- end
26
+ def next
27
+ self.class.from(start_date + 7)
28
+ end
26
29
 
27
- def prev
28
- self.class.from(start_date - 7)
29
- end
30
+ def prev
31
+ self.class.from(start_date - 7)
32
+ end
30
33
 
31
- alias_method :succ, :next
32
- alias_method :pred, :prev
34
+ alias_method :succ, :next
35
+ alias_method :pred, :prev
33
36
 
34
- private
37
+ private
35
38
 
36
- def self.initialization_parameter(date)
37
- [date.cwyear, date.cweek]
39
+ def self.initialization_parameter(date)
40
+ [date.cwyear, date.cweek]
41
+ end
38
42
  end
39
43
  end
data/lib/year.rb CHANGED
@@ -3,34 +3,38 @@ 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
11
+
12
+ attr_reader :year
10
13
 
11
- def initialize(year)
12
- @year = Integer(year)
14
+ def initialize(year)
15
+ @year = Integer(year)
13
16
 
14
- @start_date = Date.new(@year, 1, 1)
15
- @end_date = Date.new(@year, 12, 31)
16
- end
17
+ @start_date = Date.new(@year, 1, 1)
18
+ @end_date = Date.new(@year, 12, 31)
19
+ end
17
20
 
18
- def id
19
- year
20
- end
21
+ def id
22
+ year
23
+ end
21
24
 
22
- def to_s
23
- year.to_s
24
- end
25
+ def to_s
26
+ year.to_s
27
+ end
25
28
 
26
- def next
27
- self.class.new(year + 1)
28
- end
29
+ def next
30
+ self.class.new(year + 1)
31
+ end
29
32
 
30
- def prev
31
- self.class.new(year - 1)
32
- end
33
+ def prev
34
+ self.class.new(year - 1)
35
+ end
33
36
 
34
- alias_method :succ, :next
35
- alias_method :pred, :prev
37
+ alias_method :succ, :next
38
+ alias_method :pred, :prev
39
+ end
36
40
  end
data/tempora-0.2.1.gem ADDED
Binary file
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.2
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-19 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,11 +20,12 @@ 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
+ - lib/tempora/has_time.rb
28
29
  - lib/tempora/has_weeks.rb
29
30
  - lib/tempora/initialization.rb
30
31
  - lib/tempora/version.rb
@@ -32,6 +33,7 @@ files:
32
33
  - lib/week.rb
33
34
  - lib/year.rb
34
35
  - sig/tempus.rbs
36
+ - tempora-0.2.1.gem
35
37
  homepage: https://github.com/max-power/tempora
36
38
  licenses:
37
39
  - MIT
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