russian_workdays 2.6.0 → 2.7.0

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: 615b35e7fbf6a624b93b48e8cd1c958d7f32b8f2e04d131229aaf154479f8588
4
- data.tar.gz: b5ac049a0a2ec1e3ddd4f23958193e49f9cc4a5a3a6050e281f1f8b270bb5f88
3
+ metadata.gz: 202f95e7558fdf25ad74f1c2b22af5802bb0e2c44c51a6522f262127a7a13179
4
+ data.tar.gz: e025d8cd63eb3c63f8b34d6209c1470fce148f4f5af64155399777e9244f4563
5
5
  SHA512:
6
- metadata.gz: c92da678653c77e49932bff37af2f9ae55214a6a3fb3e26d3ccecdde8af8a662ee86822b20273b528c2e0608d3b5bad57d83e2bc4b495d998b6c80fbbcc500b2
7
- data.tar.gz: 70750a19c6aab14cae25925529e6ff5b0919ba00ba85ea6eb27398b3c9ca412a5b7564e4febcc4c71cc9b16398ee80443d6d08766dcfed8e3856794ca13b1bdb
6
+ metadata.gz: d2d0c957efda7da66731790c28931ae96d693089dbb1ce4a0c810b6e37f026e06ab1b98351762199eb76207a36a789694b2385c24226c653297cede860b9ad28
7
+ data.tar.gz: 7a96dfcaebb479bfe423121ba739178897b5ddf7a8f1309d5a40169f0dcfe8cf9e2d4f862b42dc48168b1302b41fb2c957740ca96a69b58ccd5915a0bd9cc960
data/.rubocop.yml CHANGED
@@ -1,155 +1,8 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.5
3
- # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
4
- # to ignore them, so only the ones explicitly set in this file are enabled.
5
- DisabledByDefault: true
6
-
7
- # Prefer &&/|| over and/or.
8
- Style/AndOr:
9
- Enabled: true
10
-
11
- # Do not use braces for hash literals when they are the last argument of a
12
- # method call.
13
- Style/BracesAroundHashParameters:
14
- Enabled: true
15
- EnforcedStyle: context_dependent
16
-
17
- # Align `when` with `case`.
18
- Layout/CaseIndentation:
19
- Enabled: true
20
-
21
- # Align comments with method definitions.
22
- Layout/CommentIndentation:
23
- Enabled: true
24
-
25
- Layout/ElseAlignment:
26
- Enabled: true
27
-
28
- # Align `end` with the matching keyword or starting expression except for
29
- # assignments, where it should be aligned with the LHS.
30
- Layout/EndAlignment:
31
- Enabled: true
32
- EnforcedStyleAlignWith: variable
33
- AutoCorrect: true
34
-
35
- Layout/EmptyLineAfterMagicComment:
36
- Enabled: true
37
-
38
- # In a regular class definition, no empty lines around the body.
39
- Layout/EmptyLinesAroundClassBody:
40
- Enabled: true
41
-
42
- # In a regular method definition, no empty lines around the body.
43
- Layout/EmptyLinesAroundMethodBody:
44
- Enabled: true
45
-
46
- # In a regular module definition, no empty lines around the body.
47
- Layout/EmptyLinesAroundModuleBody:
48
- Enabled: true
49
-
50
- Layout/FirstParameterIndentation:
51
- Enabled: true
52
-
53
- # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
54
- Style/HashSyntax:
55
- Enabled: true
56
-
57
- # Method definitions after `private` or `protected` isolated calls need one
58
- # extra level of indentation.
59
- Layout/IndentationConsistency:
60
- Enabled: true
61
- EnforcedStyle: rails
62
-
63
- # Two spaces, no tabs (for indentation).
64
- Layout/IndentationWidth:
65
- Enabled: true
66
-
67
- Layout/LeadingCommentSpace:
68
- Enabled: true
69
-
70
- Layout/SpaceAfterColon:
71
- Enabled: true
72
-
73
- Layout/SpaceAfterComma:
74
- Enabled: true
75
-
76
- Layout/SpaceAroundEqualsInParameterDefault:
77
- Enabled: true
78
-
79
- Layout/SpaceAroundKeyword:
80
- Enabled: true
81
-
82
- Layout/SpaceAroundOperators:
83
- Enabled: true
84
-
85
- Layout/SpaceBeforeComma:
86
- Enabled: true
87
-
88
- Layout/SpaceBeforeFirstArg:
89
- Enabled: true
90
-
91
- Style/DefWithParentheses:
92
- Enabled: true
93
-
94
- # Defining a method with parameters needs parentheses.
95
- Style/MethodDefParentheses:
96
- Enabled: true
97
-
98
- Style/FrozenStringLiteralComment:
99
- Enabled: true
100
- EnforcedStyle: always
101
-
102
- # Use `foo {}` not `foo{}`.
103
- Layout/SpaceBeforeBlockBraces:
104
- Enabled: true
105
-
106
- # Use `foo { bar }` not `foo {bar}`.
107
- Layout/SpaceInsideBlockBraces:
108
- Enabled: true
109
-
110
- # Use `{ a: 1 }` not `{a:1}`.
111
- Layout/SpaceInsideHashLiteralBraces:
112
- Enabled: true
113
-
114
- Layout/SpaceInsideParens:
115
- Enabled: true
116
-
117
- # Check quotes usage according to lint rule below.
118
- Style/StringLiterals:
119
- Enabled: true
120
- EnforcedStyle: double_quotes
121
-
122
- # Detect hard tabs, no hard tabs.
123
- Layout/Tab:
124
- Enabled: true
125
-
126
- # Blank lines should not have any spaces.
127
- Layout/TrailingBlankLines:
128
- Enabled: true
129
-
130
- # No trailing whitespace.
131
- Layout/TrailingWhitespace:
132
- Enabled: true
133
-
134
- # Use quotes for string literals when they are enough.
135
- Style/UnneededPercentQ:
136
- Enabled: true
137
-
138
- # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
139
- Lint/RequireParentheses:
140
- Enabled: true
141
-
142
- Lint/StringConversionInInterpolation:
143
- Enabled: true
144
-
145
- Style/RedundantReturn:
146
- Enabled: true
147
- AllowMultipleReturnValues: true
148
-
149
- Style/Semicolon:
150
- Enabled: true
151
- AllowAsExpressionSeparator: true
152
-
153
- # Prefer Foo.method over Foo::method
154
- Style/ColonMethodCall:
155
- Enabled: true
2
+ TargetRubyVersion: 2.6
3
+ Documentation:
4
+ Enabled: false
5
+ Lint/MissingSuper:
6
+ Enabled: false
7
+ Metrics/BlockLength:
8
+ AllowedMethods: ['describe', 'context']
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## [2.7.0] - 2025-02-03
2
+
3
+ - Исправлены ошибки данных для 2023 года
4
+ - Добавлены данные для 2024 года
5
+ - Добавлены данные для 2025 года
6
+ - Отрефакторен код гема
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
5
 
