-------------------------------------------------------------------------------
--
--  <STRONG>Copyright &copy; 2001, 2002 by Thomas Wolf.</STRONG>
--  <BLOCKQUOTE>
--    This piece of software is free software; you can redistribute it and/or
--    modify it under the terms of the  GNU General Public License as published
--    by the Free Software  Foundation; either version 2, or (at your option)
--    any later version. This software is distributed in the hope that it will
--    be useful, but <EM>without any warranty</EM>; without even the implied
--    warranty of <EM>merchantability or fitness for a particular purpose.</EM>
--    See the GNU General Public License for  more details. You should have
--    received a copy of the GNU General Public License with this distribution,
--    see file "<A HREF="GPL.txt">GPL.txt</A>". If not, write to the Free
--    Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
--    USA.
--  </BLOCKQUOTE>
--  <BLOCKQUOTE>
--    As a special exception from the GPL, if other files instantiate generics
--    from this unit, or you link this unit with other files to produce an
--    executable, this unit does not by itself cause the resulting executable
--    to be covered by the GPL. This exception does not however invalidate any
--    other reasons why the executable file might be covered by the GPL.
--  </BLOCKQUOTE>
--
--  <AUTHOR>
--    Thomas Wolf  (TW) <E_MAIL>
--  </AUTHOR>
--
--  <PURPOSE>
--    Routines for converting @Ada.Calendar.Time@ values to strings. Identical
--    in function to the operations in <CODE>
--    <A HREF="util-calendars-western.html">Util.Calendars.Western</A></CODE>
--    and <CODE><A HREF="util-times-io.html">Util.Times.IO</A></CODE>.
--
--    Provided nonetheless because one doesn't always want to drag in all the
--    extended time and calendar support, especially for simple applications.
--  </PURPOSE>
--
--  <TASKING>
--    Fully task-safe; not abortion-safe.
--  </TASKING>
--
--  <NO_STORAGE>
--
--  <HISTORY>
--    13-MAR-2002   TW  Initial version.
--  </HISTORY>
-------------------------------------------------------------------------------

pragma License (Modified_GPL);

with Ada.Calendar;

