Update concepts branch to revision 131834
[official-gcc.git] / gcc / ada / a-calfor.adb
blob65645b2fba8e352cdb7e9bc8b81bb00ab9af2ebc
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . C A L E N D A R . F O R M A T T I N G --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2006-2007, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 with Ada.Calendar; use Ada.Calendar;
35 with Ada.Calendar.Time_Zones; use Ada.Calendar.Time_Zones;
37 package body Ada.Calendar.Formatting is
39 --------------------------
40 -- Implementation Notes --
41 --------------------------
43 -- All operations in this package are target and time representation
44 -- independent, thus only one source file is needed for multiple targets.
46 procedure Check_Char (S : String; C : Character; Index : Integer);
47 -- Subsidiary to the two versions of Value. Determine whether the
48 -- input string S has character C at position Index. Raise
49 -- Constraint_Error if there is a mismatch.
51 procedure Check_Digit (S : String; Index : Integer);
52 -- Subsidiary to the two versions of Value. Determine whether the
53 -- character of string S at position Index is a digit. This catches
54 -- invalid input such as 1983-*1-j3 u5:n7:k9 which should be
55 -- 1983-01-03 05:07:09. Raise Constraint_Error if there is a mismatch.
57 ----------------
58 -- Check_Char --
59 ----------------
61 procedure Check_Char (S : String; C : Character; Index : Integer) is
62 begin
63 if S (Index) /= C then
64 raise Constraint_Error;
65 end if;
66 end Check_Char;
68 -----------------
69 -- Check_Digit --
70 -----------------
72 procedure Check_Digit (S : String; Index : Integer) is
73 begin
74 if S (Index) not in '0' .. '9' then
75 raise Constraint_Error;
76 end if;
77 end Check_Digit;
79 ---------
80 -- Day --
81 ---------
83 function Day
84 (Date : Time;
85 Time_Zone : Time_Zones.Time_Offset := 0) return Day_Number
87 Y : Year_Number;
88 Mo : Month_Number;
89 D : Day_Number;
90 H : Hour_Number;
91 Mi : Minute_Number;
92 Se : Second_Number;
93 Ss : Second_Duration;
94 Le : Boolean;
96 pragma Unreferenced (Y, Mo, H, Mi);
98 begin
99 Split (Date, Y, Mo, D, H, Mi, Se, Ss, Le, Time_Zone);
100 return D;
101 end Day;
103 -----------------
104 -- Day_Of_Week --
105 -----------------
107 function Day_Of_Week (Date : Time) return Day_Name is
108 begin
109 return Day_Name'Val (Formatting_Operations.Day_Of_Week (Date));
110 end Day_Of_Week;
112 ----------
113 -- Hour --
114 ----------
116 function Hour
117 (Date : Time;
118 Time_Zone : Time_Zones.Time_Offset := 0) return Hour_Number
120 Y : Year_Number;
121 Mo : Month_Number;
122 D : Day_Number;
123 H : Hour_Number;
124 Mi : Minute_Number;
125 Se : Second_Number;
126 Ss : Second_Duration;
127 Le : Boolean;
129 pragma Unreferenced (Y, Mo, D, Mi);
131 begin
132 Split (Date, Y, Mo, D, H, Mi, Se, Ss, Le, Time_Zone);
133 return H;
134 end Hour;
136 -----------
137 -- Image --
138 -----------
140 function Image
141 (Elapsed_Time : Duration;
142 Include_Time_Fraction : Boolean := False) return String
144 Hour : Hour_Number;
145 Minute : Minute_Number;
146 Second : Second_Number;
147 Sub_Second : Duration;
148 SS_Nat : Natural;
150 Low : Integer;
151 High : Integer;
153 Result : String := "-00:00:00.00";
155 begin
156 Split (abs (Elapsed_Time), Hour, Minute, Second, Sub_Second);
158 -- Determine the two slice bounds for the result string depending on
159 -- whether the input is negative and whether fractions are requested.
161 if Elapsed_Time < 0.0 then
162 Low := 1;
163 else
164 Low := 2;
165 end if;
167 if Include_Time_Fraction then
168 High := 12;
169 else
170 High := 9;
171 end if;
173 -- Prevent rounding when converting to natural
175 Sub_Second := Sub_Second * 100.0 - 0.5;
176 SS_Nat := Natural (Sub_Second);
178 declare
179 Hour_Str : constant String := Hour_Number'Image (Hour);
180 Minute_Str : constant String := Minute_Number'Image (Minute);
181 Second_Str : constant String := Second_Number'Image (Second);
182 SS_Str : constant String := Natural'Image (SS_Nat);
184 begin
185 -- Hour processing, positions 2 and 3
187 if Hour < 10 then
188 Result (3) := Hour_Str (2);
189 else
190 Result (2) := Hour_Str (2);
191 Result (3) := Hour_Str (3);
192 end if;
194 -- Minute processing, positions 5 and 6
196 if Minute < 10 then
197 Result (6) := Minute_Str (2);
198 else
199 Result (5) := Minute_Str (2);
200 Result (6) := Minute_Str (3);
201 end if;
203 -- Second processing, positions 8 and 9
205 if Second < 10 then
206 Result (9) := Second_Str (2);
207 else
208 Result (8) := Second_Str (2);
209 Result (9) := Second_Str (3);
210 end if;
212 -- Optional sub second processing, positions 11 and 12
214 if Include_Time_Fraction then
215 if SS_Nat < 10 then
216 Result (12) := SS_Str (2);
217 else
218 Result (11) := SS_Str (2);
219 Result (12) := SS_Str (3);
220 end if;
221 end if;
223 return Result (Low .. High);
224 end;
225 end Image;
227 -----------
228 -- Image --
229 -----------
231 function Image
232 (Date : Time;
233 Include_Time_Fraction : Boolean := False;
234 Time_Zone : Time_Zones.Time_Offset := 0) return String
236 Year : Year_Number;
237 Month : Month_Number;
238 Day : Day_Number;
239 Hour : Hour_Number;
240 Minute : Minute_Number;
241 Second : Second_Number;
242 Sub_Second : Duration;
243 SS_Nat : Natural;
244 Leap_Second : Boolean;
246 Result : String := "0000-00-00 00:00:00.00";
248 begin
249 Split (Date, Year, Month, Day,
250 Hour, Minute, Second, Sub_Second, Leap_Second, Time_Zone);
252 -- Prevent rounding when converting to natural
254 Sub_Second := Sub_Second * 100.0 - 0.5;
255 SS_Nat := Natural (Sub_Second);
257 declare
258 Year_Str : constant String := Year_Number'Image (Year);
259 Month_Str : constant String := Month_Number'Image (Month);
260 Day_Str : constant String := Day_Number'Image (Day);
261 Hour_Str : constant String := Hour_Number'Image (Hour);
262 Minute_Str : constant String := Minute_Number'Image (Minute);
263 Second_Str : constant String := Second_Number'Image (Second);
264 SS_Str : constant String := Natural'Image (SS_Nat);
266 begin
267 -- Year processing, positions 1, 2, 3 and 4
269 Result (1) := Year_Str (2);
270 Result (2) := Year_Str (3);
271 Result (3) := Year_Str (4);
272 Result (4) := Year_Str (5);
274 -- Month processing, positions 6 and 7
276 if Month < 10 then
277 Result (7) := Month_Str (2);
278 else
279 Result (6) := Month_Str (2);
280 Result (7) := Month_Str (3);
281 end if;
283 -- Day processing, positions 9 and 10
285 if Day < 10 then
286 Result (10) := Day_Str (2);
287 else
288 Result (9) := Day_Str (2);
289 Result (10) := Day_Str (3);
290 end if;
292 -- Hour processing, positions 12 and 13
294 if Hour < 10 then
295 Result (13) := Hour_Str (2);
296 else
297 Result (12) := Hour_Str (2);
298 Result (13) := Hour_Str (3);
299 end if;
301 -- Minute processing, positions 15 and 16
303 if Minute < 10 then
304 Result (16) := Minute_Str (2);
305 else
306 Result (15) := Minute_Str (2);
307 Result (16) := Minute_Str (3);
308 end if;
310 -- Second processing, positions 18 and 19
312 if Second < 10 then
313 Result (19) := Second_Str (2);
314 else
315 Result (18) := Second_Str (2);
316 Result (19) := Second_Str (3);
317 end if;
319 -- Optional sub second processing, positions 21 and 22
321 if Include_Time_Fraction then
322 if SS_Nat < 10 then
323 Result (22) := SS_Str (2);
324 else
325 Result (21) := SS_Str (2);
326 Result (22) := SS_Str (3);
327 end if;
329 return Result;
330 else
331 return Result (1 .. 19);
332 end if;
333 end;
334 end Image;
336 ------------
337 -- Minute --
338 ------------
340 function Minute
341 (Date : Time;
342 Time_Zone : Time_Zones.Time_Offset := 0) return Minute_Number
344 Y : Year_Number;
345 Mo : Month_Number;
346 D : Day_Number;
347 H : Hour_Number;
348 Mi : Minute_Number;
349 Se : Second_Number;
350 Ss : Second_Duration;
351 Le : Boolean;
353 pragma Unreferenced (Y, Mo, D, H);
355 begin
356 Split (Date, Y, Mo, D, H, Mi, Se, Ss, Le, Time_Zone);
357 return Mi;
358 end Minute;
360 -----------
361 -- Month --
362 -----------
364 function Month
365 (Date : Time;
366 Time_Zone : Time_Zones.Time_Offset := 0) return Month_Number
368 Y : Year_Number;
369 Mo : Month_Number;
370 D : Day_Number;
371 H : Hour_Number;
372 Mi : Minute_Number;
373 Se : Second_Number;
374 Ss : Second_Duration;
375 Le : Boolean;
377 pragma Unreferenced (Y, D, H, Mi);
379 begin
380 Split (Date, Y, Mo, D, H, Mi, Se, Ss, Le, Time_Zone);
381 return Mo;
382 end Month;
384 ------------
385 -- Second --
386 ------------
388 function Second (Date : Time) return Second_Number is
389 Y : Year_Number;
390 Mo : Month_Number;
391 D : Day_Number;
392 H : Hour_Number;
393 Mi : Minute_Number;
394 Se : Second_Number;
395 Ss : Second_Duration;
396 Le : Boolean;
398 pragma Unreferenced (Y, Mo, D, H, Mi);
400 begin
401 Split (Date, Y, Mo, D, H, Mi, Se, Ss, Le);
402 return Se;
403 end Second;
405 ----------------
406 -- Seconds_Of --
407 ----------------
409 function Seconds_Of
410 (Hour : Hour_Number;
411 Minute : Minute_Number;
412 Second : Second_Number := 0;
413 Sub_Second : Second_Duration := 0.0) return Day_Duration is
415 begin
416 -- Validity checks
418 if not Hour'Valid
419 or else not Minute'Valid
420 or else not Second'Valid
421 or else not Sub_Second'Valid
422 then
423 raise Constraint_Error;
424 end if;
426 return Day_Duration (Hour * 3_600) +
427 Day_Duration (Minute * 60) +
428 Day_Duration (Second) +
429 Sub_Second;
430 end Seconds_Of;
432 -----------
433 -- Split --
434 -----------
436 procedure Split
437 (Seconds : Day_Duration;
438 Hour : out Hour_Number;
439 Minute : out Minute_Number;
440 Second : out Second_Number;
441 Sub_Second : out Second_Duration)
443 Secs : Natural;
445 begin
446 -- Validity checks
448 if not Seconds'Valid then
449 raise Constraint_Error;
450 end if;
452 if Seconds = 0.0 then
453 Secs := 0;
454 else
455 Secs := Natural (Seconds - 0.5);
456 end if;
458 Sub_Second := Second_Duration (Seconds - Day_Duration (Secs));
459 Hour := Hour_Number (Secs / 3_600);
460 Secs := Secs mod 3_600;
461 Minute := Minute_Number (Secs / 60);
462 Second := Second_Number (Secs mod 60);
464 -- Validity checks
466 if not Hour'Valid
467 or else not Minute'Valid
468 or else not Second'Valid
469 or else not Sub_Second'Valid
470 then
471 raise Time_Error;
472 end if;
473 end Split;
475 -----------
476 -- Split --
477 -----------
479 procedure Split
480 (Date : Time;
481 Year : out Year_Number;
482 Month : out Month_Number;
483 Day : out Day_Number;
484 Seconds : out Day_Duration;
485 Leap_Second : out Boolean;
486 Time_Zone : Time_Zones.Time_Offset := 0)
488 H : Integer;
489 M : Integer;
490 Se : Integer;
491 Su : Duration;
492 Tz : constant Long_Integer := Long_Integer (Time_Zone);
494 begin
495 Formatting_Operations.Split
496 (Date => Date,
497 Year => Year,
498 Month => Month,
499 Day => Day,
500 Day_Secs => Seconds,
501 Hour => H,
502 Minute => M,
503 Second => Se,
504 Sub_Sec => Su,
505 Leap_Sec => Leap_Second,
506 Time_Zone => Tz,
507 Is_Ada_05 => True);
509 -- Validity checks
511 if not Year'Valid
512 or else not Month'Valid
513 or else not Day'Valid
514 or else not Seconds'Valid
515 then
516 raise Time_Error;
517 end if;
518 end Split;
520 -----------
521 -- Split --
522 -----------
524 procedure Split
525 (Date : Time;
526 Year : out Year_Number;
527 Month : out Month_Number;
528 Day : out Day_Number;
529 Hour : out Hour_Number;
530 Minute : out Minute_Number;
531 Second : out Second_Number;
532 Sub_Second : out Second_Duration;
533 Time_Zone : Time_Zones.Time_Offset := 0)
535 Dd : Day_Duration;
536 Le : Boolean;
537 Tz : constant Long_Integer := Long_Integer (Time_Zone);
539 begin
540 Formatting_Operations.Split
541 (Date => Date,
542 Year => Year,
543 Month => Month,
544 Day => Day,
545 Day_Secs => Dd,
546 Hour => Hour,
547 Minute => Minute,
548 Second => Second,
549 Sub_Sec => Sub_Second,
550 Leap_Sec => Le,
551 Time_Zone => Tz,
552 Is_Ada_05 => True);
554 -- Validity checks
556 if not Year'Valid
557 or else not Month'Valid
558 or else not Day'Valid
559 or else not Hour'Valid
560 or else not Minute'Valid
561 or else not Second'Valid
562 or else not Sub_Second'Valid
563 then
564 raise Time_Error;
565 end if;
566 end Split;
568 -----------
569 -- Split --
570 -----------
572 procedure Split
573 (Date : Time;
574 Year : out Year_Number;
575 Month : out Month_Number;
576 Day : out Day_Number;
577 Hour : out Hour_Number;
578 Minute : out Minute_Number;
579 Second : out Second_Number;
580 Sub_Second : out Second_Duration;
581 Leap_Second : out Boolean;
582 Time_Zone : Time_Zones.Time_Offset := 0)
584 Dd : Day_Duration;
585 Tz : constant Long_Integer := Long_Integer (Time_Zone);
587 begin
588 Formatting_Operations.Split
589 (Date => Date,
590 Year => Year,
591 Month => Month,
592 Day => Day,
593 Day_Secs => Dd,
594 Hour => Hour,
595 Minute => Minute,
596 Second => Second,
597 Sub_Sec => Sub_Second,
598 Leap_Sec => Leap_Second,
599 Time_Zone => Tz,
600 Is_Ada_05 => True);
602 -- Validity checks
604 if not Year'Valid
605 or else not Month'Valid
606 or else not Day'Valid
607 or else not Hour'Valid
608 or else not Minute'Valid
609 or else not Second'Valid
610 or else not Sub_Second'Valid
611 then
612 raise Time_Error;
613 end if;
614 end Split;
616 ----------------
617 -- Sub_Second --
618 ----------------
620 function Sub_Second (Date : Time) return Second_Duration is
621 Y : Year_Number;
622 Mo : Month_Number;
623 D : Day_Number;
624 H : Hour_Number;
625 Mi : Minute_Number;
626 Se : Second_Number;
627 Ss : Second_Duration;
628 Le : Boolean;
630 pragma Unreferenced (Y, Mo, D, H, Mi);
632 begin
633 Split (Date, Y, Mo, D, H, Mi, Se, Ss, Le);
634 return Ss;
635 end Sub_Second;
637 -------------
638 -- Time_Of --
639 -------------
641 function Time_Of
642 (Year : Year_Number;
643 Month : Month_Number;
644 Day : Day_Number;
645 Seconds : Day_Duration := 0.0;
646 Leap_Second : Boolean := False;
647 Time_Zone : Time_Zones.Time_Offset := 0) return Time
649 Adj_Year : Year_Number := Year;
650 Adj_Month : Month_Number := Month;
651 Adj_Day : Day_Number := Day;
653 H : constant Integer := 1;
654 M : constant Integer := 1;
655 Se : constant Integer := 1;
656 Ss : constant Duration := 0.1;
657 Tz : constant Long_Integer := Long_Integer (Time_Zone);
659 begin
660 -- Validity checks
662 if not Year'Valid
663 or else not Month'Valid
664 or else not Day'Valid
665 or else not Seconds'Valid
666 or else not Time_Zone'Valid
667 then
668 raise Constraint_Error;
669 end if;
671 -- A Seconds value of 86_400 denotes a new day. This case requires an
672 -- adjustment to the input values.
674 if Seconds = 86_400.0 then
675 if Day < Days_In_Month (Month)
676 or else (Is_Leap (Year)
677 and then Month = 2)
678 then
679 Adj_Day := Day + 1;
680 else
681 Adj_Day := 1;
683 if Month < 12 then
684 Adj_Month := Month + 1;
685 else
686 Adj_Month := 1;
687 Adj_Year := Year + 1;
688 end if;
689 end if;
690 end if;
692 return
693 Formatting_Operations.Time_Of
694 (Year => Adj_Year,
695 Month => Adj_Month,
696 Day => Adj_Day,
697 Day_Secs => Seconds,
698 Hour => H,
699 Minute => M,
700 Second => Se,
701 Sub_Sec => Ss,
702 Leap_Sec => Leap_Second,
703 Use_Day_Secs => True,
704 Is_Ada_05 => True,
705 Time_Zone => Tz);
706 end Time_Of;
708 -------------
709 -- Time_Of --
710 -------------
712 function Time_Of
713 (Year : Year_Number;
714 Month : Month_Number;
715 Day : Day_Number;
716 Hour : Hour_Number;
717 Minute : Minute_Number;
718 Second : Second_Number;
719 Sub_Second : Second_Duration := 0.0;
720 Leap_Second : Boolean := False;
721 Time_Zone : Time_Zones.Time_Offset := 0) return Time
723 Dd : constant Day_Duration := Day_Duration'First;
724 Tz : constant Long_Integer := Long_Integer (Time_Zone);
726 begin
727 -- Validity checks
729 if not Year'Valid
730 or else not Month'Valid
731 or else not Day'Valid
732 or else not Hour'Valid
733 or else not Minute'Valid
734 or else not Second'Valid
735 or else not Sub_Second'Valid
736 or else not Time_Zone'Valid
737 then
738 raise Constraint_Error;
739 end if;
741 return
742 Formatting_Operations.Time_Of
743 (Year => Year,
744 Month => Month,
745 Day => Day,
746 Day_Secs => Dd,
747 Hour => Hour,
748 Minute => Minute,
749 Second => Second,
750 Sub_Sec => Sub_Second,
751 Leap_Sec => Leap_Second,
752 Use_Day_Secs => False,
753 Is_Ada_05 => True,
754 Time_Zone => Tz);
755 end Time_Of;
757 -----------
758 -- Value --
759 -----------
761 function Value
762 (Date : String;
763 Time_Zone : Time_Zones.Time_Offset := 0) return Time
765 D : String (1 .. 22);
766 Year : Year_Number;
767 Month : Month_Number;
768 Day : Day_Number;
769 Hour : Hour_Number;
770 Minute : Minute_Number;
771 Second : Second_Number;
772 Sub_Second : Second_Duration := 0.0;
774 begin
775 -- Validity checks
777 if not Time_Zone'Valid then
778 raise Constraint_Error;
779 end if;
781 -- Length checks
783 if Date'Length /= 19
784 and then Date'Length /= 22
785 then
786 raise Constraint_Error;
787 end if;
789 -- After the correct length has been determined, it is safe to
790 -- copy the Date in order to avoid Date'First + N indexing.
792 D (1 .. Date'Length) := Date;
794 -- Format checks
796 Check_Char (D, '-', 5);
797 Check_Char (D, '-', 8);
798 Check_Char (D, ' ', 11);
799 Check_Char (D, ':', 14);
800 Check_Char (D, ':', 17);
802 if Date'Length = 22 then
803 Check_Char (D, '.', 20);
804 end if;
806 -- Leading zero checks
808 Check_Digit (D, 6);
809 Check_Digit (D, 9);
810 Check_Digit (D, 12);
811 Check_Digit (D, 15);
812 Check_Digit (D, 18);
814 if Date'Length = 22 then
815 Check_Digit (D, 21);
816 end if;
818 -- Value extraction
820 Year := Year_Number (Year_Number'Value (D (1 .. 4)));
821 Month := Month_Number (Month_Number'Value (D (6 .. 7)));
822 Day := Day_Number (Day_Number'Value (D (9 .. 10)));
823 Hour := Hour_Number (Hour_Number'Value (D (12 .. 13)));
824 Minute := Minute_Number (Minute_Number'Value (D (15 .. 16)));
825 Second := Second_Number (Second_Number'Value (D (18 .. 19)));
827 -- Optional part
829 if Date'Length = 22 then
830 Sub_Second := Second_Duration (Second_Duration'Value (D (20 .. 22)));
831 end if;
833 -- Sanity checks
835 if not Year'Valid
836 or else not Month'Valid
837 or else not Day'Valid
838 or else not Hour'Valid
839 or else not Minute'Valid
840 or else not Second'Valid
841 or else not Sub_Second'Valid
842 then
843 raise Constraint_Error;
844 end if;
846 return Time_Of (Year, Month, Day,
847 Hour, Minute, Second, Sub_Second, False, Time_Zone);
849 exception
850 when others => raise Constraint_Error;
851 end Value;
853 -----------
854 -- Value --
855 -----------
857 function Value (Elapsed_Time : String) return Duration is
858 D : String (1 .. 11);
859 Hour : Hour_Number;
860 Minute : Minute_Number;
861 Second : Second_Number;
862 Sub_Second : Second_Duration := 0.0;
864 begin
865 -- Length checks
867 if Elapsed_Time'Length /= 8
868 and then Elapsed_Time'Length /= 11
869 then
870 raise Constraint_Error;
871 end if;
873 -- After the correct length has been determined, it is safe to
874 -- copy the Elapsed_Time in order to avoid Date'First + N indexing.
876 D (1 .. Elapsed_Time'Length) := Elapsed_Time;
878 -- Format checks
880 Check_Char (D, ':', 3);
881 Check_Char (D, ':', 6);
883 if Elapsed_Time'Length = 11 then
884 Check_Char (D, '.', 9);
885 end if;
887 -- Leading zero checks
889 Check_Digit (D, 1);
890 Check_Digit (D, 4);
891 Check_Digit (D, 7);
893 if Elapsed_Time'Length = 11 then
894 Check_Digit (D, 10);
895 end if;
897 -- Value extraction
899 Hour := Hour_Number (Hour_Number'Value (D (1 .. 2)));
900 Minute := Minute_Number (Minute_Number'Value (D (4 .. 5)));
901 Second := Second_Number (Second_Number'Value (D (7 .. 8)));
903 -- Optional part
905 if Elapsed_Time'Length = 11 then
906 Sub_Second := Second_Duration (Second_Duration'Value (D (9 .. 11)));
907 end if;
909 -- Sanity checks
911 if not Hour'Valid
912 or else not Minute'Valid
913 or else not Second'Valid
914 or else not Sub_Second'Valid
915 then
916 raise Constraint_Error;
917 end if;
919 return Seconds_Of (Hour, Minute, Second, Sub_Second);
921 exception
922 when others => raise Constraint_Error;
923 end Value;
925 ----------
926 -- Year --
927 ----------
929 function Year
930 (Date : Time;
931 Time_Zone : Time_Zones.Time_Offset := 0) return Year_Number
933 Y : Year_Number;
934 Mo : Month_Number;
935 D : Day_Number;
936 H : Hour_Number;
937 Mi : Minute_Number;
938 Se : Second_Number;
939 Ss : Second_Duration;
940 Le : Boolean;
942 pragma Unreferenced (Mo, D, H, Mi);
944 begin
945 Split (Date, Y, Mo, D, H, Mi, Se, Ss, Le, Time_Zone);
946 return Y;
947 end Year;
949 end Ada.Calendar.Formatting;