6
6
  # Default directory to look in is `/specs`
7
7
  # Run with `rake spec`
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'russian_workdays'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -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
@@ -436,127 +436,70 @@
436
436
  - 2022-02-22
437
437
  - 2022-03-05
438
438
  - 2022-11-03
439
+ ---
439
440
  2023:
440
441
  :holidays:
441
- - 2023-01-01
442
- - 2023-01-02
443
- - 2023-01-03
444
- - 2023-01-04
445
- - 2023-01-05
446
- - 2023-01-06
447
- - 2023-01-07
448
- - 2023-01-08
449
- - 2023-01-14
450
- - 2023-01-15
451
- - 2023-01-21
452
- - 2023-01-22
453
- - 2023-01-28
454
- - 2023-01-29
455
- - 2023-02-04
456
- - 2023-02-05
457
- - 2023-02-11
458
- - 2023-02-12
459
- - 2023-02-18
460
- - 2023-02-19
461
- - 2023-02-23
462
- - 2023-02-24
463
- - 2023-02-25
464
- - 2023-02-26
465
- - 2023-03-04
466
- - 2023-03-05
467
- - 2023-03-08
468
- - 2023-03-11
469
- - 2023-03-12
470
- - 2023-03-18
471
- - 2023-03-19
472
- - 2023-03-25
473
- - 2023-03-26
474
- - 2023-04-01
475
- - 2023-04-02
476
- - 2023-04-08
477
- - 2023-04-09
478
- - 2023-04-15
479
- - 2023-04-16
480
- - 2023-04-22
481
- - 2023-04-23
482
- - 2023-04-29
483
- - 2023-04-30
484
- - 2023-05-01
485
- - 2023-05-06
486
- - 2023-05-07
487
- - 2023-05-08
488
- - 2023-05-09
489
- - 2023-05-13
490
- - 2023-05-14
491
- - 2023-05-20
492
- - 2023-05-21
493
- - 2023-05-27
494
- - 2023-05-28
495
- - 2023-06-03
496
- - 2023-06-04
497
- - 2023-06-10
498
- - 2023-06-11
499
- - 2023-06-12
500
- - 2023-06-17
501
- - 2023-06-18
502
- - 2023-06-24
503
- - 2023-06-25
504
- - 2023-07-01
505
- - 2023-07-02
506
- - 2023-07-08
507
- - 2023-07-09
508
- - 2023-07-15
509
- - 2023-07-16
510
- - 2023-07-22
511
- - 2023-07-23
512
- - 2023-07-29
513
- - 2023-07-30
514
- - 2023-08-05
515
- - 2023-08-06
516
- - 2023-08-12
517
- - 2023-08-13
518
- - 2023-08-19
519
- - 2023-08-20
520
- - 2023-08-26
521
- - 2023-08-27
522
- - 2023-09-02
523
- - 2023-09-03
524
- - 2023-09-09
525
- - 2023-09-10
526
- - 2023-09-16
527
- - 2023-09-17
528
- - 2023-09-23
529
- - 2023-09-24
530
- - 2023-09-30
531
- - 2023-10-01
532
- - 2023-10-07
533
- - 2023-10-08
534
- - 2023-10-14
535
- - 2023-10-15
536
- - 2023-10-21
537
- - 2023-10-22
538
- - 2023-10-28
539
- - 2023-10-29
540
- - 2023-11-04
541
- - 2023-11-05
542
- - 2023-11-06
543
- - 2023-11-11
544
- - 2023-11-12
545
- - 2023-11-18
546
- - 2023-11-19
547
- - 2023-11-25
548
- - 2023-11-26
549
- - 2023-12-02
550
- - 2023-12-03
551
- - 2023-12-09
552
- - 2023-12-10
553
- - 2023-12-16
554
- - 2023-12-17
555
- - 2023-12-23
556
- - 2023-12-24
557
- - 2023-12-30
558
- - 2023-12-31
442
+ - 2023-01-02
443
+ - 2023-01-03
444
+ - 2023-01-04
445
+ - 2023-01-05
446
+ - 2023-01-06
447
+ - 2023-02-23
448
+ - 2023-02-24
449
+ - 2023-03-08
450
+ - 2023-05-01
451
+ - 2023-05-08
452
+ - 2023-05-09
453
+ - 2023-06-12
454
+ - 2023-11-06
455
+ :preholidays:
456
+ - 2023-02-22
457
+ - 2023-03-07
458
+ - 2023-11-03
459
+ 2024:
460
+ :holidays:
461
+ - 2024-01-01
462
+ - 2024-01-02
463
+ - 2024-01-03
464
+ - 2024-01-04
465
+ - 2024-01-05
466
+ - 2024-01-08
467
+ - 2024-02-23
468
+ - 2024-03-08
469
+ - 2024-04-29
470
+ - 2024-04-30
471
+ - 2024-05-01
472
+ - 2024-05-09
473
+ - 2024-05-10
474
+ - 2024-06-12
475
+ - 2024-11-04
476
+ - 2024-12-30
477
+ - 2024-12-31
478
+ :preholidays:
479
+ - 2024-02-22
480
+ - 2024-03-07
481
+ - 2024-05-08
482
+ - 2024-06-11
483
+ - 2024-11-02
484
+ 2025:
485
+ :holidays:
486
+ - 2025-01-01
487
+ - 2025-01-02
488
+ - 2025-01-03
489
+ - 2025-01-06
490
+ - 2025-01-07
491
+ - 2025-01-08
492
+ - 2025-05-01
493
+ - 2025-05-02
494
+ - 2025-05-08
495
+ - 2025-05-09
496
+ - 2025-06-12
497
+ - 2025-06-13
498
+ - 2025-11-03
499
+ - 2025-11-04
500
+ - 2025-12-31
559
501
  :preholidays:
