@@ -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,13 @@ 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
1995- { 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 }
1998-
1999- { microsecond , _precision , rest } ->
2000- { { String . to_integer ( binary_part ( microsecond , 0 , 6 ) ) , 6 } , rest }
1996+ { microsecond , precision , rest } ->
1997+ scale = scale_factor ( precision )
1998+ { { :erlang . list_to_integer ( microsecond ) * scale , precision } , rest }
20011999 end
20022000 end
20032001
@@ -2009,34 +2007,42 @@ defmodule Calendar.ISO do
20092007 { { 0 , 0 } , rest }
20102008 end
20112009
2010+ defp parse_microsecond ( << head , tail :: binary >> , 6 , acc ) when head in ?0 .. ?9 ,
2011+ do: parse_microsecond ( tail , 6 , acc )
2012+
20122013 defp parse_microsecond ( << head , tail :: binary >> , precision , acc ) when head in ?0 .. ?9 ,
2013- do: parse_microsecond ( tail , precision + 1 , << acc :: binary , head >> )
2014+ do: parse_microsecond ( tail , precision + 1 , [ head | acc ] )
20142015
2015- defp parse_microsecond ( rest , precision , acc ) , do: { acc , precision , rest }
2016+ defp parse_microsecond ( rest , precision , acc ) do
2017+ { :lists . reverse ( acc ) , precision , rest }
2018+ end
20162019
20172020 defp parse_offset ( "" ) , do: { nil , "" }
20182021 defp parse_offset ( "Z" ) , do: { 0 , "" }
20192022 defp parse_offset ( "-00:00" ) , do: :error
20202023
2021- defp parse_offset ( << ?+ , hour :: 2 - bytes , ?: , min :: 2 - bytes , rest :: binary >> ) ,
2022- do: parse_offset ( 1 , hour , min , rest )
2024+ defp parse_offset ( << ?+ , h1 , h2 , ?: , m1 , m2 , rest :: binary >> ) ,
2025+ do: parse_offset ( 1 , h1 , h2 , m1 , m2 , rest )
20232026
2024- defp parse_offset ( << ?- , hour :: 2 - bytes , ?: , min :: 2 - bytes , rest :: binary >> ) ,
2025- do: parse_offset ( - 1 , hour , min , rest )
2027+ defp parse_offset ( << ?- , h1 , h2 , ?: , m1 , m2 , rest :: binary >> ) ,
2028+ do: parse_offset ( - 1 , h1 , h2 , m1 , m2 , rest )
20262029
2027- defp parse_offset ( << ?+ , hour :: 2 - bytes , min :: 2 - bytes , rest :: binary >> ) ,
2028- do: parse_offset ( 1 , hour , min , rest )
2030+ defp parse_offset ( << ?+ , h1 , h2 , m1 , m2 , rest :: binary >> ) ,
2031+ do: parse_offset ( 1 , h1 , h2 , m1 , m2 , rest )
20292032
2030- defp parse_offset ( << ?- , hour :: 2 - bytes , min :: 2 - bytes , rest :: binary >> ) ,
2031- do: parse_offset ( - 1 , hour , min , rest )
2033+ defp parse_offset ( << ?- , h1 , h2 , m1 , m2 , rest :: binary >> ) ,
2034+ do: parse_offset ( - 1 , h1 , h2 , m1 , m2 , rest )
20322035
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 )
2036+ defp parse_offset ( << ?+ , h1 , h2 , rest :: binary >> ) , do: parse_offset ( 1 , h1 , h2 , ?0 , ?0 , rest )
2037+ defp parse_offset ( << ?- , h1 , h2 , rest :: binary >> ) , do: parse_offset ( - 1 , h1 , h2 , ?0 , ?0 , rest )
20352038 defp parse_offset ( _ ) , do: :error
20362039
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
2040+ defp parse_offset ( sign , h1 , h2 , m1 , m2 , rest ) do
2041+ with true <- h1 in ?0 .. ?2 and h2 in ?0 .. ?9 ,
2042+ true <- m1 in ?0 .. ?5 and m2 in ?0 .. ?9 ,
2043+ hour = ( h1 - ?0 ) * 10 + h2 - ?0 ,
2044+ min = ( m1 - ?0 ) * 10 + m2 - ?0 ,
2045+ true <- hour < 24 do
20402046 { ( hour * 60 + min ) * 60 * sign , rest }
20412047 else
20422048 _ -> :error
0 commit comments