@@ -183,9 +183,9 @@ defmodule Duration do
183
183
184
184
## Examples
185
185
186
- iex> Duration.add(% Duration{ week: 2, day: 1}, % Duration{ day: 2} )
186
+ iex> Duration.add(Duration.new!( week: 2, day: 1), Duration.new!( day: 2) )
187
187
%Duration{week: 2, day: 3}
188
- iex> Duration.add(% Duration{ microsecond: {400, 3}}, % Duration{ microsecond: {600, 6}} )
188
+ iex> Duration.add(Duration.new!( microsecond: {400, 3}), Duration.new!( microsecond: {600, 6}) )
189
189
%Duration{microsecond: {1000, 6}}
190
190
191
191
"""
@@ -213,9 +213,9 @@ defmodule Duration do
213
213
214
214
## Examples
215
215
216
- iex> Duration.subtract(% Duration{ week: 2, day: 1}, % Duration{ day: 2} )
216
+ iex> Duration.subtract(Duration.new!( week: 2, day: 1), Duration.new!( day: 2) )
217
217
%Duration{week: 2, day: -1}
218
- iex> Duration.subtract(% Duration{ microsecond: {400, 6}}, % Duration{ microsecond: {600, 3}} )
218
+ iex> Duration.subtract(Duration.new!( microsecond: {400, 6}), Duration.new!( microsecond: {600, 3}) )
219
219
%Duration{microsecond: {-200, 6}}
220
220
221
221
"""
@@ -241,9 +241,9 @@ defmodule Duration do
241
241
242
242
## Examples
243
243
244
- iex> Duration.multiply(% Duration{ day: 1, minute: 15, second: -10} , 3)
244
+ iex> Duration.multiply(Duration.new!( day: 1, minute: 15, second: -10) , 3)
245
245
%Duration{day: 3, minute: 45, second: -30}
246
- iex> Duration.multiply(% Duration{ microsecond: {200, 4}} , 3)
246
+ iex> Duration.multiply(Duration.new!( microsecond: {200, 4}) , 3)
247
247
%Duration{microsecond: {600, 4}}
248
248
249
249
"""
@@ -266,9 +266,9 @@ defmodule Duration do
266
266
267
267
## Examples
268
268
269
- iex> Duration.negate(% Duration{ day: 1, minute: 15, second: -10} )
269
+ iex> Duration.negate(Duration.new!( day: 1, minute: 15, second: -10) )
270
270
%Duration{day: -1, minute: -15, second: 10}
271
- iex> Duration.negate(% Duration{ microsecond: {500000, 4}} )
271
+ iex> Duration.negate(Duration.new!( microsecond: {500000, 4}) )
272
272
%Duration{microsecond: {-500000, 4}}
273
273
274
274
"""
@@ -353,78 +353,60 @@ defmodule Duration do
353
353
354
354
## Examples
355
355
356
- iex> Duration.to_iso8601(% Duration{ year: 3} )
356
+ iex> Duration.to_iso8601(Duration.new!( year: 3) )
357
357
"P3Y"
358
- iex> Duration.to_iso8601(% Duration{ day: 40, hour: 12, minute: 42, second: 12} )
358
+ iex> Duration.to_iso8601(Duration.new!( day: 40, hour: 12, minute: 42, second: 12) )
359
359
"P40DT12H42M12S"
360
- iex> Duration.to_iso8601(% Duration{ second: 30} )
360
+ iex> Duration.to_iso8601(Duration.new!( second: 30) )
361
361
"PT30S"
362
362
363
- iex> Duration.to_iso8601(% Duration{} )
363
+ iex> Duration.to_iso8601(Duration.new!([]) )
364
364
"PT0S"
365
365
366
- iex> Duration.to_iso8601(% Duration{ second: 1, microsecond: {2_200, 3}} )
366
+ iex> Duration.to_iso8601(Duration.new!( second: 1, microsecond: {2_200, 3}) )
367
367
"PT1.002S"
368
- iex> Duration.to_iso8601(% Duration{ second: 1, microsecond: {-1_200_000, 4}} )
368
+ iex> Duration.to_iso8601(Duration.new!( second: 1, microsecond: {-1_200_000, 4}) )
369
369
"PT-0.2000S"
370
370
"""
371
371
372
372
@ spec to_iso8601 ( t ) :: String . t ( )
373
- def to_iso8601 ( duration )
374
-
375
- def to_iso8601 ( % Duration {
376
- year: 0 ,
377
- month: 0 ,
378
- week: 0 ,
379
- day: 0 ,
380
- hour: 0 ,
381
- minute: 0 ,
382
- second: 0 ,
383
- microsecond: { 0 , _ }
384
- } ) do
385
- "PT0S"
373
+ def to_iso8601 ( % Duration { } = duration ) do
374
+ case { to_iso8601_duration_date ( duration ) , to_iso8601_duration_time ( duration ) } do
375
+ { [ ] , [ ] } -> "PT0S"
376
+ { date , time } -> IO . iodata_to_binary ( [ ?P , date , time ] )
377
+ end
386
378
end
387
379
388
- def to_iso8601 ( % Duration { } = d ) do
389
- IO . iodata_to_binary ( [ ?P , to_iso8601_duration_date ( d ) , to_iso8601_duration_time ( d ) ] )
380
+ defp to_iso8601_duration_date ( % { year: 0 , month: 0 , week: 0 , day: 0 } ) do
381
+ [ ]
390
382
end
391
383
392
- defp to_iso8601_duration_date ( d ) do
393
- [
394
- if ( d . year == 0 , do: [ ] , else: [ Integer . to_string ( d . year ) , ?Y ] ) ,
395
- if ( d . month == 0 , do: [ ] , else: [ Integer . to_string ( d . month ) , ?M ] ) ,
396
- if ( d . week == 0 , do: [ ] , else: [ Integer . to_string ( d . week ) , ?W ] ) ,
397
- if ( d . day == 0 , do: [ ] , else: [ Integer . to_string ( d . day ) , ?D ] )
398
- ]
384
+ defp to_iso8601_duration_date ( % { year: year , month: month , week: week , day: day } ) do
385
+ [ pair ( year , ?Y ) , pair ( month , ?M ) , pair ( week , ?W ) , pair ( day , ?D ) ]
399
386
end
400
387
401
- defp to_iso8601_duration_time ( % Duration { hour: 0 , minute: 0 , second: 0 , microsecond: { 0 , _ } } ) do
388
+ defp to_iso8601_duration_time ( % { hour: 0 , minute: 0 , second: 0 , microsecond: { 0 , _ } } ) do
402
389
[ ]
403
390
end
404
391
405
- defp to_iso8601_duration_time ( d ) do
406
- [
407
- ?T ,
408
- if ( d . hour == 0 , do: [ ] , else: [ Integer . to_string ( d . hour ) , ?H ] ) ,
409
- if ( d . minute == 0 , do: [ ] , else: [ Integer . to_string ( d . minute ) , ?M ] ) ,
410
- second_component ( d )
411
- ]
392
+ defp to_iso8601_duration_time ( % { hour: hour , minute: minute } = d ) do
393
+ [ ?T , pair ( hour , ?H ) , pair ( minute , ?M ) , second_component ( d ) ]
412
394
end
413
395
414
- defp second_component ( % Duration { second: 0 , microsecond: { 0 , _ } } ) do
396
+ defp second_component ( % { second: 0 , microsecond: { 0 , _ } } ) do
415
397
[ ]
416
398
end
417
399
418
- defp second_component ( % Duration { second: 0 , microsecond: { _ , 0 } } ) do
400
+ defp second_component ( % { second: 0 , microsecond: { _ , 0 } } ) do
419
401
~c" 0S"
420
402
end
421
403
422
- defp second_component ( % Duration { microsecond: { _ , 0 } } = d ) do
423
- [ Integer . to_string ( d . second ) , ?S ]
404
+ defp second_component ( % { second: second , microsecond: { _ , 0 } } ) do
405
+ [ Integer . to_string ( second ) , ?S ]
424
406
end
425
407
426
- defp second_component ( % Duration { microsecond: { ms , p } } = d ) do
427
- total_ms = d . second * @ microseconds_per_second + ms
408
+ defp second_component ( % { second: second , microsecond: { ms , p } } ) do
409
+ total_ms = second * @ microseconds_per_second + ms
428
410
second = total_ms |> div ( @ microseconds_per_second ) |> abs ( )
429
411
ms = total_ms |> rem ( @ microseconds_per_second ) |> abs ( )
430
412
sign = if total_ms < 0 , do: ?- , else: [ ]
@@ -437,4 +419,8 @@ defmodule Duration do
437
419
?S
438
420
]
439
421
end
422
+
423
+ @ compile { :inline , pair: 2 }
424
+ defp pair ( 0 , _key ) , do: [ ]
425
+ defp pair ( num , key ) , do: [ Integer . to_string ( num ) , key ]
440
426
end
0 commit comments