@@ -1279,15 +1279,16 @@ defmodule Calendar.ISO do
12791279 def microseconds_to_iodata ( microsecond , 6 ) , do: zero_pad ( microsecond , 6 )
12801280
12811281 def microseconds_to_iodata ( microsecond , precision ) do
1282- num = div ( microsecond , div_factor ( precision ) )
1282+ num = div ( microsecond , scale_factor ( precision ) )
12831283 zero_pad ( num , precision )
12841284 end
12851285
1286- defp div_factor ( 1 ) , do: 100_000
1287- defp div_factor ( 2 ) , do: 10_000
1288- defp div_factor ( 3 ) , do: 1_000
1289- defp div_factor ( 4 ) , do: 100
1290- defp div_factor ( 5 ) , do: 10
1286+ defp scale_factor ( 1 ) , do: 100_000
1287+ defp scale_factor ( 2 ) , do: 10_000
1288+ defp scale_factor ( 3 ) , do: 1_000
1289+ defp scale_factor ( 4 ) , do: 100
1290+ defp scale_factor ( 5 ) , do: 10
1291+ defp scale_factor ( 6 ) , do: 1
12911292
12921293 defp time_to_iodata_format ( hour , minute , second , :extended ) do
12931294 [ zero_pad ( hour , 2 ) , ?: , zero_pad ( minute , 2 ) , ?: | zero_pad ( second , 2 ) ]
@@ -1988,16 +1989,17 @@ defmodule Calendar.ISO do
19881989 end
19891990
19901991 defp parse_microsecond ( "." <> rest ) do
1991- case parse_microsecond ( rest , 0 , "" ) do
1992- { "" , 0 , _ } ->
1992+ case parse_microsecond ( rest , 0 , [ ] ) do
1993+ { [ ] , 0 , _ } ->
19931994 :error
19941995
19951996 { microsecond , precision , rest } when precision in 1 .. 6 ->
1996- pad = String . duplicate ( "0" , 6 - byte_size ( microsecond ) )
1997- { { String . to_integer ( microsecond <> pad ) , precision } , rest }
1997+ bs = length ( microsecond )
1998+ scale = scale_factor ( bs )
1999+ { { :erlang . list_to_integer ( microsecond ) * scale , precision } , rest }
19982000
19992001 { microsecond , _precision , rest } ->
2000- { { String . to_integer ( binary_part ( microsecond , 0 , 6 ) ) , 6 } , rest }
2002+ { { :erlang . list_to_integer ( Enum . take ( microsecond , 6 ) ) , 6 } , rest }
20012003 end
20022004 end
20032005
@@ -2010,33 +2012,38 @@ defmodule Calendar.ISO do
20102012 end
20112013
20122014 defp parse_microsecond ( << head , tail :: binary >> , precision , acc ) when head in ?0 .. ?9 ,
2013- do: parse_microsecond ( tail , precision + 1 , << acc :: binary , head >> )
2015+ do: parse_microsecond ( tail , precision + 1 , [ head | acc ] )
20142016
2015- defp parse_microsecond ( rest , precision , acc ) , do: { acc , precision , rest }
2017+ defp parse_microsecond ( rest , precision , acc ) do
2018+ { :lists . reverse ( acc ) , precision , rest }
2019+ end
20162020
20172021 defp parse_offset ( "" ) , do: { nil , "" }
20182022 defp parse_offset ( "Z" ) , do: { 0 , "" }
20192023 defp parse_offset ( "-00:00" ) , do: :error
20202024
2021- defp parse_offset ( << ?+ , hour :: 2 - bytes , ?: , min :: 2 - bytes , rest :: binary >> ) ,
2022- do: parse_offset ( 1 , hour , min , rest )
2025+ defp parse_offset ( << ?+ , h1 , h2 , ?: , m1 , m2 , rest :: binary >> ) ,
2026+ do: parse_offset ( 1 , h1 , h2 , m1 , m2 , rest )
20232027
2024- defp parse_offset ( << ?- , hour :: 2 - bytes , ?: , min :: 2 - bytes , rest :: binary >> ) ,
2025- do: parse_offset ( - 1 , hour , min , rest )
2028+ defp parse_offset ( << ?- , h1 , h2 , ?: , m1 , m2 , rest :: binary >> ) ,
2029+ do: parse_offset ( - 1 , h1 , h2 , m1 , m2 , rest )
20262030
2027- defp parse_offset ( << ?+ , hour :: 2 - bytes , min :: 2 - bytes , rest :: binary >> ) ,
2028- do: parse_offset ( 1 , hour , min , rest )
2031+ defp parse_offset ( << ?+ , h1 , h2 , m1 , m2 , rest :: binary >> ) ,
2032+ do: parse_offset ( 1 , h1 , h2 , m1 , m2 , rest )
20292033
2030- defp parse_offset ( << ?- , hour :: 2 - bytes , min :: 2 - bytes , rest :: binary >> ) ,
2031- do: parse_offset ( - 1 , hour , min , rest )
2034+ defp parse_offset ( << ?- , h1 , h2 , m1 , m2 , rest :: binary >> ) ,
2035+ do: parse_offset ( - 1 , h1 , h2 , m1 , m2 , rest )
20322036
2033- defp parse_offset ( << ?+ , hour :: 2 - bytes , rest :: binary >> ) , do: parse_offset ( 1 , hour , "00" , rest )
2034- defp parse_offset ( << ?- , hour :: 2 - bytes , rest :: binary >> ) , do: parse_offset ( - 1 , hour , "00" , rest )
2037+ defp parse_offset ( << ?+ , h1 , h2 , rest :: binary >> ) , do: parse_offset ( 1 , h1 , h2 , ?0 , ?0 , rest )
2038+ defp parse_offset ( << ?- , h1 , h2 , rest :: binary >> ) , do: parse_offset ( - 1 , h1 , h2 , ?0 , ?0 , rest )
20352039 defp parse_offset ( _ ) , do: :error
20362040
2037- defp parse_offset ( sign , hour , min , rest ) do
2038- with { hour , "" } when hour < 24 <- Integer . parse ( hour ) ,
2039- { min , "" } when min < 60 <- Integer . parse ( min ) do
2041+ defp parse_offset ( sign , h1 , h2 , m1 , m2 , rest ) do
2042+ with true <- h1 in ?0 .. ?2 and h2 in ?0 .. ?9 ,
2043+ true <- m1 in ?0 .. ?5 and m2 in ?0 .. ?9 ,
2044+ hour = ( h1 - ?0 ) * 10 + h2 - ?0 ,
2045+ min = ( m1 - ?0 ) * 10 + m2 - ?0 ,
2046+ true <- hour < 24 do
20402047 { ( hour * 60 + min ) * 60 * sign , rest }
20412048 else
20422049 _ -> :error
0 commit comments