Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,25 @@ Use `:array` style for structured data:
=> ["5 months", "1 week"]
```

#### `only`

Use the `only` option to accumulate all time into a single unit. Supported values are `:years`, `:months`, `:weeks`, and `:days`:

```ruby
>> timeago(Date.today.prev_day(365), only: :weeks)
=> "52 weeks ago"
>> timeago(Date.today.prev_day(365), only: :months)
=> "12 months ago"
>> timeago(Date.today.prev_day(100), only: :weeks)
=> "14 weeks ago"
>> timeago(Date.today.prev_day(500), only: :days)
=> "500 days ago"
>> timeago(Date.today.prev_day(365), only: :weeks, style: :short)
=> "52w ago"
>> timeago(Date.today.prev_day(365), only: :months, locale: :es)
=> "hace 12 meses"
```

## Localization

By default, `jekyll-timego` already provides translations for some languages. You can check the list [here](lib/locales/). However, you are able to provide your own translations, or even override the originals, easily.
Expand Down Expand Up @@ -169,6 +188,10 @@ il y a environ 2 années et 6 mois
2y ago
> timeago 2016-1-1 2018-1-1 -l es -s short
hace 2a y 1d
> timeago 2016-1-1 2018-1-1 --only weeks
104 weeks ago
> timeago 2016-1-1 2018-1-1 --only months -s short
24mo ago
```

### Console
Expand Down
4 changes: 4 additions & 0 deletions bin/timeago
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ parser = OptionParser.new do |opts|
opts.on("-s", "--style STYLE", "Uses the provided style (short, array)") do |style|
options[:style] = style
end

opts.on("-o", "--only UNIT", "Accumulates time in specified unit (years, months, weeks, days)") do |unit|
options[:only] = unit
end
end

begin
Expand Down
40 changes: 40 additions & 0 deletions lib/jekyll-timeago/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ module Core
# Available styles
STYLES = %w(default short array)

# Available "only" options
ONLY_OPTIONS = %w(years months weeks days)

def timeago(from, to = Date.today, options = {})
if to.is_a?(Hash)
options = to
Expand All @@ -30,6 +33,7 @@ def timeago(from, to = Date.today, options = {})
@depth = validate_depth(@options[:depth] || @options["depth"])
@style = validate_style(@options[:style] || @options["style"])
@threshold = validate_threshold(@options[:threshold] || @options["threshold"])
@only = validate_only(@options[:only] || @options["only"])

time_ago_to_now
end
Expand All @@ -53,6 +57,12 @@ def validate_style(style)
STYLES.include?(style) ? style : nil
end

def validate_only(only)
return nil if only.nil?
only = only.to_s
ONLY_OPTIONS.include?(only) ? only : nil
end

def time_ago_to_now
days_passed = (@to - @from).to_i

Expand Down Expand Up @@ -85,6 +95,9 @@ def translate_unit(unit, count)

# Builds time ranges with natural unit conversions: ['1 month', '5 days']
def build_time_ago_slots(days_passed)
# If "only" option is specified, calculate total time in that unit
return build_only_slots(days_passed) if @only

# Calculate components with natural unit conversions
components = calculate_natural_components(days_passed)

Expand All @@ -95,6 +108,33 @@ def build_time_ago_slots(days_passed)
selected.map { |unit, count| translate_unit(unit, count) }
end

# Build time slots when "only" option is specified
def build_only_slots(days_passed)
unit = @only.to_sym
count = calculate_total_in_unit(days_passed, unit)
[translate_unit(unit, count)]
end

# Calculate total time in specified unit
def calculate_total_in_unit(days_passed, unit)
case unit
when :days
days_passed
when :weeks
# Ensure minimum of 1 week if days_passed > 0
return 1 if days_passed > 0 && days_passed < 7
(days_passed / 7.0).round
when :months
# Ensure minimum of 1 month if days_passed > 0
return 1 if days_passed > 0 && days_passed < 30
(days_passed / 30.0).round
when :years
# Ensure minimum of 1 year if days_passed > 0
return 1 if days_passed > 0 && days_passed < 365
(days_passed / 365.0).round
end
end

