moments 0.0.2.alpha → 0.1.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 +5 -5
- data/.editorconfig +12 -0
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +42 -0
- data/.travis.yml +9 -7
- data/CHANGELOG.md +32 -0
- data/Gemfile +2 -0
- data/{LICENSE.txt → LICENSE.md} +0 -0
- data/README.md +17 -7
- data/Rakefile +2 -1
- data/lib/moments.rb +5 -2
- data/lib/moments/difference.rb +106 -34
- data/lib/moments/version.rb +13 -4
- data/moments.gemspec +17 -17
- data/spec/lib/moments/difference_spec.rb +730 -111
- data/spec/lib/moments_spec.rb +6 -22
- data/spec/spec_helper.rb +3 -11
- metadata +48 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2cfe9d93c489151bacb9c2c4b8de955a038db05cddf2a6d7edcb60c24532f8f3
|
4
|
+
data.tar.gz: be776d177f3878449fb8aabab929cbe84bb31965e428cef9c31bd72d3ce964a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b231e18ee429b37402e44571866f860a57e8b86957db6a18a75463fb6c3e325b7b7ec5dfe1da62d01259d78b749f3272bbd1c3078c268b8d1fbfcb70a3e55db
|
7
|
+
data.tar.gz: fab01ca909e9c5418ad1ca734a4709e11a81effe6bc283bf8cb5174f2d62548d29bd7a3bedc85be2c2b23902f6f614694bc45dc229184bb657c00bf0373dfdf4
|
data/.editorconfig
ADDED
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
Layout/LineLength:
|
2
|
+
Max: 100
|
3
|
+
Layout/MultilineOperationIndentation:
|
4
|
+
EnforcedStyle: indented
|
5
|
+
Layout/ArgumentAlignment:
|
6
|
+
EnforcedStyle: with_fixed_indentation
|
7
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
8
|
+
Enabled: true
|
9
|
+
Layout/SpaceAroundMethodCallOperator:
|
10
|
+
Enabled: true
|
11
|
+
|
12
|
+
Lint/DeprecatedOpenSSLConstant:
|
13
|
+
Enabled: true
|
14
|
+
Lint/MixedRegexpCaptureTypes:
|
15
|
+
Enabled: true
|
16
|
+
Lint/RaiseException:
|
17
|
+
Enabled: true
|
18
|
+
Lint/StructNewOverride:
|
19
|
+
Enabled: true
|
20
|
+
|
21
|
+
Style/ExponentialNotation:
|
22
|
+
Enabled: true
|
23
|
+
Style/HashEachMethods:
|
24
|
+
Enabled: true
|
25
|
+
Style/HashTransformKeys:
|
26
|
+
Enabled: true
|
27
|
+
Style/HashTransformValues:
|
28
|
+
Enabled: true
|
29
|
+
Style/RedundantFetchBlock:
|
30
|
+
Enabled: true
|
31
|
+
Style/RedundantRegexpCharacterClass:
|
32
|
+
Enabled: true
|
33
|
+
Style/RedundantRegexpEscape:
|
34
|
+
Enabled: true
|
35
|
+
Style/SlicingWithRange:
|
36
|
+
Enabled: true
|
37
|
+
|
38
|
+
Metrics/ParameterLists:
|
39
|
+
CountKeywordArgs: false
|
40
|
+
Metrics/BlockLength:
|
41
|
+
Exclude:
|
42
|
+
- spec/**/*
|
data/.travis.yml
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
sudo: false
|
2
|
+
cache: bundler
|
1
3
|
language: ruby
|
2
4
|
script: "bundle exec rspec"
|
5
|
+
before_install:
|
6
|
+
- gem update --system
|
7
|
+
- gem --version
|
8
|
+
- bundle install
|
3
9
|
rvm:
|
4
|
-
- 2.
|
5
|
-
-
|
6
|
-
-
|
7
|
-
- jruby-head
|
8
|
-
addons:
|
9
|
-
code_climate:
|
10
|
-
repo_token: 83c2e090282b16d91251419d1258e47c82d725056835a1daef193077cbb2a0e6
|
10
|
+
- 2.5.0
|
11
|
+
- 2.6.0
|
12
|
+
- 2.7.0
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## [v0.1.0](https://github.com/excpt/moments/tree/v0.1.0) (2020-08-18)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/excpt/moments/compare/v0.0.2.alpha...v0.1.0)
|
6
|
+
|
7
|
+
**Closed issues:**
|
8
|
+
|
9
|
+
- Replace Travis CI with another CI [\#3](https://github.com/excpt/moments/issues/3)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Fix `\#in\_\*` for times with miliseconds [\#6](https://github.com/excpt/moments/pull/6) ([AlexWayfer](https://github.com/AlexWayfer))
|
14
|
+
- Fix diffs with different timezones, `Date` diffs and `\#in\_years` [\#5](https://github.com/excpt/moments/pull/5) ([AlexWayfer](https://github.com/AlexWayfer))
|
15
|
+
- Add `\#in\_\*` methods, like `\#in\_seconds` [\#4](https://github.com/excpt/moments/pull/4) ([AlexWayfer](https://github.com/AlexWayfer))
|
16
|
+
- Many improvements [\#2](https://github.com/excpt/moments/pull/2) ([AlexWayfer](https://github.com/AlexWayfer))
|
17
|
+
|
18
|
+
## [v0.0.2.alpha](https://github.com/excpt/moments/tree/v0.0.2.alpha) (2014-11-14)
|
19
|
+
|
20
|
+
[Full Changelog](https://github.com/excpt/moments/compare/v0.0.1.alpha...v0.0.2.alpha)
|
21
|
+
|
22
|
+
## [v0.0.1.alpha](https://github.com/excpt/moments/tree/v0.0.1.alpha) (2014-05-26)
|
23
|
+
|
24
|
+
[Full Changelog](https://github.com/excpt/moments/compare/9b7612483150b52000ab4948d5c2217945230a1d...v0.0.1.alpha)
|
25
|
+
|
26
|
+
**Closed issues:**
|
27
|
+
|
28
|
+
- Test ticket from Code Climate [\#1](https://github.com/excpt/moments/issues/1)
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
data/Gemfile
CHANGED
data/{LICENSE.txt → LICENSE.md}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Moments [](http://badge.fury.io/rb/moments)
|
2
2
|
|
3
|
+
[](https://codeship.com/projects/53081)
|
3
4
|
[](https://travis-ci.org/excpt/moments)
|
4
5
|
[](https://codeclimate.com/github/excpt/moments)
|
5
6
|
[](https://codeclimate.com/github/excpt/moments)
|
@@ -11,29 +12,38 @@ Handles time differences and calculations.
|
|
11
12
|
|
12
13
|
Add this line to your application's Gemfile:
|
13
14
|
|
14
|
-
|
15
|
+
```ruby
|
16
|
+
gem 'moments'
|
17
|
+
```
|
15
18
|
|
16
19
|
And then execute:
|
17
20
|
|
18
|
-
|
21
|
+
```sh
|
22
|
+
$ bundle
|
23
|
+
```
|
19
24
|
|
20
25
|
Or install it yourself as:
|
21
26
|
|
22
|
-
|
27
|
+
```sh
|
28
|
+
$ gem install moments
|
29
|
+
```
|
23
30
|
|
24
31
|
## Usage
|
25
32
|
|
26
33
|
```ruby
|
27
34
|
require 'moments'
|
28
35
|
|
29
|
-
t1 = Time.
|
30
|
-
t2 = Time.
|
36
|
+
t1 = Time.new 2015, 1, 1, 0, 0, 0
|
37
|
+
t2 = Time.now # 2020, 8, 6, 19, 29, 6
|
31
38
|
|
32
|
-
# Important: For now t1 must be equal or less than t2
|
33
39
|
diff = Moments.difference t1, t2
|
34
40
|
|
35
41
|
puts diff.to_hash
|
36
|
-
#
|
42
|
+
# { years: 5, months: 7, days: 5, hours: 19, minutes: 29, seconds: 6 }
|
43
|
+
|
44
|
+
puts diff.in_months
|
45
|
+
# 67 (5 * 12 + 7)
|
46
|
+
# there are also methods for each component
|
37
47
|
```
|
38
48
|
|
39
49
|
## Contributing
|
data/Rakefile
CHANGED
data/lib/moments.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
|
2
|
-
require 'moments/difference'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
3
|
+
require_relative 'moments/version'
|
4
|
+
require_relative 'moments/difference'
|
5
|
+
|
6
|
+
# Entrypoint for the moments gem
|
4
7
|
module Moments
|
5
8
|
def self.difference(from, to)
|
6
9
|
Moments::Difference.new from, to
|
data/lib/moments/difference.rb
CHANGED
@@ -1,13 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
1
5
|
module Moments
|
6
|
+
# Calculates differences between two given Time instances.
|
2
7
|
class Difference
|
8
|
+
DATE_PARTS = {
|
9
|
+
years: :year,
|
10
|
+
months: :month,
|
11
|
+
days: :day
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
TIME_PARTS = {
|
15
|
+
hours: :hour,
|
16
|
+
minutes: :min,
|
17
|
+
seconds: :sec
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
private_constant :DATE_PARTS, :TIME_PARTS
|
21
|
+
|
22
|
+
# == Parameters:
|
23
|
+
# from::
|
24
|
+
# A instance of Time
|
25
|
+
# to::
|
26
|
+
# A instance of Time
|
3
27
|
def initialize(from, to)
|
4
|
-
@from = from
|
5
|
-
@to
|
28
|
+
@from = parse_argument from
|
29
|
+
@to = parse_argument to
|
6
30
|
|
7
|
-
|
8
|
-
message = "Start date (#{from}) must be less or equal than the end date (#{@to})."
|
9
|
-
raise ArgumentError.new(message)
|
10
|
-
end
|
31
|
+
@ordered_from, @ordered_to = [@from, @to].sort
|
11
32
|
|
12
33
|
precise_difference
|
13
34
|
end
|
@@ -28,15 +49,61 @@ module Moments
|
|
28
49
|
@from > @to
|
29
50
|
end
|
30
51
|
|
52
|
+
def in_seconds
|
53
|
+
@ordered_to.to_i - @ordered_from.to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
def in_minutes
|
57
|
+
in_seconds / 60
|
58
|
+
end
|
59
|
+
|
60
|
+
def in_hours
|
61
|
+
in_minutes / 60
|
62
|
+
end
|
63
|
+
|
64
|
+
def in_days
|
65
|
+
in_hours / 24
|
66
|
+
end
|
67
|
+
|
68
|
+
def in_months
|
69
|
+
months_diff = @ordered_to.month - @ordered_from.month
|
70
|
+
months_diff -= 1 if months_diff.positive? && @ordered_to.mday < @ordered_from.mday
|
71
|
+
|
72
|
+
(@ordered_to.year - @ordered_from.year) * 12 + months_diff
|
73
|
+
end
|
74
|
+
|
75
|
+
def in_years
|
76
|
+
years_diff = @ordered_to.year - @ordered_from.year
|
77
|
+
|
78
|
+
return years_diff unless years_diff.positive?
|
79
|
+
return years_diff if @ordered_to.month > @ordered_from.month
|
80
|
+
|
81
|
+
if (@ordered_to.month < @ordered_from.month) || (@ordered_to.mday < @ordered_from.mday)
|
82
|
+
years_diff -= 1
|
83
|
+
end
|
84
|
+
|
85
|
+
years_diff
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
TIME_CLASSES = [Time, DateTime].freeze
|
91
|
+
|
92
|
+
private_constant :TIME_CLASSES
|
93
|
+
|
94
|
+
def parse_argument(value)
|
95
|
+
case value
|
96
|
+
when *TIME_CLASSES
|
97
|
+
value.to_time.getutc
|
98
|
+
when Date
|
99
|
+
value
|
100
|
+
else
|
101
|
+
raise ArgumentError, 'Unsupported format'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
31
105
|
def precise_difference
|
32
|
-
@diff =
|
33
|
-
seconds: @to.sec - @from.sec,
|
34
|
-
minutes: @to.min - @from.min,
|
35
|
-
hours: @to.hour - @from.hour,
|
36
|
-
days: @to.day - @from.day,
|
37
|
-
months: @to.month - @from.month,
|
38
|
-
years: @to.year - @from.year,
|
39
|
-
}
|
106
|
+
@diff = calculate_diff
|
40
107
|
|
41
108
|
calculate :seconds, :minutes
|
42
109
|
calculate :minutes, :hours
|
@@ -47,37 +114,42 @@ module Moments
|
|
47
114
|
@diff
|
48
115
|
end
|
49
116
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if @diff[attr] < 0
|
54
|
-
@diff[attr] += increment
|
55
|
-
@diff[subtr] -= 1
|
117
|
+
def calculate_diff
|
118
|
+
are_time_parts = [@from, @to].all? do |value|
|
119
|
+
TIME_CLASSES.any? { |time_class| value.is_a?(time_class) }
|
56
120
|
end
|
121
|
+
|
122
|
+
(are_time_parts ? DATE_PARTS.merge(TIME_PARTS) : DATE_PARTS)
|
123
|
+
.transform_values do |method_name|
|
124
|
+
@ordered_to.public_send(method_name) - @ordered_from.public_send(method_name)
|
125
|
+
end
|
57
126
|
end
|
58
127
|
|
59
|
-
|
128
|
+
def calculate(attribute, difference, stepping = 60)
|
129
|
+
return unless @diff.key?(attribute) && @diff.key?(difference)
|
60
130
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@diff[:months] -= 1
|
66
|
-
end
|
131
|
+
return if @diff[attribute] >= 0
|
132
|
+
|
133
|
+
@diff[attribute] += stepping
|
134
|
+
@diff[difference] -= 1
|
67
135
|
end
|
68
136
|
|
69
|
-
|
137
|
+
def calculate_days
|
138
|
+
return if @diff[:days] >= 0
|
139
|
+
|
140
|
+
previous_month_days = (Time.new(@to.year, @to.month, 1) - 1).day
|
141
|
+
@diff[:days] = precise_previous_month_days(
|
142
|
+
@diff[:days], previous_month_days, @from.day
|
143
|
+
)
|
144
|
+
@diff[:months] -= 1
|
145
|
+
end
|
70
146
|
|
71
147
|
def precise_previous_month_days(days, previous, from)
|
72
148
|
if previous < from
|
73
|
-
|
149
|
+
previous + days + (from - previous)
|
74
150
|
else
|
75
|
-
|
151
|
+
previous + days
|
76
152
|
end
|
77
|
-
|
78
|
-
days
|
79
153
|
end
|
80
|
-
|
81
|
-
private :precise_previous_month_days
|
82
154
|
end
|
83
155
|
end
|
data/lib/moments/version.rb
CHANGED
@@ -1,14 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Moments::Version module
|
1
4
|
module Moments
|
2
5
|
def self.gem_version
|
3
6
|
Gem::Version.new VERSION::STRING
|
4
7
|
end
|
5
8
|
|
9
|
+
# Moments version builder module
|
6
10
|
module VERSION
|
11
|
+
# major version
|
7
12
|
MAJOR = 0
|
8
|
-
|
9
|
-
|
10
|
-
|
13
|
+
# minor version
|
14
|
+
MINOR = 1
|
15
|
+
# patch version
|
16
|
+
PATCH = 0
|
17
|
+
# alpha, beta, etc. tag
|
18
|
+
PRE = nil
|
11
19
|
|
12
|
-
|
20
|
+
# Build version string
|
21
|
+
STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
|
13
22
|
end
|
14
23
|
end
|
data/moments.gemspec
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
require 'moments/version'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/moments/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
6
|
+
spec.name = 'moments'
|
7
|
+
spec.version = Moments.gem_version
|
8
|
+
spec.authors = ['Tim Rudat']
|
9
|
+
spec.email = ['timrudat@gmail.com']
|
10
|
+
spec.summary = 'Handles time differences.'
|
11
|
+
spec.description = ''
|
12
|
+
spec.homepage = 'https://github.com/excpt/moments'
|
13
|
+
spec.license = 'MIT'
|
15
14
|
|
16
15
|
spec.files = `git ls-files -z`.split("\x0")
|
17
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
18
|
+
spec.require_paths = ['lib']
|
20
19
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
20
|
+
spec.add_development_dependency 'bundler', '>= 1', '< 3'
|
21
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
|
22
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
24
|
+
spec.add_development_dependency 'rubocop', '~> 0.86.0'
|
25
25
|
end
|