package Util.Calendar.IO is

   pragma Elaborate_Body;

   function Image
     (Instant      : in Ada.Calendar.Day_Duration;
      With_Seconds : in Boolean := True;
      AM_PM        : in Boolean := False)
     return String;
   --  Returns a string representation of the given time value. If
   --  <CODE>Seconds</CODE> is <CODE>False</CODE>, the format is "HH:MM",
   --  seconds are omitted. If <CODE>Seconds</CODE> is <CODE>True</CODE>,
   --  the format is "HH:MM:SS".
   --
   --  If <CODE>AM_PM</CODE> is false, the international 24h representation
   --  is chosen, otherwise the english a.m./p.m. format is generated: the
   --  hour part always is in the range 0 .. 12, and the strings " am" or
   --  " pm" are appended as needed. Note that noon and midnight cannot be
   --  represented in the am/pm system (12:00 am or 00:00 am have no meaning
   --  at all; "am" starts <EM>after</EM> midnight, and "pm" starts
   --  <EM>after</EM> noon). If <CODE>AM_PM</CODE> is <CODE>True</CODE>, noon
   --  generates the string "Noon", and midnight generates the
   --  string "Midnight". Note that midnight is 00:00:00, hence it is the
   --  beginning of the day, not the end! Also note that you still can get a
   --  string "00:00 am" or "00:00:00 am" if the seconds or the fraction is >
   --  zero, but not displayed. Instants between noon and 13:00:00 generate
   --  strings with an hour part "12" and " pm" at the end.
   --
   --  The function never rounds, i.e. seconds or fractions omitted are just
   --  truncated, e.g. 11:11:59.665 yields "11:11" or "11:11:59".

   function Image
     (Instant   : in Ada.Calendar.Day_Duration;
      Precision : in Natural;
      AM_PM     : in Boolean := False)
     return String;
   --  Returns a string with the format "HH:MM:SS.FFF", where FFF has as many
   --  digits as specified by <CODE>Precision</CODE>. If <CODE>Precision</CODE>
   --  is zero, the whole fraction including the decimal point is omitted.
   --  <CODE>AM_PM</CODE> has the same effect as for the <EM>other</EM>
   --  <CODE>Image</CODE> function, except that instances between noon and
   --  13:00:00 generate strings with an hour part "00" and " pm" at the end.
   --  This is because rounding of e.g. 23:59:59.9 with precision 0 may
   --  generate the string "12:00:00 pm", and so might e.g. 12:00:00.1 if
   --  we returned these mid-day times with an hour part "12", too.
   --
   --  This function rounds the fraction to the given precision:
   --
   --  <TABLE BORDER=0>
   --  <TR><TH>Precision</TH><TH COLSPAN=2>Resulting String</TH></TR>
   --  <TR><TH></TH><TH>11:11:59.665</TH><TH>11:11:59.999</TH></TR>
   --  <TR><TD ALIGN="CENTER">0</TD>
   --      <TD ALIGN="LEFT">"11:12:00"</TD>
   --      <TD ALIGN="LEFT">"11:12:00"</TD></TR>
   --  <TR><TD ALIGN="CENTER">1</TD>
   --      <TD ALIGN="LEFT">"11:11:59.7"</TD>
   --      <TD ALIGN="LEFT">"11:12:00.0"</TD></TR>
   --  <TR><TD ALIGN="CENTER">2</TD>
   --      <TD ALIGN="LEFT">"11:11:59.67"</TD>
   --      <TD ALIGN="LEFT">"11:12:00.00"</TD></TR>
   --  <TR><TD ALIGN="CENTER">3</TD>
   --      <TD ALIGN="LEFT">"11:11:59.665"</TD>
   --      <TD ALIGN="LEFT">"11:11:59.999"</TD></TR>
   --  <TR><TD ALIGN="CENTER">4</TD>
   --      <TD ALIGN="LEFT">"11:11:59.6650"</TD>
   --      <TD ALIGN="LEFT">"11:11:59.9990"</TD></TR>
   --  </TABLE>
   --
   --  Note that rounding may generate a result of "24:00:00" or "12:00:00 am"
   --  (noon) or "12:00:00 pm" (midnight; end of the day!) if @Precision@ is
   --  zero!

   type Date_Format is (DMY, MDY, YMD);
   --  Day-Month-Year, Month-Day-Year, Year-Month-Day. I've never come across
   --  any other ordering, and hence the remaining permutations DYM, MYD, and
   --  YDM are not supported.

   function Image
     (Date      : in Ada.Calendar.Time;
      Format    : in Date_Format := YMD;
      Separator : in String      := "-";
      Padding   : in Boolean     := True)
     return String;
   --  Individual date components are separated by the given
   --  <CODE>Separator</CODE>.
   --
   --  If <CODE>Padding</CODE> is true, day and month numbers smaller than
   --  10 have a leading zero.
   --
   --  Examples: (assuming <CODE>Padding = True</CODE>)
   --
   --  <TABLE>
   --  <TR><TH></TH>
   --                       <TH>Format</TH><TH>Separator</TH><TH>03-OCT-2001
   --                                                          yields:</TH>
   --  </TR>
   --  <TR>
   --  <TD>English style:</TD><TD>MDY</TD><TD>"/"</TD> <TD> "10/03/2001"</TD>
   --  </TR>
   --  <TR>
   --  <TD>German style:</TD> <TD>DMY</TD><TD>". "</TD><TD> "03. 10. 2001"</TD>
   --  </TR>
   --  <TR>
   --  <TD>ISO 8601:</TD>     <TD>YMD</TD><TD>"-"</TD> <TD> "2001-10-03"</TD>
   --  </TR>
   --  <TR>
   --  <TD>Timestamp:</TD>    <TD>YMD</TD><TD>""</TD>  <TD> "20011003"</TD>
   --  </TR>
   --  </TABLE>
   --
   --  With the default arguments, the function returns the ISO 8601 date
   --  representation.

end Util.Calendar.IO;

