diff options
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/doc/src/calendar.xml | 6 | ||||
-rw-r--r-- | lib/stdlib/src/calendar.erl | 11 | ||||
-rw-r--r-- | lib/stdlib/test/calendar_SUITE.erl | 68 | ||||
-rw-r--r-- | lib/stdlib/test/unicode_util_SUITE.erl | 27 | ||||
-rwxr-xr-x | lib/stdlib/uc_spec/gen_unicode_mod.escript | 2 |
5 files changed, 66 insertions, 48 deletions
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml index 6b4fa7f98a..5aee635c38 100644 --- a/lib/stdlib/doc/src/calendar.xml +++ b/lib/stdlib/doc/src/calendar.xml @@ -403,7 +403,11 @@ default is <c>second</c>. If some other unit is given (<c>millisecond</c>, <c>microsecond</c>, or <c>nanosecond</c>), the formatted string includes a - fraction of a second.</p> + fraction of a second. The number of fractional second + digits is three, six, or nine depending on what time unit + is chosen. Notice that trailing zeros are not removed from + the fraction. + </p> </item> </taglist> <pre> diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl index 9a600c1972..bb5d450cd6 100644 --- a/lib/stdlib/src/calendar.erl +++ b/lib/stdlib/src/calendar.erl @@ -693,14 +693,11 @@ local_offset(SystemTime, Unit) -> UniversalSecs = datetime_to_gregorian_seconds(UniversalTime), LocalSecs - UniversalSecs. +fraction_str(1, _Time) -> + ""; fraction_str(Factor, Time) -> - case Time rem Factor of - 0 -> - ""; - Fraction -> - FS = io_lib:fwrite(".~*..0B", [log10(Factor), abs(Fraction)]), - string:trim(FS, trailing, "0") - end. + Fraction = Time rem Factor, + io_lib:fwrite(".~*..0B", [log10(Factor), abs(Fraction)]). fraction(second, _) -> 0; diff --git a/lib/stdlib/test/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl index 55118e251c..df62c0921d 100644 --- a/lib/stdlib/test/calendar_SUITE.erl +++ b/lib/stdlib/test/calendar_SUITE.erl @@ -183,14 +183,15 @@ rfc3339(Config) when is_list(Config) -> D = [{time_designator, $\s}], Z = [{offset, "Z"}], - "1985-04-12T23:20:50.52Z" = test_parse("1985-04-12T23:20:50.52Z", Ms), - "1985-04-12T23:20:50.52Z" = test_parse("1985-04-12t23:20:50.52z", Ms), - "1985-04-12T21:20:50.52Z" = + "1985-04-12T23:20:50.520Z" = test_parse("1985-04-12T23:20:50.52Z", Ms), + "1985-04-12T23:20:50.520Z" = test_parse("1985-04-12t23:20:50.52z", Ms), + "1985-04-12T21:20:50.520Z" = test_parse("1985-04-12T23:20:50.52+02:00", Ms), "1985-04-12T23:20:50Z" = test_parse("1985-04-12T23:20:50.52Z", S), - "1985-04-12T23:20:50.52Z" = test_parse("1985-04-12T23:20:50.52Z", Ms), - "1985-04-12T23:20:50.52Z" = test_parse("1985-04-12t23:20:50.52z", Mys), - "1985-04-12 21:20:50.52Z" = + "1985-04-12T23:20:50.520Z" = test_parse("1985-04-12T23:20:50.52Z", Ms), + "1985-04-12T23:20:50.520000Z" = + test_parse("1985-04-12t23:20:50.52z", Mys), + "1985-04-12 21:20:50.520000000Z" = test_parse("1985-04-12 23:20:50.52+02:00", Ns++D), "1985-04-12T23:20:50Z" = test_parse("1985-04-12T23:20:50.52Z"), "1996-12-20T00:39:57Z" = test_parse("1996-12-19T16:39:57-08:00"), @@ -221,17 +222,20 @@ rfc3339(Config) when is_list(Config) -> "1970-01-02T00:00:00Z" = test_parse("1970-01-01T23:59:60Z"), "1970-01-02T00:00:00Z" = test_parse("1970-01-01T23:59:60.5Z"), "1970-01-02T00:00:00Z" = test_parse("1970-01-01T23:59:60.55Z"), - "1970-01-02T00:00:00.55Z" = test_parse("1970-01-01T23:59:60.55Z", Ms), - "1970-01-02T00:00:00.55Z" = test_parse("1970-01-01T23:59:60.55Z", Mys), - "1970-01-02T00:00:00.55Z" = test_parse("1970-01-01T23:59:60.55Z", Ns), + "1970-01-02T00:00:00.550Z" = test_parse("1970-01-01T23:59:60.55Z", Ms), + "1970-01-02T00:00:00.550000Z" = + test_parse("1970-01-01T23:59:60.55Z", Mys), + "1970-01-02T00:00:00.550000000Z" = + test_parse("1970-01-01T23:59:60.55Z", Ns), "1970-01-02T00:00:00.999999Z" = test_parse("1970-01-01T23:59:60.999999Z", Mys), - "1970-01-02T00:00:01Z" = + "1970-01-02T00:00:01.000Z" = test_parse("1970-01-01T23:59:60.999999Z", Ms), "1970-01-01T00:00:00Z" = test_parse("1970-01-01T00:00:00+00:00"), "1970-01-01T00:00:00Z" = test_parse("1970-01-01T00:00:00-00:00"), "1969-12-31T00:01:00Z" = test_parse("1970-01-01T00:00:00+23:59"), - "1918-11-11T09:00:00Z" = test_parse("1918-11-11T11:00:00+02:00", Mys), + "1918-11-11T09:00:00.000000Z" = + test_parse("1918-11-11T11:00:00+02:00", Mys), "1970-01-01T00:00:00.000001Z" = test_parse("1970-01-01T00:00:00.000001Z", Mys), @@ -242,26 +246,26 @@ rfc3339(Config) when is_list(Config) -> test_time(erlang:system_time(millisecond), Ms), test_time(erlang:system_time(microsecond), Mys++[{offset, "-02:20"}]), - T = erlang:system_time(second), - TS = do_format(T, []), - TS = do_format(T * 1000, Ms), - TS = do_format(T * 1000 * 1000, Mys), - TS = do_format(T * 1000 * 1000 * 1000, Ns), - 946720800 = TO = do_parse("2000-01-01 10:00:00Z", []), Str = "2000-01-01T10:02:00+00:02", Str = do_format(TO, [{offset, 120}]), - Str = do_format(TO * 1000, [{offset, 120 * 1000}]++Ms), - Str = do_format(TO * 1000 * 1000, [{offset, 120 * 1000 * 1000}]++Mys), - Str = do_format(TO * 1000 * 1000 * 1000, - [{offset, 120 * 1000 * 1000 * 1000}]++Ns), + "2000-01-01T10:02:00.000+00:02" = + do_format(TO * 1000, [{offset, 120 * 1000}]++Ms), + "2000-01-01T10:02:00.000000+00:02" = + do_format(TO * 1000 * 1000, [{offset, 120 * 1000 * 1000}]++Mys), + "2000-01-01T10:02:00.000000000+00:02" = + do_format(TO * 1000 * 1000 * 1000, + [{offset, 120 * 1000 * 1000 * 1000}]++Ns), NStr = "2000-01-01T09:58:00-00:02", NStr = do_format(TO, [{offset, -120}]), - NStr = do_format(TO * 1000, [{offset, -120 * 1000}]++Ms), - NStr = do_format(TO * 1000 * 1000, [{offset, -120 * 1000 * 1000}]++Mys), - NStr = do_format(TO * 1000 * 1000 * 1000, - [{offset, -120 * 1000 * 1000 * 1000}]++Ns), + "2000-01-01T09:58:00.000-00:02" = + do_format(TO * 1000, [{offset, -120 * 1000}]++Ms), + "2000-01-01T09:58:00.000000-00:02" = + do_format(TO * 1000 * 1000, [{offset, -120 * 1000 * 1000}]++Mys), + "2000-01-01T09:58:00.000000000-00:02" = + do_format(TO * 1000 * 1000 * 1000, + [{offset, -120 * 1000 * 1000 * 1000}]++Ns), 543210000 = do_parse("1970-01-01T00:00:00.54321Z", Ns), 54321000 = do_parse("1970-01-01T00:00:00.054321Z", Ns), @@ -278,18 +282,18 @@ rfc3339(Config) when is_list(Config) -> -1613833200000000 = do_parse("1918-11-11T11:00:00+02:00", Mys), -1613833200000000 = do_parse("1918-11-11T09:00:00Z", Mys), - "1970-01-01T00:00:00Z" = do_format_z(0, Mys), + "1970-01-01T00:00:00.000000Z" = do_format_z(0, Mys), "1970-01-01T00:00:01Z" = do_format_z(1, S), "1970-01-01T00:00:00.001Z" = do_format_z(1, Ms), "1970-01-01T00:00:00.000001Z" = do_format_z(1, Mys), "1970-01-01T00:00:00.000000001Z" = do_format_z(1, Ns), - "1970-01-01T00:00:01Z" = do_format_z(1000000, Mys), - "1970-01-01T00:00:00.54321Z" = do_format_z(543210, Mys), + "1970-01-01T00:00:01.000000Z" = do_format_z(1000000, Mys), + "1970-01-01T00:00:00.543210Z" = do_format_z(543210, Mys), "1970-01-01T00:00:00.543Z" = do_format_z(543, Ms), - "1970-01-01T00:00:00.54321Z" = do_format_z(543210000, Ns), - "1970-01-01T00:00:06.54321Z" = do_format_z(6543210, Mys), - "1979-06-21T12:12:12Z" = do_format_z(298815132000000, Mys), - "1918-11-11T13:00:00Z" = do_format_z(-1613818800000000, Mys), + "1970-01-01T00:00:00.543210000Z" = do_format_z(543210000, Ns), + "1970-01-01T00:00:06.543210Z" = do_format_z(6543210, Mys), + "1979-06-21T12:12:12.000000Z" = do_format_z(298815132000000, Mys), + "1918-11-11T13:00:00.000000Z" = do_format_z(-1613818800000000, Mys), ok. %% diff --git a/lib/stdlib/test/unicode_util_SUITE.erl b/lib/stdlib/test/unicode_util_SUITE.erl index 962b307b07..044b4e5834 100644 --- a/lib/stdlib/test/unicode_util_SUITE.erl +++ b/lib/stdlib/test/unicode_util_SUITE.erl @@ -126,17 +126,30 @@ verify_gc(Line0, N, Acc) -> %io:format("Line: ~s~n",[Line]), [Data|_Comments] = string:tokens(Line, "#"), - %io:format("Data: ~w~n",[string:tokens(Data, " \t")]), + %% io:format("Data: ~w~n",[string:tokens(Data, " \t")]), {Str,Res} = gc_test_data(string:tokens(Data, " \t"), [], [[]]), - try - Res = fetch(Str, fun unicode_util:gc/1), - Acc - catch _Cl:{badmatch, Other} -> + %% io:format("InputStr: ~w ~w~n",[Str,unicode:characters_to_binary(Str)]), + case verify_gc(Str, Res, N, Line) andalso + verify_gc(unicode:characters_to_binary(Str), Res, N, Line0) of + true -> Acc; + false -> Acc+1 + end. + +verify_gc({error,_,[CP|_]}=Err, _Res, N, Line) -> + IsSurrogate = 16#D800 =< CP andalso CP =< 16#DFFF, + %% Surrogat is not valid in utf8 encoding only utf16 + IsSurrogate orelse + io:format("~w: ~ts~n Error in unicode:characters_to_binary ~w~n", [N, Line, Err]), + IsSurrogate; +verify_gc(Str, Res, N, Line) -> + try fetch(Str, fun unicode_util:gc/1) of + Res -> true; + Other -> io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[N, Line, Str, Str]), io:format("Expected: ~p~n", [Res]), io:format("Got: ~w~n", [Other]), - Acc+1; - Cl:R:Stacktrace -> + false + catch Cl:R:Stacktrace -> io:format("~p: ~ts => |~tp|~n",[N, Line, Str]), io:format("Expected: ~p~n", [Res]), erlang:raise(Cl,R,Stacktrace) diff --git a/lib/stdlib/uc_spec/gen_unicode_mod.escript b/lib/stdlib/uc_spec/gen_unicode_mod.escript index fe5a860d45..535f01a1c5 100755 --- a/lib/stdlib/uc_spec/gen_unicode_mod.escript +++ b/lib/stdlib/uc_spec/gen_unicode_mod.escript @@ -646,7 +646,7 @@ gen_gc(Fd, GBP) -> io:put_chars(Fd, "is_emodifier(_) -> false.\n\n"), io:put_chars(Fd, "gc_zwj(R0, Acc) ->\n case cp(R0) of\n"), - GenZWJGlue = fun(Range) -> io:format(Fd, "~8c~s gc_extend(R1, R0, [CP|Acc]);\n", + GenZWJGlue = fun(Range) -> io:format(Fd, "~8c~s gc_extend(cp(R1), R0, [CP|Acc]);\n", [$\s,gen_case_clause(Range)]) end, [GenZWJGlue(CP) || CP <- merge_ranges(maps:get(glue_after_zwj,GBP))], GenZWJEBG = fun(Range) -> io:format(Fd, "~8c~s gc_e_cont(R1, [CP|Acc]);\n", |