timet 1.5.6 → 1.5.7

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: d5bbd4564baa142a2bf20160bdd2499f8df24ce2357eb03b8f1d05a26341fac5
4
- data.tar.gz: 2fe4c7eb71ab3ff20dc4691caf0bbfad9441e7cf3b1414caaf89ac7571ed4592
3
+ metadata.gz: 488c0136f2b11a62046a2f507b054d346a5def75dc3a32609ea51872bb411e6b
4
+ data.tar.gz: c28bbe32a4558ab6755e438ba7c5a53f879d6c036ae68706782b62d8ca26133c
5
5
  SHA512:
6
- metadata.gz: c7d324fe2b3f0aa476caa77cb44414206f6f7c723d47c78a8b9ffd5f5d1319d994520dee9c044d4cb145a2528abf00427c9198a122fefd3e0c85eeff3dcdb5ea
7
- data.tar.gz: d9a91d46ef64f42d03d2dcc8356338d4fb27f9f81a7bce5ebc100b008476083239b1b7dbdfe599187e3b2f545ea55211f87b347e5a86a7a864d6d39d3b20e5b3
6
+ metadata.gz: d1e74dfa8e0d6fdacf0fd8c458ade7667e2f2722376aea9307a5dab7b68b6a0a561b475432cf666564ba6664c18b6f80f94aed0bd88c3f6703ead36aa5d1cf84
7
+ data.tar.gz: 70608773c6f504e38637b7d4b2d71a852d7ed20c5679170c082d302748e1e3e6e4be2d1d4b909ce49e2ae45052dc3ac2cd02ba9a51106aba723211d3efa3c66a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## [1.5.7] - 2025-05-16
2
+
3
+ **Improvements:**
4
+
5
+ - Extracted collision checks in [`ValidationEditHelper`](lib/timet/validation_edit_helper.rb) into dedicated private methods (`check_collision_with_previous_item`, `check_collision_with_next_item`).
6
+ - Enhanced time collision validation in [`ValidationEditHelper`](lib/timet/validation_edit_helper.rb): renamed `validate_collision` to `validate_time_collisions`, added a `field` argument for specific checks ('start'/'end'), implemented distinct collision logic, and updated `perform_validation` to use the new method for both fields.
7
+ - Improved time validation logic structure by extracting `determine_start_base_date_time` and `determine_end_base_date_time` from `determine_base_date_time`, and introducing `validate_time_order` to centralize start/end time order validation.
8
+ - Centralized datetime creation by introducing `create_datetime_from_components` in [`TimeHelper`](lib/timet/time_helper.rb).
9
+ - Improved time validation and determination logic in [`TimeValidationHelper`](lib/timet/time_validation_helper.rb) and [`ValidationEditHelper`](lib/timet/validation_edit_helper.rb): refactored `determine_base_date_time` to use a `case` statement, extracted `validate_time_difference` for 24-hour difference validation, and removed the unused `time_str` parameter from `determine_and_create_datetime`.
10
+ - Centralized time validation logic to the new [`TimeValidationHelper`](lib/timet/time_validation_helper.rb) module, moving relevant methods from [`ValidationEditHelper`](lib/timet/validation_edit_edit_helper.rb).
11
+ - Refactored time validation and item data helpers by moving time validation logic to [`TimeUpdateHelper`](lib/timet/time_update_helper.rb) and item data fetching methods to [`ItemDataHelper`](lib/timet/item_data_helper.rb).
12
+ - Extracted time parsing, base date determination, datetime creation, end time adjustment, and validation logic into dedicated private methods in [`lib/timet/validation_edit_helper.rb`](lib/timet/validation_edit_helper.rb).
13
+ - Improved time validation and editing logic in [`ValidationEditHelper`](lib/timet/validation_edit_helper.rb): anchored end time date to start time date, handled end time on the next day, enforced < 24 hour duration, and preserved original time on empty input.
14
+ - Centralized utility methods into a new [`Timet::Utils`](lib/timet/utils.rb) module.
15
+ - Improved [`WeekInfo`](lib/timet/week_info.rb) initialization to accept a `Date` object and display string, and refactored its responsibilities for clarity and Reek compliance.
16
+ - Improved [`TimeBlockChart`](lib/timet/time_block_chart.rb) readability by replacing magic numbers with constants and ensuring chronological date order in `print_blocks`.
17
+ - Refactored [`TimeBlockChart`](lib/timet/time_block_chart.rb) for clarity and Reek compliance, moving separator printing responsibility and the `CHAR_MAPPING` constant to appropriate locations/helpers.
18
+ - Refactored database initialization logic in [`Timet::Application`](lib/timet/application.rb) for clarity and testability, encapsulating `initialize_database` within a `no_commands` block.
19
+ - Updated gem dependencies, including `aws-sdk-s3`, `icalendar`, `rubocop`, and `rubocop-rspec`.
20
+
21
+ **Bug Fixes:**
22
+
23
+ - Corrected `perform_validation` in [`ValidationEditHelper`](lib/timet/validation_edit_helper.rb) to accept and utilize the `item` object for correct context in collision checks.
24
+ - Modified `create_new_datetime` to derive date components from the parsed time component, allowing users to specify a full date and time for 'start' or 'end' fields.
25
+ - Fixed a bug in [`WeekInfo#format_and_print_date_info`](lib/timet/week_info.rb) where weekend days were incorrectly checked using "Sa" and "Su".
26
+ - Handled empty `@time_block` in [`TimeBlockChart#initialize`](lib/timet/time_block_chart.rb) to prevent errors.
27
+
1
28
  ## [1.5.6] - 2025-04-07
