File 2081-stdlib-Add-native-to-calendar-rfc3339_time_unit.patch of Package erlang

From 93226c07471c11bed1ced88cdc016abbc7f7e594 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Fri, 24 Sep 2021 20:10:56 +0200
Subject: [PATCH 1/2] stdlib: Add native to calendar rfc3339_time_unit

thus supporting
calendar:system_time_to_rfc3339(Time, [{unit,native}]).
calendar:rfc3339_to_system_time(Time, [{unit,native}]).
---
 lib/stdlib/doc/src/calendar.xml    | 18 ++++++++++++------
 lib/stdlib/src/calendar.erl        | 25 +++++++++++++++++++++----
 lib/stdlib/test/calendar_SUITE.erl | 18 +++++++++++++++++-
 3 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index 213bca365d..feb0a5784e 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -124,6 +124,13 @@
     <datatype>
       <name name="weeknum"/>
     </datatype>
+    <datatype>
+      <name name="rfc3339_time_unit"/>
+      <desc><note><p>
+        The <c>native</c> time unit was added to <c>rfc3339_time_unit()</c>
+        in OTP 25.0.</p></note>
+      </desc>
+    </datatype>
   </datatypes>
 
   <funcs>
@@ -321,7 +328,6 @@
       <name name="rfc3339_to_system_time" arity="2" since="OTP 21.0"/>
       <fsummary>Convert from RFC 3339 timestamp to system time.</fsummary>
       <type name="rfc3339_string"/>
-      <type name="rfc3339_time_unit"/>
       <desc>
         <p>Converts an RFC 3339 timestamp into system time. The data format
           of RFC 3339 timestamps is described by
@@ -378,7 +384,6 @@
       <fsummary>Convert from system to RFC 3339 timestamp.</fsummary>
       <type name="offset"/>
       <type name="rfc3339_string"/>
-      <type name="rfc3339_time_unit"/>
       <desc>
         <p>Converts a system time into an RFC 3339 timestamp. The data format
           of RFC 3339 timestamps is described by
@@ -401,12 +406,13 @@
 	  <tag><c>{unit, Unit}</c></tag>
 	  <item><p>The time unit of <c><anno>Time</anno></c>. The
 	    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
+	    (<c>millisecond</c>, <c>microsecond</c>, <c>nanosecond</c>, or
+            <c>native</c>), the formatted string includes a
 	    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.
+	    is chosen. For <c>native</c> three fractional digits are
+            included. Notice that trailing zeros are not removed from the
+            fraction.
             </p>
 	  </item>
 	</taglist>
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl
index 2f95f54312..e9fcccaba8 100644
--- a/lib/stdlib/src/calendar.erl
+++ b/lib/stdlib/src/calendar.erl
@@ -94,11 +94,11 @@
 -type yearweeknum()    :: {year(),weeknum()}.
 
 -type rfc3339_string() :: [byte(), ...].
-%% By design 'native' is not supported:
 -type rfc3339_time_unit() :: 'microsecond'
                            | 'millisecond'
                            | 'nanosecond'
-                           | 'second'.
+                           | 'second'
+                           | 'native'.
 
 %%----------------------------------------------------------------------
 
@@ -444,7 +444,23 @@ system_time_to_rfc3339(Time) ->
 
 system_time_to_rfc3339(Time, Options) ->
     Unit = proplists:get_value(unit, Options, second),
-    OffsetOption = proplists:get_value(offset, Options, ""),
+    OffsetOpt0 = proplists:get_value(offset, Options, ""),
+    case Unit of
+        native ->
+            TimeMS = erlang:convert_time_unit(Time, native, millisecond),
+            OffsetOpt1 =
+                if is_integer(OffsetOpt0) ->
+                        erlang:convert_time_unit(OffsetOpt0, native,
+                                                 millisecond);
+                   true ->
+                        OffsetOpt0
+                end,
+            system_time_to_rfc3339_do(TimeMS, Options, millisecond, OffsetOpt1);
+        _ ->
+            system_time_to_rfc3339_do(Time, Options, Unit, OffsetOpt0)
+    end.
+
+system_time_to_rfc3339_do(Time, Options, Unit, OffsetOption) ->
     T = proplists:get_value(time_designator, Options, $T),
     AdjustmentSecs = offset_adjustment(Time, Unit, OffsetOption),
     Offset = offset(OffsetOption, AdjustmentSecs),
