uk_academic_calendar 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 71d754790b2fdbde926c3ba208b5e860d00d5e1804ea07c74bab60d9478807d4
4
+ data.tar.gz: 4bbc74989d5cffb7e3fda1789a01112e45379474b0b4e6cad8e3645e8f75a507
5
+ SHA512:
6
+ metadata.gz: 89aadec469b4df7320211d795dbf992c7e55083f486f8767dd6083d236d0f5a3ba8208654861545d2fe0ab60022bccd51ed0deb501cbd64f94ae88f10722f672
7
+ data.tar.gz: 163abbbdde711855ab3e6218278a61d84b58c83025c74dc397dd346662498de48009f7761f3692f36c0b6b661dac7ab892d0f577cb014da8a1a0a3b9feffc622
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,22 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ NewCops: enable
4
+
5
+ Style/StringLiterals:
6
+ Enabled: true
7
+ EnforcedStyle: single_quotes
8
+
9
+ Style/StringLiteralsInInterpolation:
10
+ Enabled: true
11
+ EnforcedStyle: single_quotes
12
+
13
+ Style/SymbolArray:
14
+ EnforcedStyle: brackets
15
+
16
+ Layout/LineLength:
17
+ Max: 120
18
+
19
+ Metrics/BlockLength:
20
+ Exclude:
21
+ - '*.gemspec'
22
+ - 'spec/**/*.rb'
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Matthew Smith
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.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # UKAcademicCalendar
2
+
3
+ Designed to assist in Ruby programs dealing with the UK Academic Calendar, i.e. the Sept - Sept academic year, and the 3 'terms' (Autumn, Spring, Summer).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'uk_academic_calendar'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install uk_academic_calendar
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'uk_academic_calendar'
25
+
26
+ # Assuming today is 20th Jan 2024
27
+ Date.today.academic_year #=> 2023
28
+ Date.today.beginning_of_academic_year #=> 2023-09-01
29
+ Date.today.end_of_academic_year #=> 2024-08-31
30
+ # or...
31
+ Time.now.academic_year #=> 2023
32
+ Time.now.beginning_of_academic_year #=> 2023-09-01 00:00:00 +0100
33
+ Time.now.end_of_academic_year #=> 2024-08-31 23:59:59.999999999 +0100
34
+
35
+ term_now = Date.today.academic_term #=> Spring 2023/2024
36
+ term_now.start_date #=> 2024-01-01
37
+ term_now.end_date #=> 2024-03-31, i.e. Easter Sunday
38
+ term_now.start_date = '2025-01-01' #=> raises #UKAcademicCalendar::InvalidTermStart error
39
+ term_now.to_range #=> (2024-01-01..2024-03-31)
40
+ term_now.all_dates #=> #<SortedSet:{Mon, 01 Jan 2024...}
41
+ ```
42
+
43
+ See rubydoc [docs](https://www.rubydoc.info/github/m-smiff/uk_academic_calendar/main) for full details on the API (with help from Yard).
44
+
45
+ ## Development
46
+
47
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
48
+
49
+ 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).
50
+
51
+ ## TODO
52
+
53
+ - Further granularity around the 'teachable', and inversely, 'unteachable' days within a term (e.g. adding bank holidays/inset days etc)
54
+ - Considering the above, implementation of e.g., `#teachable_days` and `#non_teachable_days` returning sorted sets of applicable dates
55
+ - Setting of 'contexts' so terms understand what dates to apply for a given 'context' (e.g. a particular local authority)
56
+
57
+ ## Contributing
58
+
59
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/uk_academic_calendar.
60
+
61
+ ## License
62
+
63
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require 'rubocop/rake_task'
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: [:spec, :rubocop]
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'term'
4
+
5
+ module UKAcademicCalendar
6
+ # Concrete class allowing instantiation of instances of an Autumn term, for a given academic year
7
+ class AutumnTerm < Term
8
+ # @return [Date] Sep 1st
9
+ def nominal_start_date
10
+ @nominal_start_date ||= Date.today.beginning_of_academic_year.change(year: academic_year)
11
+ end
12
+
13
+ # @return [Date] Dec 31st
14
+ def nominal_end_date
15
+ @nominal_end_date ||= nominal_start_date.end_of_year
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/date'
4
+ require_relative '../mixins/date_and_time_instance_methods'
5
+
6
+ class Date
7
+ # includes "UKAcademicCalendar::DateAndTimeInstanceMethods"
8
+ # @!parse include UKAcademicCalendar::DateAndTimeInstanceMethods
9
+ include UKAcademicCalendar::DateAndTimeInstanceMethods
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../mixins/succ_slashable'
4
+
5
+ class Integer
6
+ # prepends "UKAcademicCalendar::SuccSlashable"
7
+ # @!parse prepend UKAcademicCalendar::SuccSlashable
8
+ prepend UKAcademicCalendar::SuccSlashable
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/time'
4
+ require_relative '../mixins/date_and_time_instance_methods'
5
+
6
+ class Time
7
+ # includes "UKAcademicCalendar::DateAndTimeInstanceMethods"
8
+ # @!parse include UKAcademicCalendar::DateAndTimeInstanceMethods
9
+ include UKAcademicCalendar::DateAndTimeInstanceMethods
10
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UKAcademicCalendar
4
+ class Error < StandardError; end
5
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'error'
4
+
5
+ module UKAcademicCalendar
6
+ # Error class raised when a concrete term class is deemed to have an invalid date-bound
7
+ class InvalidTermBound < Error
8
+ def initialize(date, comparand)
9
+ @date = date
10
+ @comparand = comparand
11
+ super(message)
12
+ end
13
+
14
+ # @return [String]
15
+ def message
16
+ "#{@date} is invalid. Must be #{comparison_qualifier} #{@comparand}"
17
+ end
18
+
19
+ private
20
+
21
+ def comparison_qualifier
22
+ @comparand.instance_of?(Range) && 'within'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'invalid_term_bound'
4
+
5
+ module UKAcademicCalendar
6
+ # @see InvalidTermBound
7
+ class InvalidTermEnd < InvalidTermBound
8
+ private
9
+
10
+ def comparison_qualifier
11
+ super || '>'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'invalid_term_bound'
4
+
5
+ module UKAcademicCalendar
6
+ # @see InvalidTermBound
7
+ class InvalidTermStart < InvalidTermBound
8
+ private
9
+
10
+ def comparison_qualifier
11
+ super || '<'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UKAcademicCalendar
4
+ # Mixin included in Date and Time classes providing academic year related instance methods
5
+ module DateAndTimeInstanceMethods
6
+ # @return [Integer] integer representing the calendar year within the academic year started in
7
+ # @example
8
+ # Date.new(2024, 8, 31).academic_year #=> 2023
9
+ # Time.new(2024, 9, 1, 12).academic_year #=> 2024
10
+ def academic_year
11
+ return year if yday >= start_yday
12
+
13
+ year - 1
14
+ end
15
+
16
+ # @return [#to_date] instance of self.class representing the beginning of the academic year
17
+ # @example
18
+ # Date.new(2024, 8, 31).beginning_of_academic_year #=> 2023-09-01
19
+ # Time.new(2024, 9, 1, 12).beginning_of_academic_year #=> 2024-09-01 00:00:00 +0100
20
+ def beginning_of_academic_year
21
+ shifted = change(year: academic_year, month: YEAR_OFFSET_START_MONTH, day: 1)
22
+ return shifted unless acts_like? :time
23
+
24
+ shifted.beginning_of_day
25
+ end
26
+
27
+ # @return [#to_date] instance of self.class representing the end of the academic year
28
+ # @example
29
+ # Date.new(2024, 8, 31).end_of_academic_year #=> 2024-08-31
30
+ # Time.new(2024, 9, 1, 12).end_of_academic_year #=> 2025-08-31 23:59:59.999999999 +0100
31
+ def end_of_academic_year
32
+ shifted = beginning_of_academic_year.next_year.prev_day
33
+ return shifted unless acts_like? :time
34
+
35
+ shifted.end_of_day
36
+ end
37
+
38
+ # @return [Integer] integer representing the month of the academic year including self
39
+ # @example
40
+ # Date.new(2024, 8, 31).academic_year_month #=> 12
41
+ # Time.new(2024, 11, 1, 12).academic_year_month #=> 3
42
+ def academic_year_month
43
+ ac_yr_start_month = YEAR_OFFSET_START_MONTH
44
+ ((month - ac_yr_start_month) % 12) + 1
45
+ end
46
+
47
+ # @return [UKAcademicCalendar::AutumnTerm, UKAcademicCalendar::SpringTerm, UKAcademicCalendar::SummerTerm]
48
+ # term object including self
49
+ # @example
50
+ # Date.new(2024, 8, 31).academic_term #=> Summer 2023/2024
51
+ # Time.new(2024, 11, 1, 12).academic_term #=> Autumn 2024/2025
52
+ def academic_term
53
+ UKAcademicCalendar.term_including self
54
+ end
55
+
56
+ # @return [#to_date] instance of self.class representing the beginning of the academic term including self
57
+ # @example
58
+ # Date.new(2024, 2, 25).beginning_of_academic_term #=> 2024-01-01
59
+ # Time.new(2024, 9, 1, 12).beginning_of_academic_term #=> 2024-09-01 00:00:00 +0100
60
+ def beginning_of_academic_term
61
+ term_start = academic_term.start_date
62
+ shifted = change(year: term_start.year, month: term_start.month, day: term_start.day)
63
+ return shifted unless acts_like? :time
64
+
65
+ shifted.beginning_of_day
66
+ end
67
+
68
+ # @return [#to_date] instance of self.class representing the end of the academic term including self
69
+ # @example
70
+ # Date.new(2024, 11, 25).end_of_academic_term #=> 2024-12-31
71
+ # Time.new(2024, 7, 1, 12).end_of_academic_term #=> 2024-08-31 23:59:999999999 +0100
72
+ def end_of_academic_term
73
+ term_end = academic_term.end_date
74
+ shifted = change(year: term_end.year, month: term_end.month, day: term_end.day)
75
+ return shifted unless acts_like? :time
76
+
77
+ shifted.end_of_day
78
+ end
79
+
80
+ private
81
+
82
+ def start_yday
83
+ self.class.new(year, YEAR_OFFSET_START_MONTH, 1).yday
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UKAcademicCalendar
4
+ # Mixin included in Integer class
5
+ module SuccSlashable
6
+ # @param base [Integer]
7
+ # @param slash_succ [Boolean] option specifying whether to leverage the "slash_succ" option
8
+ # @return [String] string where self is concatenated with the value succeeding self, seperated by a forward slash
9
+ # @example
10
+ # 2023.to_s(slash_succ: true) #=> "2023/2024"
11
+ def to_s(base = 10, slash_succ: false)
12
+ if slash_succ
13
+ "#{to_i}/#{to_i.succ}"
14
+ else
15
+ super(base)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'term'
4
+
5
+ module UKAcademicCalendar
6
+ # Concrete class allowing instantiation of instances of an spring term, for a given academic year
7
+ class SpringTerm < Term
8
+ # @return [Date] Jan 1st
9
+ def nominal_start_date
10
+ nominal_end_date.beginning_of_year
11
+ end
12
+
13
+ # @return [Date] Easter Sunday
14
+ def nominal_end_date
15
+ Easter.easter(academic_year + 1)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'term'
4
+
5
+ module UKAcademicCalendar
6
+ # Concrete class allowing instantiation of instances of an Summer term, for a given academic year
7
+ class SummerTerm < Term
8
+ # @return [Date] the Monday after Easter Sunday
9
+ def nominal_start_date
10
+ Easter.easter(academic_year + 1).next_day
11
+ end
12
+
13
+ # @return [Date] Aug 31st
14
+ def nominal_end_date
15
+ nominal_start_date.end_of_academic_year
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'abstract_class'
4
+ require 'easter'
5
+ require 'forwardable'
6
+ require 'sorted_set'
7
+
8
+ require_relative 'errors/invalid_term_start'
9
+ require_relative 'errors/invalid_term_end'
10
+
11
+ module UKAcademicCalendar
12
+ # Abstract class representing blueprint behaviour for academic terms, bounded by writeable start and end dates
13
+ class Term
14
+ extend AbstractClass
15
+
16
+ extend Forwardable
17
+ # @!method include?
18
+ # Forwards to Range
19
+ # @see Range#include?
20
+ # @!method each
21
+ # Forwards to Range
22
+ # @see Range#each
23
+ def_delegators :to_range, :include?, :each
24
+
25
+ # @param academic_year [Integer]
26
+ # @return [UKAcademicCalendar::AutumnTerm, UKAcademicCalendar::SpringTerm, UKAcademicCalendar::SummerTerm]
27
+ def initialize(academic_year)
28
+ @academic_year = academic_year
29
+ @season = extract_season_from_class_name
30
+ @start_date = nominal_start_date
31
+ @end_date = nominal_end_date
32
+ end
33
+
34
+ # @return [Integer] the calendar year within which the term's academic year starts in
35
+ attr_reader :academic_year
36
+ # @overload start_date
37
+ # @overload start_date=(value)
38
+ # Sets value to @start_date, first going through validation
39
+ # @param val [#to_date, nil] the start date of the term. If nil given, falls back to #nominal_start_date
40
+ # @return [Date] assigned date value
41
+ # @raise [UKAcademicCalendar::InvalidTermStart, UKAcademicCalendar::InvalidTermEnd] if the assigned date is
42
+ # considered invalid
43
+ attr_accessor :start_date
44
+ # @overload end_date
45
+ # @overload end_date=(value)
46
+ # Sets value to @end_date, first going through validation
47
+ # @param val [#to_date, nil] the end date of the term. If nil given, falls back to #nominal_end_date
48
+ # @return [Date] assigned date value
49
+ # @raise [UKAcademicCalendar::InvalidTermStart, UKAcademicCalendar::InvalidTermEnd] if the assigned date is
50
+ # considered invalid
51
+ attr_accessor :end_date
52
+ # @return [Symbol] the name of the season the term spans
53
+ attr_reader :season
54
+
55
+ # @return [Integer] the integer hash value for self
56
+ def hash
57
+ [self.class, academic_year, start_date, end_date].hash
58
+ end
59
+
60
+ # @param other [#hash] any object that responds to `#hash`
61
+ # @return [Boolean] true if self and other are of the same class, academic_year, and have eql start and end dates.
62
+ # Otherwise returns false.
63
+ def eql?(other)
64
+ hash == other.hash
65
+ end
66
+ alias == eql?
67
+
68
+ # @return [String] prettified string describing the term, e.g. "Summer 2023/2024"
69
+ # @example
70
+ # term = UKAcademicCalendar::SummerTerm 2023
71
+ # term.to_s #=> "Summer 2023/2024"
72
+ def to_s
73
+ "#{season.to_s.titleize} #{academic_year.to_s(slash_succ: true)}"
74
+ end
75
+
76
+ def inspect
77
+ to_s
78
+ end
79
+
80
+ def start_date=(val) # rubocop:disable Lint/DuplicateMethods
81
+ @start_date = validate_date(val&.to_date, :start)
82
+ end
83
+
84
+ def end_date=(val) # rubocop:disable Lint/DuplicateMethods
85
+ @end_date = validate_date(val&.to_date, :end)
86
+ end
87
+
88
+ # @return [Range] range bounded by start and end dates, end inclusive
89
+ def to_range
90
+ start_date..end_date
91
+ end
92
+
93
+ # @return [SortedSet<Date>] sorted set of dates making up the term
94
+ def all_dates
95
+ SortedSet.new(to_range.to_a)
96
+ end
97
+
98
+ private
99
+
100
+ def extract_season_from_class_name
101
+ self.class.to_s.demodulize[/(.*)Term\z/, 1].downcase.to_sym
102
+ end
103
+
104
+ def validate_date(date, bound)
105
+ return public_send(:"nominal_#{bound}_date") unless date.present?
106
+
107
+ # First validate the date is within bounds...
108
+ validate_within_bounds(date, nominal_start_date..nominal_end_date, bound)
109
+ # ...then validate the dates are in acceptable (i.e. start < end) sequence
110
+ validate_sequence(date, bound)
111
+
112
+ date
113
+ end
114
+
115
+ def validate_within_bounds(date, range, date_bound)
116
+ return if date.in? range
117
+
118
+ raise date_error_class(date_bound).new(date, range)
119
+ end
120
+
121
+ def validate_sequence(date, date_bound)
122
+ operator, comparand = date_bound == :start ? [:<, :end_date] : [:>, :start_date]
123
+ # Assuming this is for :start_date, return if #start_date == nil OR date < #end_date
124
+ return if send(comparand).nil? || date.send(operator, send(comparand))
125
+
126
+ raise date_error_class(date_bound).new(date, send(comparand))
127
+ end
128
+
129
+ def date_error_class(date_bound)
130
+ case date_bound
131
+ when :start then InvalidTermStart
132
+ when :end then InvalidTermEnd
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UKAcademicCalendar
4
+ VERSION = '1.0.0'
5
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uk_academic_calendar/version'
4
+
5
+ require 'uk_academic_calendar/core_ext/date'
6
+ require 'uk_academic_calendar/core_ext/time'
7
+ require 'uk_academic_calendar/core_ext/integer'
8
+ require 'uk_academic_calendar/autumn_term'
9
+ require 'uk_academic_calendar/spring_term'
10
+ require 'uk_academic_calendar/summer_term'
11
+
12
+ require 'active_support/core_ext/class/subclasses'
13
+ require 'active_support/core_ext/object/inclusion'
14
+
15
+ # Top-level namespace, itself implementing a number of constants and module methods documented below.
16
+ module UKAcademicCalendar
17
+ # The month-number corresponding to the first month within the calendar year that the academic year starts in.
18
+ YEAR_OFFSET_START_MONTH = 9 # September
19
+ # The season-names designating the 3 terms.
20
+ SEASONS = [:autumn, :spring, :summer].freeze
21
+
22
+ class << self
23
+ # @!method autumn_term
24
+ # @param academic_year [Integer] the calendar year the academic year starts in.
25
+ # @return [UKAcademicCalendar::AutumnTerm] instance of Autumn term.
26
+
27
+ # @!method spring_term
28
+ # @param academic_year [Integer] the calendar year the academic year starts in.
29
+ # @return [UKAcademicCalendar::SpringTerm] instance of Spring term.
30
+
31
+ # @!method summer_term
32
+ # @param academic_year [Integer] the calendar year the academic year starts in.
33
+ # @return [UKAcademicCalendar::SummerTerm] instance of Summer term.
34
+ SEASONS.each do |season|
35
+ define_method(:"#{season}_term") do |academic_year|
36
+ klass = Term.descendants.find { |c| c.to_s.demodulize.downcase.start_with? season.to_s }
37
+ klass.new(academic_year)
38
+ end
39
+ end
40
+
41
+ # @param academic_year [Integer] the calendar year the academic year starts in.
42
+ # @return [Array(UKAcademicCalendar::AutumnTerm, UKAcademicCalendar::SpringTerm, UKAcademicCalendar::SummerTerm)]
43
+ # array containing ordered instances of Autumn, Spring and Summer term.
44
+ def all_terms(academic_year)
45
+ SEASONS.map { |term_name| public_send(:"#{term_name}_term", academic_year) }
46
+ end
47
+
48
+ # Convenience method for retrieving the term object including Date.today
49
+ # @return [UKAcademicCalendar::AutumnTerm, UKAcademicCalendar::SpringTerm, UKAcademicCalendar::SummerTerm] instance
50
+ # of Autumn/Spring/Summer term deemed to contain today's date.
51
+ def term_now
52
+ term_including
53
+ end
54
+
55
+ # @param val [#to_date]
56
+ # @return [UKAcademicCalendar::AutumnTerm, UKAcademicCalendar::SpringTerm, UKAcademicCalendar::SummerTerm] instance
57
+ # of Autumn/Spring/Summer term deemed to contain date param.
58
+ def term_including(val = Date.today)
59
+ date = val.to_date
60
+ all_terms(date.academic_year).find { |term| date.in? term }
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uk_academic_calendar
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-02-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: abstract_class
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '6.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '6.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: easter
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sorted_set
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ description: Designed to assist in Ruby programs dealing with the UK Academic Calendar
70
+ email:
71
+ - jetnova@pm.me
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".rspec"
77
+ - ".rubocop.yml"
78
+ - ".ruby-version"
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/uk_academic_calendar.rb
83
+ - lib/uk_academic_calendar/autumn_term.rb
84
+ - lib/uk_academic_calendar/core_ext/date.rb
85
+ - lib/uk_academic_calendar/core_ext/integer.rb
86
+ - lib/uk_academic_calendar/core_ext/time.rb
87
+ - lib/uk_academic_calendar/errors/error.rb
88
+ - lib/uk_academic_calendar/errors/invalid_term_bound.rb
89
+ - lib/uk_academic_calendar/errors/invalid_term_end.rb
90
+ - lib/uk_academic_calendar/errors/invalid_term_start.rb
91
+ - lib/uk_academic_calendar/mixins/date_and_time_instance_methods.rb
92
+ - lib/uk_academic_calendar/mixins/succ_slashable.rb
93
+ - lib/uk_academic_calendar/spring_term.rb
94
+ - lib/uk_academic_calendar/summer_term.rb
95
+ - lib/uk_academic_calendar/term.rb
96
+ - lib/uk_academic_calendar/version.rb
97
+ homepage: https://www.github.com/m-smiff/uk_academic_calendar
98
+ licenses:
99
+ - MIT
100
+ metadata:
101
+ homepage_uri: https://www.github.com/m-smiff/uk_academic_calendar
102
+ documentation_uri: https://www.rubydoc.info/github/m-smiff/uk_academic_calendar/main
103
+ source_code_uri: https://www.github.com/m-smiff/uk_academic_calendar
104
+ changelog_uri: https://www.github.com/m-smiff/uk_academic_calendar
105
+ rubygems_mfa_required: 'true'
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 2.6.0
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubygems_version: 3.5.5
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: UK Academic Calendar
125
+ test_files: []