2
29
 
3
30
  **Improvements:**
@@ -49,21 +49,27 @@ module Timet
49
49
 
50
50
  BUCKET = 'timet'
51
51
 
52
+ def initialize(*args)
53
+ super
54
+ config = args[2] || {} # Third argument is the config hash
55
+ initialize_database(config)
56
+ end
57
+
58
+ # Initializes the database connection based on the provided options.
59
+ #
60
+ # This method determines how to initialize the database connection based on the options provided.
61
+ # It supports injecting a database instance for testing, using a fallback for RSpec, and initializing
62
+ # a production database based on valid command arguments.
63
+ #
64
+ # @param options [Hash] A hash of options that may include a :database key for injecting a database instance.
65
+ # @option options [Database] :database An instance of the Database class to be used directly.
66
+ # @option options [Hash] :current_command The current command being executed, used to validate production
67
+ # database initialization.
68
+ #
69
+ # @return [void] This method does not return a value; it initializes the `@db` instance variable.
70
+ #
71
+ # @raise [SystemExit] If invalid arguments are provided for production database initialization.
52
72
  no_commands do
53
- # Initializes the database connection based on the provided options.
54
- #
55
- # This method determines how to initialize the database connection based on the options provided.
56
- # It supports injecting a database instance for testing, using a fallback for RSpec, and initializing
57
- # a production database based on valid command arguments.
58
- #
59
- # @param options [Hash] A hash of options that may include a :database key for injecting a database instance.
60
- # @option options [Database] :database An instance of the Database class to be used directly.
61
- # @option options [Hash] :current_command The current command being executed, used to validate production
62
- # database initialization.
63
- #
64
- # @return [void] This method does not return a value; it initializes the `@db` instance variable.
65
- #
66
- # @raise [SystemExit] If invalid arguments are provided for production database initialization.
67
73
  def initialize_database(options)
68
74
  db_from_options = options[:database]
69
75
 
@@ -86,12 +92,6 @@ module Timet
86
92
  end
87
93
  end
88
94
 
89
- def initialize(*args)
90
- super
91
- options = args[2] || {} # Third argument is the options hash
92
- initialize_database(options)
93
- end
94
-
95
95
  desc "start [tag] --notes='' --pomodoro=[min]",
96
96
  'Start time tracking for a task labeled with the provided [tag], notes and "pomodoro time"
