1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- G N A T . C A L E N D A R --
11 -- Copyright (C) 1999-2001 Ada Core Technologies, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- As a special exception, if other files instantiate generics from this --
25 -- unit, or you link this unit with other files to produce an executable, --
26 -- this unit does not by itself cause the resulting executable to be --
27 -- covered by the GNU General Public License. This exception does not --
28 -- however invalidate any other reasons why the executable file might be --
29 -- covered by the GNU Public License. --
31 -- GNAT was originally developed by the GNAT team at New York University. --
32 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
34 ------------------------------------------------------------------------------
36 package body GNAT.Calendar is
45 function Day_In_Year (Date : Time) return Day_In_Year_Number is
52 Split (Date, Year, Month, Day, Dsecs);
54 return Julian_Day (Year, Month, Day) - Julian_Day (Year, 1, 1) + 1;
61 function Day_Of_Week (Date : Time) return Day_Name is
68 Split (Date, Year, Month, Day, Dsecs);
70 return Day_Name'Val ((Julian_Day (Year, Month, Day)) mod 7);
77 function Hour (Date : Time) return Hour_Number is
82 Minute : Minute_Number;
83 Second : Second_Number;
84 Sub_Second : Second_Duration;
87 Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
95 -- Julian_Day is used to by Day_Of_Week and Day_In_Year. Note
96 -- that this implementation is not expensive.
100 Month : Month_Number;
104 Internal_Year : Integer;
105 Internal_Month : Integer;
106 Internal_Day : Integer;
107 Julian_Date : Integer;
112 Internal_Year := Integer (Year);
113 Internal_Month := Integer (Month);
114 Internal_Day := Integer (Day);
116 if Internal_Month > 2 then
117 Internal_Month := Internal_Month - 3;
119 Internal_Month := Internal_Month + 9;
120 Internal_Year := Internal_Year - 1;
123 C := Internal_Year / 100;
124 Ya := Internal_Year - (100 * C);
126 Julian_Date := (146_097 * C) / 4 +
128 (153 * Internal_Month + 2) / 5 +
129 Internal_Day + 1_721_119;
138 function Minute (Date : Time) return Minute_Number is
140 Month : Month_Number;
143 Minute : Minute_Number;
144 Second : Second_Number;
145 Sub_Second : Second_Duration;
148 Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
156 function Second (Date : Time) return Second_Number is
158 Month : Month_Number;
161 Minute : Minute_Number;
162 Second : Second_Number;
163 Sub_Second : Second_Duration;
166 Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
176 Year : out Year_Number;
177 Month : out Month_Number;
178 Day : out Day_Number;
179 Hour : out Hour_Number;
180 Minute : out Minute_Number;
181 Second : out Second_Number;
182 Sub_Second : out Second_Duration)
184 Dsecs : Day_Duration;
188 Split (Date, Year, Month, Day, Dsecs);
193 Secs := Natural (Dsecs - 0.5);
196 Sub_Second := Second_Duration (Dsecs - Day_Duration (Secs));
197 Hour := Hour_Number (Secs / 3600);
198 Secs := Secs mod 3600;
199 Minute := Minute_Number (Secs / 60);
200 Second := Second_Number (Secs mod 60);
207 function Sub_Second (Date : Time) return Second_Duration is
209 Month : Month_Number;
212 Minute : Minute_Number;
213 Second : Second_Number;
214 Sub_Second : Second_Duration;
217 Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
227 Month : Month_Number;
230 Minute : Minute_Number;
231 Second : Second_Number;
232 Sub_Second : Second_Duration := 0.0)
235 Dsecs : constant Day_Duration :=
236 Day_Duration (Hour * 3600 + Minute * 60 + Second) +
239 return Time_Of (Year, Month, Day, Dsecs);
246 function To_Duration (T : access timeval) return Duration is
248 procedure timeval_to_duration
251 usec : access C.long);
252 pragma Import (C, timeval_to_duration, "__gnat_timeval_to_duration");
254 Micro : constant := 10**6;
255 sec : aliased C.long;
256 usec : aliased C.long;
260 timeval_to_duration (T, sec'Access, usec'Access);
261 return Duration (sec) + Duration (usec) / Micro;
268 function To_Timeval (D : Duration) return timeval is
270 procedure duration_to_timeval (Sec, Usec : C.long; T : access timeval);
271 pragma Import (C, duration_to_timeval, "__gnat_duration_to_timeval");
273 Micro : constant := 10**6;
274 Result : aliased timeval;
283 sec := C.long (D - 0.5);
284 usec := C.long ((D - Duration (sec)) * Micro - 0.5);
287 duration_to_timeval (sec, usec, Result'Access);
296 function Week_In_Year
297 (Date : Ada.Calendar.Time)
298 return Week_In_Year_Number
301 Month : Month_Number;
304 Minute : Minute_Number;
305 Second : Second_Number;
306 Sub_Second : Second_Duration;
310 Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
312 -- Day offset number for the first week of the year.
314 Offset := Julian_Day (Year, 1, 1) mod 7;
316 return 1 + ((Day_In_Year (Date) - 1) + Offset) / 7;