560
- - 2023-02-22
561
- - 2023-03-07
562
- - 2023-11-03
502
+ - 2025-03-07
503
+ - 2025-04-30
504
+ - 2025-06-11
505
+ - 2025-11-01
@@ -3,32 +3,52 @@
3
3
  module RussianWorkdays
4
4
  class Collection
5
5
  include Enumerable
6
- AVAILABLE_WORK_HOURS_PER_WEEK = [24, 36, 40].freeze
6
+
7
+ WORK_HOURS_PER_DAY = {
8
+ 24 => 4.8,
9
+ 36 => 7.2,
10
+ 40 => 8.0
11
+ }.freeze
12
+
13
+ attr_reader :collection
7
14
 
8
15
  def initialize(collection)
9
- unless %w[Array Range].include? collection.class.name
10
- raise ArgumentError, "Must be a Array or Range object"
11
- end
12
- @collection = collection.to_a
16
+ raise ArgumentError, 'Must be a Array or Range object' unless [Array, Range].include?(collection.class)
17
+
18
+ collection.each { |date| raise MissingYearError, date.year unless DATES.key?(date.year) }
19
+
20
+ @collection = collection.map { |day| Day.new(day) }
13
21
  end
14
22
 
15
- def each
16
- @collection.each { |i| yield(i) }
23
+ def each(&block)
24
+ collection.each(&block)
17
25
  end