97
97
  in minutes (optional).
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timet
4
+ #
5
+ # The BlockCharHelper module provides a utility method for getting the block character
6
+ # based on a given value.
7
+ #
8
+ module BlockCharHelper
9
+ # Character mapping for different time ranges
10
+ CHAR_MAPPING = {
11
+ 0..120 => '_',
12
+ 121..450 => ' ',
13
+ 451..900 => '▂',
14
+ 901..1350 => '▃',
15
+ 1351..1800 => '▄',
16
+ 1801..2250 => '▅',
17
+ 2251..2700 => '▆',
18
+ 2701..3150 => '▇',
19
+ 3151..3600 => '█'
20
+ }.freeze
21
+
22
+ # Gets the block character for a given value
23
+ #
24
+ # @param [Integer, nil] value The value
25
+ # @return [String] The block character
26
+ def self.get_block_char(value)
27
+ return ' ' unless value
28
+
29
+ mapping = CHAR_MAPPING.find { |range, _| range.include?(value) }
30
+ mapping ? mapping.last : ' '
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timet
4
+ # Helper methods for fetching item data.
5
+ module ItemDataHelper
6
+ module_function
7
+
8
+ # Fetches the start time of a tracking item.
9
+ #
10
+ # @param item [Array] The tracking item.
11
+ #
12
+ # @return [Integer] The start time in epoch format.
13
+ #
14
+ # @example Fetch the start time of a tracking item
15
+ # fetch_item_start(item)
16
+ def fetch_item_start(item)
17
+ item[Timet::Application::FIELD_INDEX['start']]
18
+ end
19
+
20
+ # Fetches the end time of a tracking item.
21
+ #
22
+ # @param item [Array] The tracking item.
23
+ #
24
+ # @return [Integer] The end time in epoch format.
25
+ #
26
+ # @example Fetch the end time of a tracking item
27
+ # fetch_item_end(item)
28
+ def fetch_item_end(item)
29
+ item[Timet::Application::FIELD_INDEX['end']] || TimeHelper.current_timestamp
30
+ end
31
+
32
+ # Fetches the end time of the tracking item before the current one.
33
+ #
34
+ # @param db [Timet::Database] The database instance.
35
+ # @param id [Integer] The ID of the current tracking item.
36
+ # @param item_start [Integer] The start time of the current tracking item.
37
+ #
38
+ # @return [Integer] The end time of the previous tracking item in epoch format.
39
+ #
40
+ # @example Fetch the end time of the previous tracking item
41
+ # fetch_item_before_end(db, 1, 1633072800)
42
+ def fetch_item_before_end(db, id, item_start)
43
+ db.find_item(id - 1)&.dig(Timet::Application::FIELD_INDEX['end']) || item_start
44
+ end
45
+
46
+ # Fetches the start time of the tracking item after the current one.
47
+ #
48
+ # @param db [Timet::Database] The database instance.
49
+ # @param id [Integer] The ID of the current tracking item.
50
+ #
51
+ # @return [Integer] The start time of the next tracking item in epoch format.
52
+ #
53
+ # @example Fetch the start time of the next tracking item
54
+ # fetch_item_after_start(db, id)
55
+ def fetch_item_after_start(db, id)
56
+ db.find_item(id + 1)&.dig(Timet::Application::FIELD_INDEX['start']) || TimeHelper.current_timestamp
57
+ end
58
+ end
59
+ end
data/lib/timet/table.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  # require_relative 'color_codes'
4
4
  require 'timet/time_report_helper'
5
+ require_relative 'utils'
5
6
  module Timet
6
7
  # This class is responsible for formatting the output of the `timet` application.
7
8
  # It provides methods for formatting the table header, separators, and rows.
@@ -123,7 +124,7 @@ module Timet
123
124
 
124
125
  block_hour = TimeHelper.count_seconds_per_hour_block(start_time, end_time, tag)
125
126
  date_line = TimeHelper.timestamp_to_date(start_time)
126
- time_block[date_line] = add_hashes(time_block[date_line], block_hour)
127
+ time_block[date_line] = Timet::Utils.add_hashes(time_block[date_line], block_hour)
127
128
  time_block
