ObjFW  Check-in [4fc7884fb1]

Overview
Comment:Parse struct tm ourselves.

This way, we don't need tm_gmtoff, which we would otherwise need to
adjust the value parsed by mktime, and don't need timegm either.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 4fc7884fb12c7b001f037a7aa688e7e37b16add77d41113b2f39380b1d30856c
User & Date: js on 2011-10-28 21:30:36
Other Links: manifest | tags
Context
2011-10-28
22:03
Fix leap year calculation. check-in: f5c8495a33 user: js tags: trunk
21:30
Parse struct tm ourselves. check-in: 4fc7884fb1 user: js tags: trunk
18:32
Release the OFApplication delegate in the atexit handler. check-in: fc200bb14a user: js tags: trunk
Changes

Modified configure.ac from [fb7f68dd03] to [fb0eab47f6].

457
458
459
460
461
462
463














464
465
466
467
468
469
470

AC_CHECK_FUNC(gmtime_r, [
	AC_DEFINE(HAVE_GMTIME_R, 1, [Whether we have gmtime_r])
])
AC_CHECK_FUNC(localtime_r, [
	AC_DEFINE(HAVE_LOCALTIME_R, 1, [Whether we have localtime_r])
])















AC_CHECK_FUNC(kqueue, [
	AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue])
	AC_SUBST(OFSTREAMOBSERVER_KQUEUE_M, "OFStreamObserver_kqueue.m")
])
AC_CHECK_HEADER(poll.h, [
	AC_DEFINE(HAVE_POLL_H, 1, [Whether we have poll.h])







>
>
>
>
>
>
>
>
>
>
>
>
>
>







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

AC_CHECK_FUNC(gmtime_r, [
	AC_DEFINE(HAVE_GMTIME_R, 1, [Whether we have gmtime_r])
])
AC_CHECK_FUNC(localtime_r, [
	AC_DEFINE(HAVE_LOCALTIME_R, 1, [Whether we have localtime_r])
])

AC_MSG_CHECKING(for tm_gmtoff in struct tm)
AC_TRY_COMPILE([
	#define _GNU_SOURCE
	#include <time.h>
], [
	struct tm tm;
	tm.tm_gmtoff = 0;
], [
	AC_DEFINE(STRUCT_TM_HAS_TM_GMTOFF, 1, [Whether struct tm has tm_gmtoff])
	AC_MSG_RESULT(yes)
], [
	AC_MSG_RESULT(no)
])

AC_CHECK_FUNC(kqueue, [
	AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue])
	AC_SUBST(OFSTREAMOBSERVER_KQUEUE_M, "OFStreamObserver_kqueue.m")
])
AC_CHECK_HEADER(poll.h, [
	AC_DEFINE(HAVE_POLL_H, 1, [Whether we have poll.h])

Modified src/OFDate.m from [03b1ee2aba] to [396325df1e].

129
130
131
132
133
134
135















136
137
138
139
140
141
142
									\
	if ((tm = localtime(&seconds_)) == NULL)			\
		@throw [OFOutOfRangeException exceptionWithClass: isa];	\
									\
	return tm->field;
# endif
#endif
















@implementation OFDate
#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_THREADS)
+ (void)initialize
{
	if (self == [OFDate class])







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
									\
	if ((tm = localtime(&seconds_)) == NULL)			\
		@throw [OFOutOfRangeException exceptionWithClass: isa];	\
									\
	return tm->field;
# endif
#endif

static int month_to_day_of_year[12] = {
	31,
	31 + 28,
	31 + 28 + 31,
	31 + 28 + 31 + 30,
	31 + 28 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
};

@implementation OFDate
#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_THREADS)
+ (void)initialize
{
	if (self == [OFDate class])
230
231
232
233
234
235
236

237
238
239

240

241




242
243
244



245




246
247
248
249
250
251
252
		tm.tm_isdst = -1;

		if (strptime([string UTF8String], [format UTF8String],
		    &tm) == NULL)
			@throw [OFInvalidFormatException
			    exceptionWithClass: isa];


		if (tm.tm_gmtoff)
			@throw [OFInvalidFormatException
			    exceptionWithClass: isa];



		if ((seconds = mktime(&tm)) == -1)




			@throw [OFInvalidFormatException
			    exceptionWithClass: isa];




		seconds += tm.tm_gmtoff;




	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}







>
|


>

>
|
>
>
>
>


|
>
>
>
|
>
>
>
>







245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
		tm.tm_isdst = -1;

		if (strptime([string UTF8String], [format UTF8String],
		    &tm) == NULL)
			@throw [OFInvalidFormatException
			    exceptionWithClass: isa];

#ifdef STRUCT_TM_HAS_TM_GMTOFF
		if (tm.tm_gmtoff != 0)
			@throw [OFInvalidFormatException
			    exceptionWithClass: isa];
#endif

		/* Years */
		seconds = (tm.tm_year - 70) * 31536000;
		/* Leap years */
		seconds += ((tm.tm_year / 4) - 17) * 86400;
		/* Months */
		if (tm.tm_mon < 0 || tm.tm_mon > 12)
			@throw [OFInvalidFormatException
			    exceptionWithClass: isa];
		seconds += month_to_day_of_year[tm.tm_mon - 1] * 86400;
		/* Days */
		seconds += (tm.tm_mday - 1) * 86400;
		/* Hours */
		seconds += tm.tm_hour * 3600;
		/* Minutes */
		seconds += tm.tm_min * 60;
		/* Seconds */
		seconds += tm.tm_sec;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}