18
26
 
19
27
  %w[holiday preholiday work].each do |type|
20
28
  define_method "#{type}s" do
21
- @collection.select { |date| Day.new(date).send("#{type}?") }
29
+ collection.select { |day| day.send("#{type}?") }.map(&:to_date)
22
30
  end
23
31
  end
24
32
 
25
- def work_hours_count(work_hours_per_week = 40)
26
- unless AVAILABLE_WORK_HOURS_PER_WEEK.include?(work_hours_per_week)
27
- raise ArgumentError, "Unknown work hours count. Must be one of #{AVAILABLE_WORK_HOURS_PER_WEEK}"
33
+ def work_hours_count(work_hours_per_week = WORK_HOURS_PER_DAY.keys.last)
34
+ unless WORK_HOURS_PER_DAY.keys.include?(work_hours_per_week)
35
+ raise ArgumentError, "Unknown work hours count. Must be one of: #{WORK_HOURS_PER_DAY.keys.join(', ')}"
36
+ end
37
+
38
+ collection.sum { |day| calculate_work_hours(day, work_hours_per_week) }.ceil(1)
39
+ end
40
+
41
+ private
42
+
43
+ def calculate_work_hours(day, work_hours_per_week)
44
+ case day.type
45
+ when :work
46
+ WORK_HOURS_PER_DAY[work_hours_per_week]
47
+ when :preholiday
48
+ WORK_HOURS_PER_DAY[work_hours_per_week] - 1
49
+ else
50
+ 0
28
51
  end
29
- work_hours_per_day = (work_hours_per_week / 5.to_f)
30
- mapping = { work: work_hours_per_day, preholiday: work_hours_per_day - 1 }
31
- @collection.map { |i| mapping.fetch(Day.new(i).type, 0) }.sum.ceil(1)
32
52
  end
33
53
  end
34
54
  end
@@ -1,8 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "forwardable"
3
+ require 'forwardable'
4
4
 
5
- class CollectionPreset
6
- extend Forwardable
7
- def_delegators :@dates, :holidays, :preholidays, :works, :work_hours_count
5
+ module RussianWorkdays
6
+ class CollectionPreset
7
+ extend Forwardable
8
+ def_delegators :dates, :holidays, :preholidays, :works, :work_hours_count
9
+
10
+ private
11
+
12
+ def dates
13
+ Collection.new(range)
14
+ end
15
+ end
8
16
  end
@@ -1,23 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "yaml"
3
+ require_relative 'missing_year_error'
4
4
 
5
5
  module RussianWorkdays
6
- DATES = YAML.load_file(File.join(__dir__, "dates.yml")).freeze
7
-
8
6
  class Day
7
+ attr_reader :date
8
+
9
9
  def initialize(date)