128
129
  end
129
130
 
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'week_info'
4
+ require_relative 'block_char_helper'
5
+
3
6
  module Timet
4
7
  #
5
8
  # The TimeBlockChart class is responsible for generating and printing a visual representation
@@ -18,22 +21,18 @@ module Timet
18
21
  # @attr_reader [Integer] start_hour The starting hour of the time block
19
22
  # @attr_reader [Integer] end_hour The ending hour of the time block
20
23
  class TimeBlockChart
21
- # Character mapping for different time ranges
22
- CHAR_MAPPING = {
23
- 0..120 => '_',
24
- 121..450 => '▁',
25
- 451..900 => '▂',
26
- 901..1350 => '▃',
27
- 1351..1800 => '▄',
28
- 1801..2250 => '▅',
29
- 2251..2700 => '▆',
30
- 2701..3150 => '▇',
31
- 3151..3600 => '█'
32
- }.freeze
33
-
34
24
  # Separator character for the chart
35
25
  SEPARATOR_CHAR = '░'
36
26
 
27
+ # Width of the date/week string content (e.g., "02 2023-10-01 Fri")
28
+ DATE_WEEK_CONTENT_WIDTH = 17
29
+
30
+ # Width of the '┆- ' part after the date/week string
31
+ DATE_WEEK_BORDER_WIDTH = 3
32
+
33
+ # Width of the total hours column including the border
34
+ TOTAL_HOURS_COLUMN_WIDTH = 4
35
+
37
36
  # Initializes a new TimeBlockChart instance.
38
37
  #
39
38
  # This method sets up the time block chart by processing the time entries from the provided table
@@ -50,8 +49,13 @@ module Timet
50
49
  # @see Table#process_time_entries
51
50
  def initialize(table)
52
51
  @time_block = table.process_time_entries(display: false)
53
- @start_hour = @time_block.values.map(&:keys).flatten.uniq.min.to_i
54
- @end_hour = @time_block.values.map(&:keys).flatten.uniq.max.to_i
52
+ hours = @time_block.values.map(&:keys).flatten.uniq
53
+ if hours.empty?
54
+ @start_hour = @end_hour = 0
55
+ return
56
+ end
57
+ @start_hour = hours.min.to_i
58
+ @end_hour = hours.max.to_i
55
59
  end
56
60
 
57
61
  # Prints the time block chart.
@@ -59,13 +63,14 @@ module Timet
59
63
  # This method formats and prints the time block chart, including the header and the time blocks
60
64
  # for each entry. The chart is color-coded based on the provided color mapping for different tags.
61
65
  #
62
- # @param table [Hash] The time block data to be displayed in the chart.
63
66
  # @param colors [Hash] A mapping of tags to colors, used to color-code the time blocks.
64
67
  # @return [void] This method does not return a value; it performs side effects such as printing the chart.
65
68
  #
66
69
  # @example Print a time block chart
70
+ # # Assuming 'table' is an instance of Timet::Table
67
71
  # chart = TimeBlockChart.new(table)
68
- # chart.print_time_block_chart(table, colors)
72
+ # colors = { "work" => 0, "break" => 1 } # Example color mapping
73
+ # chart.print_time_block_chart(colors)
69
74
  #
70
75
  # @note
71
76
  # - The method first prints the header of the chart, which includes the time range.
@@ -74,9 +79,11 @@ module Timet
74
79
  #
75
80
  # @see #print_header
76
81
  # @see #print_blocks
77
- def print_time_block_chart(table, colors)
82
+ def print_time_block_chart(colors)
83
+ return puts 'No time-block data to display.' if @no_data
84
+
78
85
  print_header
79
- print_blocks(table, colors)
86
+ print_blocks(colors)
80
87
  end
81
88
 
82
89
  private
@@ -86,48 +93,64 @@ module Timet
86
93
  # @return [void]
87
94
  def print_header
88
95
  puts
