# Differences

This shows you the differences between two versions of the page.

thomaslocke [The Problem]
thomaslocke [A Full Program]
Line 1: Line 1:
=====  Introduction ​ ===== =====  Introduction ​ =====

=====  Caveat ​ ===== =====  Caveat ​ =====

-The following ​is an example ​of how to do something. It's not meant to be used in any real capacity. If you need a portable [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]],​ then you're better off using the many nice features of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6-1.html#​I3773|Ada.Calendar.Formatting]].+The following ​are examples ​of how to do something. It's not meant to be used in any real capacity. If you need a portable [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]],​ then you're better off using the many nice features of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6-1.html#​I3773|Ada.Calendar.Formatting]].

=====  The Problem ​ ===== =====  The Problem ​ =====
Line 12: Line 12:

-  ​> The time base associated with the type Time of package Calendar is implementation defined. The function Clock of package Calendar returns a value representing the current time for this time base. The implementation-defined value of the named number System.Tick (see 13.7) is an approximation of the length of the real-time interval during which the value of Calendar.Clock remains constant.+> The time base associated with the type Time of package Calendar is implementation defined. The function Clock of package Calendar returns a value representing the current time for this time base. The implementation-defined value of the named number System.Tick (see 13.7) is an approximation of the length of the real-time interval during which the value of Calendar.Clock remains constant.

So we can't see it, and we don't know how it's implemented. But there are ways around these issues. So we can't see it, and we don't know how it's implemented. But there are ways around these issues.

-=====  One Solution ​ =====+===== One Solution =====

-For my experiment I've used the [[http://​libre.adacore.com/​libre/​|GNAT GPL 2010]] compiler, and in this compiler the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Time]] type is declared as:+In this first solution, we're going to make use of the //'​Address//​ attribute. ​For my experiment I've used the [[http://​libre.adacore.com/​libre/​|GNAT GPL 2010]] compiler, and in this compiler the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Time]] type is declared as:

Line 28: Line 28:

-function ​Time_Image ​+function ​Time_Image_One
​return String    ​return String
is is
-   ​type ​Time is mod 2 ** 64; +   ​type ​New_Time ​is mod 2 ** 64;
-   ​pragma Assert (Time'Size = Item'​Size);​ +   ​pragma Assert (New_Time'Size = Item'​Size);​
-   ​ +
-   ​Time_Stamp : Time;+   ​Time_Stamp : New_Time;
begin begin
-   ​return Trim (Source => Time'Image (Time_Stamp),​+   ​return Trim (Source => New_Time'Image (Time_Stamp),​
-end Time_Image;+end Time_Image_One;
</​code>​ </​code>​

Line 48: Line 48:

-type Time is mod 2 ** 64;+type New_Time ​is mod 2 ** 64;
</​code>​ </​code>​

Line 54: Line 54:

-pragma Assert (Time'Size = Item'​Size);​+pragma Assert (New_Time'Size = Item'​Size);​
</​code>​ </​code>​

Line 64: Line 64:

-Time_Stamp : Time;+Time_Stamp : New_Time;
</​code>​ </​code>​
Line 73: Line 73:

-return Trim (Source => Time'Image (Time_Stamp),​+return Trim (Source => New_Time'Image (Time_Stamp),​
</​code>​ </​code>​
Line 79: Line 79:
And voila! We have a neat [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] return value. Whether or not this is useful for anything, well, I'll leave that decision to the reader. And voila! We have a neat [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] return value. Whether or not this is useful for anything, well, I'll leave that decision to the reader.

-=====  ​Thanks ​ =====+===== Another Solution =====
+
+The above solution is not the only way to accomplish the goal of outputting the return value of //​Ada.Calendar.Clock//​. There'​s another, and probably better, method: Using [[http://​www.adaic.org/​resources/​add_content/​standards/​05rm/​html/​RM-13-9.html|Ada.Unchecked_Conversion]]. Here's how the above //​Time_Image_One//​ function would look if we used //​Ada.Unchecked_Conversion//​ instead:
+
+function Time_Image_Two
+   ​return String
+is
+   type New_Time is mod 2 ** 64;
+   ​pragma Assert (New_Time'​Size = Ada.Calendar.Time'​Size);​
+
+   ​function To_Time
+                                    Target => New_Time);​
+
+   ​Time_Stamp : constant New_Time := To_Time (Item);
+begin
+   ​return Trim (Source => New_Time'​Image (Time_Stamp),​
+end Time_Image_Two;​
+</​code>​
+
+A great boon of this method over the first one, is this fantastic warning message the GNAT compiler will dump on you when you compile the program:
+
+  warning: representation of Time values may change between GNAT versions
+
+You're not going to get that with the first method, and in my humble opinion that warning alone makes it worthwhile to use //​Ada.Unchecked_Conversion//​ instead of the //'​Address//​ attribute used in the first solution.
+===== The Full Program =====
+
+Lets end with a little program that utilizes both solutions to output the value of //​Ada.Calendar.Clock//:​
+
+
+procedure Time_Image_Test is
+
+   ​----------------------
+   ​-- ​ Time_Image_One ​ --
+   ​----------------------
+
+   ​function Time_Image_One
+      return String
+   is
+      type New_Time is mod 2 ** 64;
+      pragma Assert (New_Time'​Size = Item'​Size);​
+
+      Time_Stamp : New_Time;
+   ​begin
+      return Trim (Source => New_Time'​Image (Time_Stamp),​
+   end Time_Image_One;​
+
+   ​----------------------
+   ​-- ​ Time_Image_Two ​ --
+   ​----------------------
+
+   ​function Time_Image_Two
+      return String
+   is
+      type New_Time is mod 2 ** 64;
+      pragma Assert (New_Time'​Size = Ada.Calendar.Time'​Size);​
+
+      function To_Time
+                                       ​Target => New_Time);​
+
+      Time_Stamp : constant New_Time := To_Time (Item);
+   ​begin
+      return Trim (Source => New_Time'​Image (Time_Stamp),​
+   end Time_Image_Two;​
+
+begin
+   ​Put_Line (Time_Image_One (Now));
+   ​Put_Line (Time_Image_Two (Now));
+end Time_Image_Test;​
+</​code>​
+
+Elegant stuff!
+
+===== Thanks ​=====

-I'd like to extend my thanks to [[http://​edb.jacob-sparre.dk/​Ada/​|Jacob Sparre]] for gently pushing me in the right direction. As usual the [[http://​freenode.net/​|freenode #ada IRC channel]] proved an invaluable help in learning something new.+I'd like to extend my thanks to [[http://​edb.jacob-sparre.dk/​Ada/​|Jacob Sparre]] for gently pushing me in the right direction ​in regards to solution one, and [[http://​identi.ca/​simonj|Simon J. Wright]] for giving me the second solution. As usual the [[http://​freenode.net/​|freenode #ada IRC channel]] and the [[http://​identi.ca/​thomaslocke/​all/​ada| identi.ca Ada group]] proved an invaluable help in learning something new.