/*- * $Id: date.c,v 1.2 90/02/03 17:00:25 Rhialto Exp $ * $Log: date.c,v $ * Revision 1.2 90/02/03 17:00:25 Rhialto * 0x21 -> DATE_MIN * * Revision 1.1 89/12/17 20:03:37 Rhialto * Initial revision * * DATE.C * * Two date conversion routines: DateStamp <-> MSDOS date/time. * * This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May * not be used or copied without a licence. */ #include #include "han.h" #define BASEYEAR 1978 #define DAYS_PER_YEAR 365 #define HOURS_PER_DAY 24 #define MINUTES_PER_HOUR 60 #define SECONDS_PER_MINUTE 60 #define DAYS_PER_WEEK 7 #define MONTHS_PER_YEAR 12 #define MINUTES_PER_DAY (MINUTES_PER_HOUR * HOURS_PER_DAY) #define SECONDS_PER_DAY ((long) SECONDS_PER_MINUTE * \ MINUTES_PER_HOUR * HOURS_PER_DAY) #define LeapYear(year) ((year & 3) == 0) /* From 1-Mar-1901 to 28-Feb-2100 */ int daycount[MONTHS_PER_YEAR] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; void ToDateStamp(datestamp, date, time) struct DateStamp *datestamp; word date; word time; { { int hours, minutes, seconds; seconds = (time & 31) * 2; time >>= 5; minutes = time & 63; time >>= 6; hours = time; datestamp->ds_Minute = MINUTES_PER_HOUR * hours + minutes; datestamp->ds_Tick = TICKS_PER_SECOND * seconds; } { ulong i, j, t; int year, month, day; if (date < DATE_MIN) date = DATE_MIN; day = date & 31; date >>= 5; month = (date & 15) - 1; date >>= 4; year = date + 1980; if ((unsigned)month > 11 || (unsigned)day > (unsigned)daycount[month]) { day = 31; month = 11; year = 1979; } j = year - BASEYEAR; /* Get the next lower full leap period (4 years and a day) since ... */ t = (year - BASEYEAR) & ~3; i = t; t = (t / 4) * (4 * DAYS_PER_YEAR + 1); /* t now is the number of days in 4 whole years since ... */ /*dbprintf(("ly0: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/ while (i < j) { /*dbprintf(("ly1: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/ t += DAYS_PER_YEAR; if (LeapYear(i + BASEYEAR)) { /*dbprintf(("leap year\n"));*/ t++; } i++; } /* t now is the number of days in whole years since ... */ /*dbprintf(("m0: i=%ld j=%ld t=%ld\n", i, j, t));*/ for (i = 0; i < month; i++) { /*dbprintf(("m1: i=%ld j=%ld t=%ld\n", i, j, t));*/ t += daycount[i]; if (i == 1 && LeapYear(year)) { t++; } } /* t now is the number of days in whole months since ... */ t += day - 1; /* t now is the number of days in whole days since ... */ datestamp->ds_Days = t; } } void ToMSDate(date, time, datestamp) word *date; word *time; register struct DateStamp *datestamp; { { word hours, minutes, seconds; hours = datestamp->ds_Minute / MINUTES_PER_HOUR; minutes = datestamp->ds_Minute % MINUTES_PER_HOUR; seconds = datestamp->ds_Tick / TICKS_PER_SECOND; *time = (hours << 11) | (minutes << 5) | (seconds / 2); } { register long days, i, t; int year, month, day; days = datestamp->ds_Days; year = BASEYEAR + (days/(4*DAYS_PER_YEAR+1)) * 4; days %= 4 * DAYS_PER_YEAR + 1; while (days) { t = DAYS_PER_YEAR; if (LeapYear(year)) t++; if (days < t) break; days -= t; year++; } days++; for (i = 0; i < MONTHS_PER_YEAR; i++) { t = daycount[i]; if (i == 1 && LeapYear(year)) t++; if (days <= t) break; days -= t; } month = i + 1; day = days; *date = ((year - 1980) << 9) | (month << 5) | day; } }