89
- print ' ' * 19
90
- (@start_hour..@end_hour + 1).each { |hour| print format('%02d', hour).rjust(4) }
91
- puts
92
- puts '┌╴W ╴╴╴╴╴╴⏰╴╴╴╴╴╴┼'.gray + "#{'╴' * (@end_hour - @start_hour + 1) * 4}╴╴╴┼".gray
96
+ print_hours_row
97
+ # Dynamically build header using width constants
98
+ left = "┌#{'╴' * (DATE_WEEK_CONTENT_WIDTH - 11)}"
99
+ week = 'W'.center(DATE_WEEK_BORDER_WIDTH, '╴')
100
+ clock = '⏰'.center(DATE_WEEK_BORDER_WIDTH + 4, '╴')
101
+ hours_width = (@end_hour - @start_hour + 1) * 4
102
+ hours = '╴' * hours_width
103
+ right = "#{'╴' * (TOTAL_HOURS_COLUMN_WIDTH - 1)}┼"
104
+ header = left.gray + week.gray + clock.gray + '┼'.gray + hours.gray + right.gray
105
+ puts header
93
106
  end
94
107
 
95
- # Prints the time blocks for each date in the time block data.
108
+ # Prints the hours row in the header.
96
109
  #
97
- # This method iterates over the time block data, formats and prints the date information,
98
- # prints the time blocks for each date using the provided color mapping, and calculates
99
- # and prints the total hours for each day. It also prints a footer at the end.
110
+ # @return [void]
111
+ def print_hours_row
112
+ left_margin = DATE_WEEK_CONTENT_WIDTH + DATE_WEEK_BORDER_WIDTH - 1
113
+ print ' ' * left_margin
114
+ (@start_hour..@end_hour).each { |hour| print format('%02d', hour).rjust(4) }
115
+ puts
116
+ end
117
+
118
+ # Prints the main body of the time block chart, including date rows and corresponding time blocks.
100
119
  #
101
- # @param table [Hash] The time block data containing the time entries for each date.
102
- # @param colors [Hash] A mapping of tags to colors, used to color-code the time blocks.
103
- # @return [void] This method does not return a value; it performs side effects such as printing
104
- # the time blocks and related information.
120
+ # This method iterates over each date present in the `@time_block` instance variable,
121
+ # which is expected to be a hash mapping date strings to hourly time block data.
122
+ # For each date, it:
123
+ # 1. Displays week and date information using `WeekInfo`.
124
+ # 2. Prints the visual time blocks for the hours of the day using `#print_time_blocks`.
125
+ # 3. Calculates and prints the total hours logged for that day using `#calculate_and_print_hours`.
126
+ # After processing all dates, it prints a chart footer using `#print_footer`.
105
127
  #
106
- # @example Print time blocks
107
- # chart = TimeBlockChart.new(table)
108
- # chart.print_blocks(table, colors)
128
+ # @param colors [Hash] A mapping of tags to color indices. This is used by `#print_time_blocks`
129
+ # to color-code the visual time blocks. Example: `{ "work" => 0, "break" => 1 }`
130
+ # @return [void] This method does not return a value; it prints directly to the console.
109
131
  #
110
132
  # @note
111
- # - The method skips processing if the `table` parameter is `nil`.
112
- # - For each date in the time block data, it formats and prints the date and day of the week.
113
- # - It prints the time blocks using the provided color mapping to visually distinguish
114
- # between different tags.
115
- # - It calculates and prints the total hours for each day.
116
- # - A footer is printed at the end to provide a visual separation.
133
+ # - This is a private method, primarily called by `#print_time_block_chart`.
134
+ # - It returns early if `@time_block` is `nil`. If `@time_block` is an empty hash,
135
+ # no date-specific rows are printed, but the chart footer is still rendered.
136
+ # - Relies on `@start_hour` and `@end_hour` instance variables being correctly set
137
+ # during the `TimeBlockChart`'s initialization.
117
138
  #
118
- # @see #format_and_print_date_info
139
+ # @see WeekInfo#format_and_print_date_info
119
140
  # @see #print_time_blocks
120
141
  # @see #calculate_and_print_hours
