1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- G N A T . C A L E N D A R . T I M E _ I O --
9 -- Copyright (C) 1999-2005, AdaCore --
11 -- This specification is derived from the Ada Reference Manual for use with --
12 -- GNAT. The copyright notice above, and the license provisions that follow --
13 -- apply solely to the contents of the part following the private keyword. --
15 -- GNAT is free software; you can redistribute it and/or modify it under --
16 -- terms of the GNU General Public License as published by the Free Soft- --
17 -- ware Foundation; either version 2, or (at your option) any later ver- --
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
20 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
21 -- for more details. You should have received a copy of the GNU General --
22 -- Public License distributed with GNAT; see file COPYING. If not, write --
23 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
24 -- Boston, MA 02110-1301, USA. --
26 -- As a special exception, if other files instantiate generics from this --
27 -- unit, or you link this unit with other files to produce an executable, --
28 -- this unit does not by itself cause the resulting executable to be --
29 -- covered by the GNU General Public License. This exception does not --
30 -- however invalidate any other reasons why the executable file might be --
31 -- covered by the GNU Public License. --
33 -- GNAT was originally developed by the GNAT team at New York University. --
34 -- Extensive contributions were provided by Ada Core Technologies Inc. --
36 ------------------------------------------------------------------------------
38 with Ada.Calendar; use Ada.Calendar;
39 with Ada.Characters.Handling;
40 with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
43 package body GNAT.Calendar.Time_IO is
59 type Padding_Mode is (None, Zero, Space);
61 -----------------------
62 -- Local Subprograms --
63 -----------------------
65 function Am_Pm (H : Natural) return String;
66 -- Return AM or PM depending on the hour H
68 function Hour_12 (H : Natural) return Positive;
69 -- Convert a 1-24h format to a 0-12 hour format
71 function Image (Str : String; Length : Natural := 0) return String;
72 -- Return Str capitalized and cut to length number of characters. If
73 -- length is set to 0 it does not cut it.
77 Padding : Padding_Mode := Zero;
78 Length : Natural := 0) return String;
79 -- Return image of N. This number is eventually padded with zeros or spaces
80 -- depending of the length required. If length is 0 then no padding occurs.
84 Padding : Padding_Mode := Zero;
85 Length : Natural := 0) return String;
86 -- As above with N provided in Integer format
92 function Am_Pm (H : Natural) return String is
94 if H = 0 or else H > 12 then
105 function Hour_12 (H : Natural) return Positive is
122 Length : Natural := 0) return String
124 use Ada.Characters.Handling;
125 Local : constant String :=
126 To_Upper (Str (1)) & To_Lower (Str (2 .. Str'Last));
131 return Local (1 .. Length);
141 Padding : Padding_Mode := Zero;
142 Length : Natural := 0) return String
145 return Image (Long_Integer (N), Padding, Length);
150 Padding : Padding_Mode := Zero;
151 Length : Natural := 0) return String
153 function Pad_Char return String;
159 function Pad_Char return String is
162 when None => return "";
163 when Zero => return "00";
164 when Space => return " ";
168 NI : constant String := Long_Integer'Image (N);
169 NIP : constant String := Pad_Char & NI (2 .. NI'Last);
171 -- Start of processing for Image
174 if Length = 0 or else Padding = None then
175 return NI (2 .. NI'Last);
177 return NIP (NIP'Last - Length + 1 .. NIP'Last);
186 (Date : Ada.Calendar.Time;
187 Picture : Picture_String) return String
189 Padding : Padding_Mode := Zero;
190 -- Padding is set for one directive
192 Result : Unbounded_String;
195 Month : Month_Number;
198 Minute : Minute_Number;
199 Second : Second_Number;
200 Sub_Second : Second_Duration;
202 P : Positive := Picture'First;
205 Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
208 -- A directive has the following format "%[-_]."
210 if Picture (P) = '%' then
214 if P = Picture'Last then
218 -- Check for GNU extension to change the padding
220 if Picture (P + 1) = '-' then
223 elsif Picture (P + 1) = '_' then
228 if P = Picture'Last then
232 case Picture (P + 1) is
237 Result := Result & '%';
242 Result := Result & ASCII.LF;
247 Result := Result & ASCII.HT;
252 Result := Result & Image (Hour, Padding, 2);
257 Result := Result & Image (Hour_12 (Hour), Padding, 2);
262 Result := Result & Image (Hour, Space, 2);
267 Result := Result & Image (Hour_12 (Hour), Space, 2);
272 Result := Result & Image (Minute, Padding, 2);
277 Result := Result & Am_Pm (Hour);
279 -- Time, 12-hour (hh:mm:ss [AP]M)
283 Image (Hour_12 (Hour), Padding, Length => 2) & ':' &
284 Image (Minute, Padding, Length => 2) & ':' &
285 Image (Second, Padding, Length => 2) & ' ' &
288 -- Seconds since 1970-01-01 00:00:00 UTC
289 -- (a nonstandard extension)
293 Sec : constant Long_Integer :=
295 ((Julian_Day (Year, Month, Day) -
296 Julian_Day (1970, 1, 1)) * 86_400 +
297 Hour * 3_600 + Minute * 60 + Second);
300 Result := Result & Image (Sec, None);
306 Result := Result & Image (Second, Padding, Length => 2);
308 -- Milliseconds (3 digits)
309 -- Microseconds (6 digits)
310 -- Nanoseconds (9 digits)
312 when 'i' | 'e' | 'o' =>
314 Sub_Sec : constant Long_Integer :=
315 Long_Integer (Sub_Second * 1_000_000_000);
317 Img1 : constant String := Sub_Sec'Img;
318 Img2 : constant String :=
319 "00000000" & Img1 (Img1'First + 1 .. Img1'Last);
320 Nanos : constant String :=
321 Img2 (Img2'Last - 8 .. Img2'Last);
324 case Picture (P + 1) is
327 Nanos (Nanos'First .. Nanos'First + 2);
331 Nanos (Nanos'First .. Nanos'First + 5);
334 Result := Result & Nanos;
341 -- Time, 24-hour (hh:mm:ss)
345 Image (Hour, Padding, Length => 2) & ':' &
346 Image (Minute, Padding, Length => 2) & ':' &
347 Image (Second, Padding, Length => 2);
349 -- Locale's abbreviated weekday name (Sun..Sat)
353 Image (Day_Name'Image (Day_Of_Week (Date)), 3);
355 -- Locale's full weekday name, variable length
356 -- (Sunday..Saturday)
360 Image (Day_Name'Image (Day_Of_Week (Date)));
362 -- Locale's abbreviated month name (Jan..Dec)
366 Image (Month_Name'Image (Month_Name'Val (Month - 1)), 3);
368 -- Locale's full month name, variable length
369 -- (January..December)
373 Image (Month_Name'Image (Month_Name'Val (Month - 1)));
375 -- Locale's date and time (Sat Nov 04 12:02:33 EST 1989)
380 Result := Result & Image (Date, "%a %b %d %T %Y");
382 Result := Result & Image (Date, "%a %b %_d %_T %Y");
384 Result := Result & Image (Date, "%a %b %-d %-T %Y");
387 -- Day of month (01..31)
390 Result := Result & Image (Day, Padding, 2);
396 Image (Month, Padding, 2) & '/' &
397 Image (Day, Padding, 2) & '/' &
398 Image (Year, Padding, 2);
400 -- Day of year (001..366)
403 Result := Result & Image (Day_In_Year (Date), Padding, 3);
408 Result := Result & Image (Month, Padding, 2);
410 -- Week number of year with Sunday as first day of week
415 Offset : constant Natural :=
416 (Julian_Day (Year, 1, 1) + 1) mod 7;
418 Week : constant Natural :=
419 1 + ((Day_In_Year (Date) - 1) + Offset) / 7;
422 Result := Result & Image (Week, Padding, 2);
425 -- Day of week (0..6) with 0 corresponding to Sunday
429 DOW : Natural range 0 .. 6;
432 if Day_Of_Week (Date) = Sunday then
435 DOW := Day_Name'Pos (Day_Of_Week (Date));
438 Result := Result & Image (DOW, Length => 1);
441 -- Week number of year with Monday as first day of week
445 Result := Result & Image (Week_In_Year (Date), Padding, 2);
447 -- Last two digits of year (00..99)
451 Y : constant Natural := Year - (Year / 100) * 100;
453 Result := Result & Image (Y, Padding, 2);
459 Result := Result & Image (Year, None, 4);
468 Result := Result & Picture (P);
472 exit when P > Picture'Last;
476 return To_String (Result);
484 (Date : Ada.Calendar.Time;
485 Picture : Picture_String)
488 Ada.Text_IO.Put (Image (Date, Picture));
491 end GNAT.Calendar.Time_IO;