FreeBSD/sys/fs/udf/udf_vnops.c
/*
 * Timezone calculation compliments of Julian Elischer <julian@elischer.org>.
 */
Timezone calculation compliments of Julian Elischer .
Timezone calculation compliments of Julian Elischer .
static void
udf_timetotimespec(struct timestamp *time, struct timespec *t)
{
	int i, lpyear, daysinyear, year, startyear;
	union {
		uint16_t	u_tz_offset;
		int16_t		s_tz_offset;
	} tz;
	year = le16toh(time->year);
	if (year < 1970 || time->month < 1 || time->month > 12) {
		t->tv_sec = 0;
		t->tv_nsec = 0;
		return;
	}
	t->tv_sec = time->second;
	t->tv_sec += time->minute * 60;
	t->tv_sec += time->hour * 3600;
	t->tv_sec += (time->day - 1) * 3600 * 24;
	lpyear = udf_isaleapyear(year);
	t->tv_sec += mon_lens[lpyear][time->month - 1] * 3600 * 24;
	startyear = 1970;
	if (year > 2009) {
		t->tv_sec += 1262304000;
		startyear += 40;
	} else if (year > 1999) {
		t->tv_sec += 946684800;
		startyear += 30;
	} else if (year > 1989) {
		t->tv_sec += 631152000;
		startyear += 20;
	} else if (year > 1979) {
		t->tv_sec += 315532800;
		startyear += 10;
	}
	daysinyear = (year - startyear) * 365;
	for (i = startyear; i < year; i++)
		daysinyear += udf_isaleapyear(i);
	t->tv_sec += daysinyear * 3600 * 24;
	t->tv_nsec = time->centisec * 10000 + time->hund_usec * 100 +
	    time->usec;
	tz.u_tz_offset = le16toh(time->type_tz);
	tz.u_tz_offset &= 0x0fff;
	if (tz.u_tz_offset & 0x0800)
		tz.u_tz_offset |= 0xf000;	
	if ((le16toh(time->type_tz) & 0x1000) && (tz.s_tz_offset != -2047))
		t->tv_sec -= tz.s_tz_offset * 60;
	return;
}
static void udf_timetotimespec ( struct timestamp * time , struct timespec * t ) { int i , lpyear , daysinyear , year , startyear ; union { uint16_t u_tz_offset ; int16_t s_tz_offset ; } tz ; year = le16toh ( time -> year ) ; if ( year < 1970 || time -> month < 1 || time -> month > 12 ) { t -> tv_sec = 0 ; t -> tv_nsec = 0 ; return ; } t -> tv_sec = time -> second ; t -> tv_sec += time -> minute * 60 ; t -> tv_sec += time -> hour * 3600 ; t -> tv_sec += ( time -> day - 1 ) * 3600 * 24 ; lpyear = udf_isaleapyear ( year ) ; t -> tv_sec += mon_lens [ lpyear ] [ time -> month - 1 ] * 3600 * 24 ; startyear = 1970 ; if ( year > 2009 ) { t -> tv_sec += 1262304000 ; startyear += 40 ; } else if ( year > 1999 ) { t -> tv_sec += 946684800 ; startyear += 30 ; } else if ( year > 1989 ) { t -> tv_sec += 631152000 ; startyear += 20 ; } else if ( year > 1979 ) { t -> tv_sec += 315532800 ; startyear += 10 ; } daysinyear = ( year - startyear ) * 365 ; for ( i = startyear ; i < year ; i ++ ) daysinyear += udf_isaleapyear ( i ) ; t -> tv_sec += daysinyear * 3600 * 24 ; t -> tv_nsec = time -> centisec * 10000 + time -> hund_usec * 100 + time -> usec ; tz . u_tz_offset = le16toh ( time -> type_tz ) ; tz . u_tz_offset &= 0x0fff ; if ( tz . u_tz_offset & 0x0800 ) tz . u_tz_offset |= 0xf000 ; if ( ( le16toh ( time -> type_tz ) & 0x1000 ) && ( tz . s_tz_offset != -2047 ) ) t -> tv_sec -= tz . s_tz_offset * 60 ; return ; }
Timezone calculation compliments of Julian Elischer <julian@elischer.org>.
Timezone calculation compliments of Julian Elischer <julian@elischer . org > .
/*
	 * DirectCD seems to like using bogus year values.
	 * Don't trust time->month as it will be used for an array index.
	 */ /* Calculate the time and day */ /* Calculate the month */ /* Speed up the calculation */ /* Calculate microseconds */ /*
	 * Calculate the time zone.  The timezone is 12 bit signed 2's
	 * complement, so we gotta do some extra magic to handle it right.
	 */ /* extend the sign to 16 bits */