121
142
  # @see #print_footer
122
- def print_blocks(table, colors)
123
- return unless table
143
+ def print_blocks(colors)
144
+ return unless @time_block
124
145
 
125
146
  weeks = []
126
- @time_block.each_key do |date_string|
127
- date = Date.parse(date_string)
128
- day = date.strftime('%a')[0..2]
147
+ @time_block.keys.sort.each do |date_string| # ISO-date strings sort naturally
148
+ date_object = Date.parse(date_string)
149
+ day = date_object.strftime('%a')[0..2]
129
150
 
130
- format_and_print_date_info(date_string, day, weeks)
151
+ week_info = WeekInfo.new(date_object, date_string, weeks)
152
+ print_inter_week_separator if week_info.needs_inter_week_separator?
153
+ week_info.format_and_print_date_info(day)
131
154
 
132
155
  time_block_initial = @time_block[date_string]
133
156
  print_time_blocks(time_block_initial, colors)
@@ -148,62 +171,6 @@ module Timet
148
171
  puts
149
172
  end
150
173
 
151
- # Formats and prints the date information
152
- #
153
- # @param [String] date_string The date string
154
- # @param [String] day The day of the week
155
- # @param [Array] weeks The list of weeks
156
- # @return [void]
157
- def format_and_print_date_info(date_string, day, weeks)
158
- weekend = date_string
159
- day = day.red if %w[Sa Su].include?(day)
160
- weekend = weekend.red if %w[Sa Su].include?(day)
161
-
162
- week = format_and_print_week(date_string, weeks)
163
-
164
- print '┆'.gray + "#{week} #{weekend} #{day}" + '┆- '.gray
165
- end
166
-
167
- # Formats and prints the week information
168
- #
169
- # @param [String] date_string The date string
170
- # @param [Array] weeks The list of weeks
171
- # @return [String] The formatted week string
172
- def format_and_print_week(date_string, weeks)
173
- week, current_index = determine_week(date_string, weeks)
174
- print_separator(week, current_index)
175
- week
176
- end
177
-
178
- # Determines the week for a given date
179
- #
180
- # @param [String] date_string The date string
181
- # @param [Array] weeks The list of weeks
182
- # @return [Array] The week string and current index
183
- def determine_week(date_string, weeks)
184
- weeks << Date.parse(date_string).cweek
185
- current_index = weeks.size - 1
186
- current_week = weeks[current_index]
187
- week = if current_week == weeks[current_index - 1] && current_index.positive?
188
- ' '
189
- else
190
- format('%02d', current_week).to_s.underline
191
- end
192
- [week, current_index]
193
- end
194
-
195
- # Prints the separator line
196
- #
197
- # @param [String] week The week string
198
- # @param [Integer] current_index The current index
199
- # @return [void]
200
- def print_separator(week, current_index)
201
- return unless week != ' ' && current_index.positive?
202
-
203
- sep = SEPARATOR_CHAR
204
- puts "┆#{sep * 17}┼#{sep * (@end_hour - @start_hour + 1) * 4}#{sep * 3}┼#{sep * 4}".gray
205
- end
206
-
207
174
  # Prints the footer of the chart
208
175
  #
209
176
  # @return [void]
@@ -234,7 +201,7 @@ module Timet
234
201
  formatted_hour = format('%02d', hour)
235
202
  hour_data = time_block_initial[formatted_hour]
236
203
  tag = hour_data&.last
237
- [tag, get_block_char(hour_data&.first)]
204
+ [tag, BlockCharHelper.get_block_char(hour_data&.first)]
238
205
  end
239
206
 
240
207
  # Prints the colored block character
@@ -250,14 +217,21 @@ module Timet
250
217
  print colored_block.rjust(4)
251
218
  end
252
219
 
253
- # Gets the block character for a given value
220
+ # Prints the separator line between different weeks in the chart.
254
221
  #