@@ -739,7 +755,8 @@ copy_sign(N1, _N2) -> N1.
 factor(second)      -> 1;
 factor(millisecond) -> 1000;
 factor(microsecond) -> 1000000;
-factor(nanosecond)  -> 1000000000.
+factor(nanosecond)  -> 1000000000;
+factor(native)      -> erlang:convert_time_unit(1, second, native).
 
 log10(1000) -> 3;
 log10(1000000) -> 6;
diff --git a/lib/stdlib/test/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl
index bea5a217db..5642852211 100644
--- a/lib/stdlib/test/calendar_SUITE.erl
+++ b/lib/stdlib/test/calendar_SUITE.erl
@@ -192,15 +192,19 @@ rfc3339(Config) when is_list(Config) ->
     Mys = [{unit, microsecond}],
     Ns = [{unit, nanosecond}],
     S = [{unit, second}],
+    Na = [{unit, native}],
     D = [{time_designator, $\s}],
     Z = [{offset, "Z"}],
 
     "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-12T23:20:50.520Z" = test_parse("1985-04-12t23:20:50.52z", Na),
     "1985-04-12T21:20:50.520Z" =
         test_parse("1985-04-12T23:20:50.52+02:00", Ms),
+    "1985-04-12T21:20:50.520Z" =
+        test_parse("1985-04-12T23:20:50.52+02:00", Na),
     "1985-04-12T23:20:50Z" = test_parse("1985-04-12T23:20:50.52Z", S),
     "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", Na),
     "1985-04-12T23:20:50.520000Z" =
         test_parse("1985-04-12t23:20:50.52z", Mys),
     "1985-04-12 21:20:50.520000000Z" =
@@ -216,6 +216,8 @@ rfc3339(Config) when is_list(Config) ->
 
     "9999-12-31T23:59:59Z" = roundtrip_fmt_rfc3339_z(253402300799, []),
     "9999-12-31T23:59:59.999Z" = roundtrip_fmt_rfc3339_z(253402300799*1000+999, Ms),
+    NaPerSec = erlang:convert_time_unit(1, second, native),
+    "9999-12-31T23:59:59.999Z" = do_format_z(253402300799*NaPerSec+(NaPerSec-1), Na),
     "9999-12-31T23:59:59.999999Z" =
         roundtrip_fmt_rfc3339_z(253402300799*1000000+999999, Mys),
     "9999-12-31T23:59:59.999999999Z" =
@@ -236,6 +242,7 @@ rfc3339(Config) when is_list(Config) ->
     "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.550Z" = test_parse("1970-01-01T23:59:60.55Z", Ms),
+    "1970-01-02T00:00:00.550Z" = test_parse("1970-01-01T23:59:60.55Z", Na),
     "1970-01-02T00:00:00.550000Z" =
         test_parse("1970-01-01T23:59:60.55Z", Mys),
     "1970-01-02T00:00:00.550000000Z" =
@@ -269,16 +276,25 @@ rfc3339(Config) when is_list(Config) ->
     "2000-01-01T10:02:00.000000000+00:02" =
         do_format(TO * 1000 * 1000 * 1000,
                   [{offset, 120 * 1000 * 1000 * 1000}]++Ns),
+    "2000-01-01T10:02:00.000+00:02" =
+        do_format(TO * NaPerSec, [{offset, 120 * NaPerSec}]++Na),
+
 
     NStr = "2000-01-01T09:58:00-00:02",
     NStr = do_format(TO, [{offset, -120}]),
     "2000-01-01T09:58:00.000-00:02" =
         do_format(TO * 1000, [{offset, -120 * 1000}]++Ms),
+    "2000-01-01T09:58:00.000-00:02" =
+        do_format(TO * NaPerSec, [{offset, -120 * NaPerSec}]++Na),
     "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),
+    "2000-01-01T09:58:00.000-00:02" =
+        do_format(TO * 1000, [{offset, -120 * 1000}]++Ms),
+    "2000-01-01T09:58:00.000-00:02" =
+        do_format(TO * NaPerSec, [{offset, -120 * NaPerSec}]++Na),
 
     543210000 = do_parse("1970-01-01T00:00:00.54321Z", Ns),
     54321000 = do_parse("1970-01-01T00:00:00.054321Z", Ns),
-- 
2.31.1

openSUSE Build Service is sponsored by