Skip to content

Commit 90730fc

Browse files
methods lcm, gcd, gcdx, rem, sign, signbit for periods (issue #60)
1 parent 9a4bde2 commit 90730fc

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

src/CFTime.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,12 @@ import Dates:
5050
len,
5151
monthday,
5252
yearmonth,
53-
yearmonthday
53+
yearmonthday,
54+
value
5455

55-
import Base: +, -, *, /, div, isless, string, show, convert, reinterpret, ==,
56+
import Base: +, -, *, /, div, rem, lcm, gcd, gcdx, isless,
57+
abs, sign, signbit,
58+
string, show, convert, reinterpret, ==,
5659
promote_rule, floor, mod, round, typemax, typemin
5760

5861
include("constants.jl")

src/period.jl

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ _type(::Type{Period{T, Tfactor, Texponent}}) where {T, Tfactor, Texponent} = T
2424
_factor(::Type{Period{T, Tfactor, Texponent}}) where {T, Tfactor, Texponent} = unwrap(Tfactor)
2525
_exponent(::Type{Period{T, Tfactor, Texponent}}) where {T, Tfactor, Texponent} = unwrap(Texponent)
2626

27+
Dates.value(p::Period) = p.duration
28+
2729
function Base.zero(p::Period{T, Tfactor, Texponent}) where {T, Tfactor, Texponent}
2830
return Period{T, Tfactor, Texponent}(0)
2931
end
@@ -33,11 +35,11 @@ function Base.one(p::Period{T, Tfactor, Texponent}) where {T, Tfactor, Texponent
3335
end
3436

3537
function Base.abs(p::Period{T, Tfactor, Texponent}) where {T, Tfactor, Texponent}
36-
return Period{T, Tfactor, Texponent}(abs(Dates.value(p)))
38+
return Period{T, Tfactor, Texponent}(abs(value(p)))
3739
end
3840

39-
40-
Dates.value(p::Period) = p.duration
41+
Base.sign(x::Period) = sign(value(x))
42+
Base.signbit(x::Period) = signbit(value(x))
4143

4244
# helper functions for _timetuple
4345
@inline __tf(result, time) = result
@@ -228,16 +230,21 @@ end
228230

229231
# operations between two CFTime.Periods (or Dates.Period)
230232

231-
# operators returning a CFTime.Period
232-
for op in (:+, :-, :mod)
233+
# operators returning a CFTime.Period
234+
for op in (:+, :-, :mod, :lcm, :gcd, :rem)
233235
@eval begin
234236
function $op(p1::Period{T, Tfactor, Texponent}, p2::Period{T, Tfactor, Texponent}) where {T, Tfactor, Texponent}
235237
return Period{T, Tfactor, Texponent}($op(p1.duration, p2.duration))
236238
end
237239
end
238240
end
239241

240-
# divisions and boolean functions
242+
function Base.gcdx(a::T, b::T) where {T <: Period}
243+
(g, x, y) = gcdx(value(a), value(b))
244+
return (T(g), x, y)
245+
end
246+
247+
# operators not returning a CFTime.Period
241248
for op in (:/, :div, :(==), :isless)
242249
@eval begin
243250
function $op(p1::Period{T, Tfactor, Texponent}, p2::Period{T, Tfactor, Texponent}) where {T, Tfactor, Texponent}
@@ -247,7 +254,7 @@ for op in (:/, :div, :(==), :isless)
247254
end
248255

249256

250-
for op in (:+, :-, :/, :div, :mod, :(==), :isless)
257+
for op in (:+, :-, :/, :div, :mod, :(==), :isless, :lcm, :gcd, :gcdx, :rem)
251258
@eval begin
252259
$op(p1::Period, p2::Period) = $op(promote(p1, p2)...)
253260
$op(p1::Period, p2::Dates.Period) = $op(promote(p1, p2)...)
@@ -264,6 +271,7 @@ for op in (:*, :/, :div)
264271
end
265272
end
266273
end
274+
267275
*(v::Number, p::Period) = p * v
268276

269277
function -(p::Period{T, Tfactor, Texponent}) where {T, Tfactor, Texponent}

test/test_issues.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,26 @@ dt = DateTimeStandard(2021, 5, 7, 5, 4, 17, 9, 933)
219219

220220
dt = DateTimeStandard(2021, 5, 7, 5, 4, 17, 9, 933)
221221
@test_throws InexactError convert(DateTime, dt)
222+
223+
# issue #60
224+
225+
@test sign(CFTime.Picosecond(-7)) == -1
226+
@test signbit(CFTime.Picosecond(-7)) == true
227+
@test abs(CFTime.Picosecond(-7)) == abs(CFTime.Picosecond(7))
228+
229+
@test rem(CFTime.Picosecond(7), CFTime.Picosecond(3)) == CFTime.Picosecond(1)
230+
@test CFTime.Picosecond(7) % CFTime.Picosecond(3) == CFTime.Picosecond(1)
231+
232+
@test lcm(CFTime.Picosecond(3), CFTime.Picosecond(4)) == CFTime.Picosecond(12)
233+
@test lcm(CFTime.Picosecond(3), Dates.Microsecond(4)) == CFTime.Picosecond(12_000_000)
234+
@test lcm(CFTime.Picosecond(3), CFTime.Femtosecond(4)) == CFTime.Femtosecond(3000)
235+
236+
@test gcd(CFTime.Picosecond(12), CFTime.Picosecond(28)) == CFTime.Picosecond(4)
237+
238+
a, b = CFTime.Picosecond(12), CFTime.Picosecond(28)
239+
(d, u, v) = gcdx(a, b)
240+
@test u * a + v * b == d
241+
242+
a, b = CFTime.Picosecond(12), Dates.Microsecond(28)
243+
(d, u, v) = gcdx(a, b)
244+
@test u * a + v * b == d

0 commit comments

Comments
 (0)