255
- # @param [Integer, nil] value The value
256
- # @return [String] The block character
257
- def get_block_char(value)
258
- return ' ' unless value
259
-
260
- CHAR_MAPPING.find { |range, _| range.include?(value) }&.last || ' '
222
+ # @return [void]
223
+ def print_inter_week_separator
224
+ sep = SEPARATOR_CHAR
225
+ line_parts = [
226
+ '┆',
227
+ sep * DATE_WEEK_CONTENT_WIDTH, # Date/Week column fill
228
+ '┼',
229
+ sep * (@end_hour - @start_hour + 1) * 4, # Hour blocks column fill
230
+ sep * DATE_WEEK_BORDER_WIDTH, # Additional fill for hour blocks column
231
+ '┼',
232
+ sep * TOTAL_HOURS_COLUMN_WIDTH # Total hours column fill
233
+ ]
234
+ puts line_parts.join.gray
261
235
  end
262
236
  end
263
237
  end
@@ -247,5 +247,22 @@ module Timet
247
247
  def self.beginning_of_day(time = Time.now)
248
248
  Time.new(time.year, time.month, time.day)
249
249
  end
250
+
251
+ # Creates a new datetime object.
252
+ #
253
+ # @param base_date_time [Time] The base date and time.
254
+ # @param parsed_time_component [Time] The parsed time component.
255
+ #
256
+ # @return [Time] The new datetime object.
257
+ def self.create_new_datetime(base_date_time, parsed_time_component)
258
+ Time.new(
259
+ base_date_time.year,
260
+ base_date_time.month,
261
+ base_date_time.day,
262
+ parsed_time_component.hour,
263
+ parsed_time_component.min,
264
+ parsed_time_component.sec
265
+ )
266
+ end
250
267
  end
251
268
  end
@@ -81,16 +81,16 @@ module Timet
81
81
  # - A time block chart is generated and printed using the `TimeBlockChart` class.
82
82
  # - The tag distribution is calculated and displayed based on the unique colors assigned to tags.
83
83
  #
84
- # @see #table
85
- # @see #print_time_block_chart
86
- # @see #tag_distribution
84
+ # @see Timet::Table#table For table generation.
85
+ # @see Timet::TimeBlockChart#print_time_block_chart For chart generation.
86
+ # @see #tag_distribution For tag statistics display.
87
87
  def display
88
88
  return puts 'No tracked time found for the specified filter.' if @items.empty?
89
89
 
90
90
  @table.table
91
91
  colors = @items.map { |x| x[3] }.uniq.each_with_index.to_h
92
92
  chart = TimeBlockChart.new(@table)
93
- chart.print_time_block_chart(@table, colors)
93
+ chart.print_time_block_chart(colors)
94
94
  tag_distribution(colors)
95
95
  end
96
96
 
@@ -150,7 +150,7 @@ module Timet
150
150
  # write_csv_rows(csv)
151
151
  def write_csv_rows(csv)
152
152
  items.each do |item|
153
- csv << format_item(item)
153
+ csv << Timet::Utils.format_item(item)
154
154
  end
155
155
  end
156
156
 
@@ -166,10 +166,10 @@ module Timet
166
166
  #
167
167
  # @note The method filters the items based on the specified date range and tag.
168
168
  def filter_items(filter, tag)
169
- if date_ranges.key?(filter)
170
- start_date, end_date = date_ranges[filter]
169
+ if Timet::Utils.date_ranges.key?(filter)
170
+ start_date, end_date = Timet::Utils.date_ranges[filter]
171
171
  filter_by_date_range(start_date, end_date, tag)
172
- elsif valid_date_format?(filter)
172
+ elsif Timet::Utils.valid_date_format?(filter)
173
173
  start_date, end_date = filter.split('..').map { |x| Date.parse(x) }
174
174
  filter_by_date_range(start_date, end_date, tag)
175
175
  else
@@ -226,7 +226,7 @@ module Timet
226
226
  return key if values.include?(filter)
227
227
  end
228
228
 
229
- return filter if filter && valid_date_format?(filter)
229
+ return filter if filter && Timet::Utils.valid_date_format?(filter)
230
230
 
231
231
  'today'
232
232
  end