2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Convert the date from machine to human form.
11 const ULONG Utility_DayTable
[]=
13 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
17 /*****************************************************************************
20 #include <utility/date.h>
21 #include <proto/utility.h>
23 AROS_LH2(void, Amiga2Date
,
26 AROS_LHA(ULONG
, seconds
, D0
),
27 AROS_LHA(struct ClockData
*, result
, A0
),
30 struct Library
*, UtilityBase
, 20, Utility
)
33 Convert the time value given as the number of seconds since the
34 1st of January 1978 (00:00:00 1.1.78), to a more useful values,
35 which is easier for most people to understand. These values will
36 be stored in the ClockData structure whose address is passed as
40 seconds - Number of seconds since 1.1.78 00:00:00
41 result - The ClockData structure to store the information
45 The ClockData structure will contain the converted time values.
56 Some information about some constants I use:
58 731 = 365 + 366, the number of days between 1.1.1978 and
59 1.1.1976. Using 1976 makes working out leap years
61 1461 = The number of days in four years including 1 leap year.
63 86400 = The number of seconds in one day.
65 I used these as constants so that they don't have to be computed
66 on the fly, or read from variables.
69 29-10-95 digulla automatically created from
70 utility_lib.fd and clib/utility_protos.h
71 19-05-96 iaint Wrote, with a little help from a Perl package.
72 11-08-96 iaint Updated for the new AROS format.
73 17-08-96 iaint Removed calls to unimplemented UDivMod32/UMult32
74 24-02-97 iaint Reimplemented, actually works now :)
76 *****************************************************************************/
81 static const ULONG dim
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
84 LONG leap
, year
, month
;
88 days
= seconds
/ 86400;
89 result
->wday
= days
% 7;
91 result
->sec
= seconds
% 60;
93 result
->min
= seconds
% 60;
95 result
->hour
= seconds
% 24;
98 /* stegerg: based on dos.library/datetostr */
102 if(days
<92*365+30*366)
105 1976 was a leap year so use it as a base to divide the days
106 into 4-year blocks (each beginning with a leap year).
109 year
=4*(days
/(366+3*365))+1976;
112 /* Now divide the 4-year blocks into single years. */
124 The rule for calendar calculations are:
125 1. Every year even divisible by 4 is a leap year.
126 2. As an exception from rule 1 every year even divisible by
128 3. Every year even divisible by 400 is a leap year as an
129 exception from rule 2.
130 So 1996, 2000 and 2004 are leap years - 1900 and 1999 are not.
132 Use 2000 as a base to devide the days into 400 year blocks,
133 those into 100 year blocks and so on...
136 year
=400*(days
/(97*366+303*365))+2000;
137 days
%=(97*366+303*365);
143 year
+=100*(days
/(24*366+76*365));
144 days
%=(24*366+76*365);
150 year
+=4*(days
/(366+3*365));
164 The starting-day table assumes a leap year - so add one day if
165 the date is after february 28th and the year is no leap year.
167 if(!leap
&&days
>=31+28)
170 for(month
=11;;month
--)
172 if(days
>=Utility_DayTable
[month
])
174 days
-=Utility_DayTable
[month
];
179 /* Remember that 0 means 1.1.1978. */
183 result
->month
= month
;
189 /* Calculate the current year.
191 Firstly, if the year is less than 1980, then the leap year
192 handling is not required...
205 days
= days
- (year
* 365);
210 We need to get into a year that follows a leap year, there
211 are two cases, >2100 and <=2100
213 If the year is after 2100, which is not a leap year, then
216 The first day in year 2101 is ...
224 Otherwise, we just set everything up so that we are relative
234 From here, we know that every remaining set of 4 years
239 result
->year
+= year
* 4;
249 /* Now days is the number of days in the current year... */
250 } /* (not less than 1981) */
252 /* days now contains the days since the beginning of the current year */
253 for(temp
= 0; (temp
== 1) ? (days
>= 28 + leap
) : (days
>= dim
[temp
]); temp
++)
254 days
-= (temp
== 1) ? (28 + leap
) : dim
[temp
];
256 result
->month
= temp
+ 1;
257 result
->mday
= days
+ 1;
258 result
->year
+= year
;