2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 File: cssmdatetime.cpp
22 Contains: CSSM date and time utilities for the Mac
24 Written by: The Hindsight team
26 Copyright: © 1997-2000 by Apple Computer, Inc., all rights reserved.
28 Change History (most recent first):
34 #define _CPP_CSSM_DATE_TIME_UTILS
37 #include "cssmdatetime.h"
41 #include <Security/utilities.h>
42 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
43 #include <CoreFoundation/CFDate.h>
44 #include <CoreFoundation/CFTimeZone.h>
49 namespace CSSMDateTimeUtils
52 #define MAX_TIME_STR_LEN 30
53 #define UTC_TIME_STRLEN 13
54 #define GENERALIZED_TIME_STRLEN 15
58 GetCurrentMacLongDateTime(SInt64
&outMacDate
)
60 CFTimeZoneRef timeZone
= CFTimeZoneCopyDefault();
61 CFAbsoluteTime absTime
= CFAbsoluteTimeGetCurrent();
62 absTime
+= CFTimeZoneGetSecondsFromGMT(timeZone
, absTime
);
64 outMacDate
= SInt64(double(absTime
+ kCFAbsoluteTimeIntervalSince1904
));
68 TimeStringToMacSeconds (const CSSM_DATA
&inUTCTime
, UInt32
&ioMacDate
)
71 TimeStringToMacLongDateTime(inUTCTime
, ldt
);
72 ioMacDate
= UInt32(ldt
);
76 * Given a CSSM_DATA containing either a UTC-style or "generalized time"
77 * time string, convert to 32-bit Mac time in seconds.
78 * Returns nonzero on error.
81 TimeStringToMacLongDateTime (const CSSM_DATA
&inUTCTime
, SInt64
&outMacDate
)
91 ::memset( &date
, 0, sizeof(date
) );
93 if ((inUTCTime
.Data
== NULL
) || (inUTCTime
.Length
== 0))
95 MacOSError::throwMe(paramErr
);
98 /* tolerate NULL terminated or not */
99 len
= inUTCTime
.Length
;
100 if (inUTCTime
.Data
[len
- 1] == '\0')
105 case UTC_TIME_STRLEN
: // 2-digit year, not Y2K compliant
108 case GENERALIZED_TIME_STRLEN
: // 4-digit year
111 default: // unknown format
112 MacOSError::throwMe(paramErr
);
115 cp
= (char *)inUTCTime
.Data
;
117 /* check that all characters except last are digits */
118 for(i
=0; i
<(sint32
)(len
- 1); i
++) {
119 if ( !(isdigit(cp
[i
])) ) {
120 MacOSError::throwMe(paramErr
);
124 /* check last character is a 'Z' */
125 if(cp
[len
- 1] != 'Z' ) {
126 MacOSError::throwMe(paramErr
);
133 /* two more digits */
145 * 0 <= year <= 50 : assume century 21
146 * 50 < year < 70 : illegal per PKIX
147 * 70 < year <= 99 : assume century 20
153 MacOSError::throwMe(paramErr
);
155 /* else century 20, OK */
157 /* bug fix... we need to end up with a 4-digit year! */
160 /* by definition - tm_year is year - 1900 */
161 //tmp->tm_year = x - 1900;
169 /* in the string, months are from 1 to 12 */
170 if((x
> 12) || (x
<= 0)) {
171 MacOSError::throwMe(paramErr
);
173 /* in a tm, 0 to 11 */
174 //tmp->tm_mon = x - 1;
182 /* 1..31 in both formats */
183 if((x
> 31) || (x
<= 0)) {
184 MacOSError::throwMe(paramErr
);
194 if((x
> 23) || (x
< 0)) {
195 MacOSError::throwMe(paramErr
);
205 if((x
> 59) || (x
< 0)) {
206 MacOSError::throwMe(paramErr
);
216 if((x
> 59) || (x
< 0)) {
217 MacOSError::throwMe(paramErr
);
222 CFTimeZoneRef timeZone
= CFTimeZoneCopyDefault();
223 CFAbsoluteTime absTime
= CFGregorianDateGetAbsoluteTime(date
, timeZone
);
225 outMacDate
= SInt64(double(absTime
+ kCFAbsoluteTimeIntervalSince1904
));
228 void MacSecondsToTimeString(UInt32 inMacDate
, UInt32 inLength
, void *outData
)
230 SInt64 ldt
= SInt64(UInt64(inMacDate
));
231 MacLongDateTimeToTimeString(ldt
, inLength
, outData
);
234 void MacLongDateTimeToTimeString(const SInt64
&inMacDate
,
235 UInt32 inLength
, void *outData
)
237 CFAbsoluteTime absTime
= inMacDate
- kCFAbsoluteTimeIntervalSince1904
;
238 CFTimeZoneRef timeZone
= CFTimeZoneCopyDefault();
239 CFGregorianDate date
= CFAbsoluteTimeGetGregorianDate(absTime
, timeZone
);
244 sprintf((char *)(outData
), "%04d%02d%02d%02d%02d%02dZ",
245 int(date
.year
% 10000), date
.month
, date
.day
,
246 date
.hour
, date
.minute
, int(date
.second
));
248 else if (inLength
== 14)
250 /* UTC - 2 year digits - code which parses this assumes that
251 * (2-digit) years between 0 and 49 are in century 21 */
252 sprintf((char *)(outData
), "%02d%02d%02d%02d%02d%02dZ",
253 int(date
.year
% 100), date
.month
, date
.day
,
254 date
.hour
, date
.minute
, int(date
.second
));
257 MacOSError::throwMe(paramErr
);
260 }; // end namespace CSSMDateTimeUtils
262 } // end namespace Security