def calculate_natural_components(days_passed)
years = days_passed / 365
remaining_days = days_passed % 365
Expand Down
49 changes: 46 additions & 3 deletions spec/jekyll-timeago_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,44 @@
expect(timeago(sample_date.prev_day(160), sample_date, style: :array)).to eq(['5 months', '1 week'])
expect(timeago(sample_date.prev_day(160), sample_date, style: :array, locale: :es)).to eq(['5 meses', '1 semana'])
end

it 'allows "only" option to accumulate time into single unit' do
# Test "only: :days"
expect(timeago(sample_date.prev_day(7), sample_date, only: :days)).to eq('7 days ago')
expect(timeago(sample_date.prev_day(7), sample_date, "only" => "days")).to eq('7 days ago')
expect(timeago(sample_date.prev_day(30), sample_date, only: :days)).to eq('30 days ago')

# Test "only: :weeks"
expect(timeago(sample_date.prev_day(7), sample_date, only: :weeks)).to eq('1 week ago')
expect(timeago(sample_date.prev_day(14), sample_date, only: :weeks)).to eq('2 weeks ago')
expect(timeago(sample_date.prev_day(30), sample_date, only: :weeks)).to eq('4 weeks ago')
expect(timeago(sample_date.prev_day(365), sample_date, only: :weeks)).to eq('52 weeks ago')

# Test "only: :months"
expect(timeago(sample_date.prev_day(30), sample_date, only: :months)).to eq('1 month ago')
expect(timeago(sample_date.prev_day(60), sample_date, only: :months)).to eq('2 months ago')
expect(timeago(sample_date.prev_day(365), sample_date, only: :months)).to eq('12 months ago')

# Test "only: :years"
expect(timeago(sample_date.prev_day(365), sample_date, only: :years)).to eq('1 year ago')
expect(timeago(sample_date.prev_day(730), sample_date, only: :years)).to eq('2 years ago')
expect(timeago(sample_date.prev_day(1000), sample_date, only: :years)).to eq('3 years ago')
end

it 'allows "only" option with different styles' do
# Test with short style
expect(timeago(sample_date.prev_day(365), sample_date, only: :weeks, style: :short)).to eq('52w ago')
expect(timeago(sample_date.prev_day(30), sample_date, only: :months, style: :short)).to eq('1mo ago')

# Test with array style
expect(timeago(sample_date.prev_day(365), sample_date, only: :weeks, style: :array)).to eq(['52 weeks'])
expect(timeago(sample_date.prev_day(30), sample_date, only: :months, style: :array)).to eq(['1 month'])
end

it 'allows "only" option with different locales' do
expect(timeago(sample_date.prev_day(30), sample_date, only: :weeks, locale: :es)).to eq('hace 4 semanas')
expect(timeago(sample_date.prev_day(365), sample_date, only: :months, locale: :fr)).to eq('il y a environ 12 mois')
end
end

context 'CLI' do
Expand Down Expand Up @@ -161,11 +199,16 @@
expect(`bin/timeago 2016-1-1 2018-1-1 -s short`).to match("2y and 1d ago")
expect(`bin/timeago 2016-1-1 2018-1-1 --style short`).to match("2y and 1d ago")
expect(`bin/timeago 2016-1-1 2016-2-1 -s short`).to match("1mo and 1d ago")
end

it 'with combined locale and style options' do
expect(`bin/timeago 2016-1-1 2018-1-1 -l fr -s short`).to match("il y a environ 2a")
expect(`bin/timeago 2016-1-1 2018-1-1 --locale ru --style short`).to match("2г и 1д назад")
end

it 'with only option' do
expect(`bin/timeago 2016-1-1 2018-1-1 --only weeks`).to match("104 weeks ago")
expect(`bin/timeago 2016-1-1 2018-1-1 -o months`).to match("24 months ago")
expect(`bin/timeago 2016-1-1 2016-2-1 --only days`).to match("31 days ago")
expect(`bin/timeago 2016-1-1 2018-1-1 -l fr --only months`).to match("il y a environ 24 mois")
expect(`bin/timeago 2016-1-1 2018-1-1 --only weeks -s short`).to match("104w ago")
end
end
end
Loading