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
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
language: ruby
rvm:
- 2.6
- 2.7
matrix:
fast_finish: true
before_install:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

* [TT-6441] Due to TimeDifference being unmaintained bring it into the timely library

## 0.6.0

* [TT-6402] Require date group weekdays bit field to be not null/nil
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails6.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ source 'https://rubygems.org'
gemspec path: '../'

group :development, :test do
gem 'activerecord', '~> 6.0.0.rc1'
gem 'activerecord', '~> 6.0'
end
1 change: 1 addition & 0 deletions lib/timely/rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
require 'timely/rails/date'
require 'timely/rails/period'
require 'timely/rails/time'
require 'timely/rails/time_difference'
100 changes: 100 additions & 0 deletions lib/timely/rails/time_difference.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# frozen_string_literal: true

require 'rubygems'
require 'active_support/all'

module Timely
class TimeDifference
private_class_method :new

TIME_COMPONENTS = %i[years months weeks days hours minutes seconds].freeze

def self.between(start_time, end_time)
new(start_time, end_time)
end

def in_years
in_component(:years)
end

def in_months
(@time_diff / (1.day * 30.42)).round(2)
end

def in_weeks
in_component(:weeks)
end

def in_days
in_component(:days)
end

def in_hours
in_component(:hours)
end

def in_minutes
in_component(:minutes)
end

def in_seconds
@time_diff
end

def in_each_component
Hash[TIME_COMPONENTS.map do |time_component|
[time_component, public_send("in_#{time_component}")]
end]
end

def in_general
remaining = @time_diff
Hash[TIME_COMPONENTS.map do |time_component|
if remaining > 0
rounded_time_component = (remaining / 1.send(time_component).seconds).round(2).floor
remaining -= rounded_time_component.send(time_component)
[time_component, rounded_time_component]
else
[time_component, 0]
end
end]
end

def humanize
diff_parts = []
in_general.each do |part, quantity|
next if quantity <= 0

part = part.to_s.humanize

part = part.singularize if quantity <= 1

diff_parts << "#{quantity} #{part}"
end

last_part = diff_parts.pop
if diff_parts.empty?
last_part
else
[diff_parts.join(', '), last_part].join(' and ')
end
end

private

def initialize(start_time, end_time)
start_time = time_in_seconds(start_time)
end_time = time_in_seconds(end_time)

@time_diff = (end_time - start_time).abs
end

def time_in_seconds(time)
time.to_time.to_f
end

def in_component(component)
(@time_diff / 1.send(component)).round(2)
end
end
end
185 changes: 185 additions & 0 deletions spec/rails/time_difference_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# frozen_string_literal: true

require 'spec_helper'

describe Timely::TimeDifference do
def self.with_each_class(&block)
classes = [Time, Date, DateTime]

classes.each do |clazz|
context "with a #{clazz.name} class" do
instance_exec clazz, &block
end
end
end

describe '.between' do
with_each_class do |clazz|
it 'returns a new TimeDifference instance in each component' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time)).to be_a(Timely::TimeDifference)
end
end
end

describe '#in_each_component' do
with_each_class do |clazz|
it 'returns time difference in each component' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_each_component).to eql(years: 0.91, months: 10.98, weeks: 47.71, days: 334.0, hours: 8016.0, minutes: 480_960.0, seconds: 28_857_600.0)
end
end
end

describe '#in_general' do
with_each_class do |clazz|
it 'returns time difference in general that matches the total seconds' do
start_time = clazz.new(2009, 11)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_general).to eql(years: 1, months: 2, weeks: 0, days: 0, hours: 0, minutes: 0, seconds: 0)
end
end
end

describe '#humanize' do
with_each_class do |clazz|
it 'returns a string representing the time difference from in_general' do
start_time = clazz.new(2009, 11)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).humanize).to eql('1 Year and 2 Months')
end
end
end

describe '#in_years' do
with_each_class do |clazz|
it 'returns time difference in years based on Wolfram Alpha' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_years).to eql(0.91)
end

it 'returns an absolute difference' do
start_time = clazz.new(2011, 12)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_years).to eql(0.91)
end
end
end

describe '#in_months' do
with_each_class do |clazz|
it 'returns time difference in months based on Wolfram Alpha' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_months).to eql(10.98)
end

it 'returns an absolute difference' do
start_time = clazz.new(2011, 12)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_months).to eql(10.98)
end
end
end

describe '#in_weeks' do
with_each_class do |clazz|
it 'returns time difference in weeks based on Wolfram Alpha' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_weeks).to eql(47.71)
end

it 'returns an absolute difference' do
start_time = clazz.new(2011, 12)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_weeks).to eql(47.71)
end
end
end

describe '#in_days' do
with_each_class do |clazz|
it 'returns time difference in weeks based on Wolfram Alpha' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_days).to eql(334.0)
end

it 'returns an absolute difference' do
start_time = clazz.new(2011, 12)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_days).to eql(334.0)
end
end
end

describe '#in_hours' do
with_each_class do |clazz|
it 'returns time difference in hours based on Wolfram Alpha' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_hours).to eql(8016.0)
end

it 'returns an absolute difference' do
start_time = clazz.new(2011, 12)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_hours).to eql(8016.0)
end
end
end

describe '#in_minutes' do
with_each_class do |clazz|
it 'returns time difference in minutes based on Wolfram Alpha' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_minutes).to eql(480_960.0)
end

it 'returns an absolute difference' do
start_time = clazz.new(2011, 12)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_minutes).to eql(480_960.0)
end
end
end

describe '#in_seconds' do
with_each_class do |clazz|
it 'returns time difference in seconds based on Wolfram Alpha' do
start_time = clazz.new(2011, 1)
end_time = clazz.new(2011, 12)

expect(Timely::TimeDifference.between(start_time, end_time).in_seconds).to eql(28_857_600.0)
end

it 'returns an absolute difference' do
start_time = clazz.new(2011, 12)
end_time = clazz.new(2011, 1)

expect(Timely::TimeDifference.between(start_time, end_time).in_seconds).to eql(28_857_600.0)
end
end
end
end
2 changes: 1 addition & 1 deletion spec/support/coverage_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
require 'simplecov-rcov'
require 'coveralls'
require 'coverage/kit'
Coverage::Kit.setup(minimum_coverage: 70.15)
Coverage::Kit.setup(minimum_coverage: 72.0)