10
+ raise ArgumentError, 'Must be a Date object' unless date.is_a?(::Date)
11
+ raise MissingYearError, date.year unless DATES.key?(date.year)
12
+
10
13
  @date = date
11
- raise ArgumentError, "Must be a Date object" unless @date.is_a?(::Date)
12
- raise ArgumentError, "Data missing for that year" unless DATES.key?(@date.year)
13
14
  end
14
15
 
15
16
  def holiday?
16
- !preholiday? && (weekend? || DATES[@date.year][:holidays].include?(@date))
17
+ return true if DATES[date.year][:holidays].include?(date)
18
+
19
+ !preholiday? && weekend?
17
20
  end
18
21
 
19
22
  def preholiday?
20
- DATES[@date.year][:preholidays].include?(@date)
23
+ DATES[date.year][:preholidays].include?(date)
21
24
  end
22
25
 
23
26
  def work?
@@ -27,13 +30,18 @@ module RussianWorkdays
27
30
  def type
28
31
  return :holiday if holiday?
29
32
  return :preholiday if preholiday?
30
- return :work if work?
33
+
34
+ :work if work?
35
+ end
36
+
37
+ def to_date
38
+ date
31
39
  end
32
40
 
33
41
  private
34
42
 
35
- def weekend?
36
- @date.sunday? || @date.saturday?
37
- end
43
+ def weekend?
44
+ date.sunday? || date.saturday?
45
+ end
38
46
  end
39
47
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RussianWorkdays
4
+ class MissingYearError < ArgumentError
5
+ attr_reader :year
6
+
7
+ def initialize(year)
8
+ super
9
+ @year = year
10
+ end
11
+
12
+ def to_s
13
+ "Data missing for that year: #{year}"
14
+ end
15
+ end
16
+ end
@@ -1,12 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "collection_preset"
3
+ require_relative 'missing_year_error'
4
+ require_relative 'collection_preset'
4
5
 
5
6
  module RussianWorkdays
6
7
  class Month < CollectionPreset
8
+ attr_reader :year, :month
9
+
7
10
  def initialize(year = Date.today.year, month = 1)
8
- raise ArgumentError, "Must be a number between 1 and 12" unless (1..12).include?(month)
9
- @dates = Collection.new(Date.new(year, month, 1)..Date.new(year, month, -1))
11
+ raise MissingYearError, year unless DATES.key?(year)
12
+ raise ArgumentError, 'Must be a number between 1 and 12' unless (1..12).include?(month)
13
+
14
+ @year = year
15
+ @month = month
16
+ end
17
+
18
+ private
19
+
20
+ def range
21
+ Date.new(year, month, 1)..Date.new(year, month, -1)
10
22
  end
11
23
  end
12
24
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RussianWorkdays
4
- VERSION = "2.6.0".freeze
4
+ VERSION = '2.7.0'
5
5
  end
@@ -1,11 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "collection_preset"
3
+ require_relative 'missing_year_error'
4
+ require_relative 'collection_preset'
4
5
 
5
6
  module RussianWorkdays
6
7
  class Year < CollectionPreset
8
+ attr_reader :year
9
+
7
10
  def initialize(year = Date.today.year)
8
- @dates = Collection.new(Date.new(year, 1, 1)..Date.new(year, 12, -1))
11
+ raise MissingYearError, year unless DATES.key?(year)
12
+
13
+ @year = year
14
+ end
15
+
16
+ private
17
+
18
+ def range
19
+ Date.new(year, 1, 1)..Date.new(year, 12, -1)
9
20
  end
10
21
  end
11
22
  end
@@ -1,6 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "russian_workdays/collection"
4
- require_relative "russian_workdays/day"
5
- require_relative "russian_workdays/month"
6
- require_relative "russian_workdays/year"
3
+ require 'yaml'
4
+ require 'date'
5
+ require_relative 'russian_workdays/collection'
6
+ require_relative 'russian_workdays/day'
7
+ require_relative 'russian_workdays/month'
8
+ require_relative 'russian_workdays/year'
9
+
10
+ module RussianWorkdays
11
+ YAML_FILE = File.read(File.join(__dir__, 'dates.yml')).freeze
12
+ DATES = YAML.safe_load(YAML_FILE, permitted_classes: [::Date, Symbol]).freeze
13
+
14
+ private_constant :YAML_FILE
15
+ end