PPERT part 2: the d2d routine
VanRietschote
jchvr at ihlpg.UUCP
Wed Apr 30 00:05:14 AEST 1986
# cut here file=d2d1.c
/*
* D2D
*
* APT date to date converter
*
*/
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <string.h>
#undef NULL;
#define NULL 0
#define EOS 0
#define FALSE 0
#define TRUE 1
#define DECENIUM 1980
#define MONDAY 0
#define TUESDAY 1
#define WEDNESDAY 2
#define THURSDAY 3
#define FRIDAY 4
#define SATURDAY 5
#define SUNDAY 6
int ERROR ; /* global error number */
/* 0=okay */
/* 1=err in inf */
/* 2=err in in */
/* 3=err in outf*/
int day_month[] = {
0,31,28,31,30,31,30,31,31,30,31,30,31
};
static char *monthnames[] = {
"??",
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
"???",
};
static char *daynames[] = {
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
"???",
};
char *INFORMAT = "-%y%m%d";
char *OUTFORMAT = "+%a %h %d 19%y%n";
int year;
int month;
int day;
int week;
int weekday;
char line[100];
char word[10];
char *valptr;
char *informat;
char *outformat;
char *formptr;
char *OUT;
char TEMP[512];
/*
* dotextline processes the inputstring
*
*/
dotextline(text)
char *text;
{
valptr = text;
formptr = informat + 1;
year = month = day = week = weekday = -1;
while ((*valptr != '\0') && (*formptr != '\0')) {
while ((*valptr == *formptr) && (*formptr !='%')) {
valptr++;
formptr++;
}
if (*formptr == '%') {
if ((do_in_command())) {
print_inform_error(text);
return(TRUE);
}
}
else {
print_inform_error(text);
return(TRUE);
}
}
if ((*valptr != '\0') || (*formptr != '\0')) {
print_inform_error(text);
return(TRUE);
}
print_date();
return(FALSE);
}
/*
*
* error during input processing
*
*/
print_inform_error(text)
char *text;
{
ERROR=1; /* bad inf */
*valptr = '\0';
return(1);
}
/*
*
* do all input % commands
*
*/
do_in_command()
{
int length;
int status;
formptr++;
length = (is_digit(*formptr)) ? (*formptr++ - '0') : -1;
switch (*formptr++) {
case 'd' :
status = getval(&day,0,31,rlength(2,length));
break;
case 'm' :
status = getval(&month,1,12,rlength(2,length));
break;
case 'h' :
status = getmonthname(rlength(3,length));
break;
case 'y' :
status = getval(&year,00,99,rlength(2,length));
year += 1900;
break;
case 'j' :
status = getval(&week,001,953,rlength(3,length));
break;
case 'w' :
status = getval(&weekday,0,6,rlength(1,length));
break;
case 'a' :
status = getweekdayname(rlength(3,length));
break;
case '.' :
valptr++;
status = 0;
break;
case '*' :
while (*valptr && (*formptr != *valptr++))
status = 0;
formptr++;
break;
case '%' :
status = (*valptr++ == *formptr++) ? FALSE : TRUE;
break;
default :
status = TRUE;
}
return (status);
}
/*
* Get current date from UNIX
*
*/
do_date()
{
int tvec[2];
struct tm *localtime();
struct tm *p;
time(tvec);
p = localtime(tvec);
year = p -> tm_year + 1900;
month = p -> tm_mon + 1;
day = p -> tm_mday;
}
/*
* output processing of the date
*
*/
print_date()
{
if ((year == -1) && (month == -1) && (day == -1) &&
(week != -1) && (weekday != -1)) {
weekday = (weekday == 0) ? 6 : weekday-1;
proces_week(week,weekday);
}
else {
if ((year != -1) && (month != -1) && (day != -1)) {
proces_date(year,month,day);
}
else { ERROR=2; /* bad in */
return(TRUE);
}
}
formptr = outformat + 1;
while (*formptr != '\0') {
if (*formptr == '%') {
if (do_out_command()) {
ERROR=3; /* bad outf */
return(TRUE);
}
}
else { sprintf(TEMP,"%c",*formptr++);
strcat(OUT,TEMP);
}
}
}
do_out_command()
{
int length;
int status;
formptr++;
status = 0;
length = (is_digit(*formptr)) ? (*formptr++ -'0') : -1;
switch(*formptr++) {
case 'd' :
status = putval(day,rlength(2,length));
break;
case 'm' :
status = putval(month,rlength(2,length));
break;
case 'h' :
status = putstr(monthnames[month],
rlength(3,length));
break;
case 'y' :
year = year - ((year / 100) * 100 );
status = putval(year,rlength(2,length));
break;
case 'j' :
status = putval(week,rlength(2,length));
break;
case 'w' :
status = putval(weekday,rlength(2,length));
break;
case 'a' :
status = putstr(daynames[weekday],
rlength(3,length));
break;
case 'n' :
strcat(OUT,"\n");
break;
case 't' :
strcat(OUT,"\t");
break;
case '%' :
strcat(OUT,"%");
break;
default :
status = TRUE;
}
return(status);
}
/*
* determine the weeknumber and weekday
* for the given year,month and day
*
*/
proces_date(year,month,day)
int year;
int month;
int day;
{
int temp;
int week_no;
week_no = get_weeknumber(year,month,day);
temp = (year - (10 * (year / 10)));
if ((month == 1) && ((day == 1) || (day == 2))) {
if ((day == 2) && (dayofweek(year,month,day) == SUNDAY)) {
year += -1;
week_no = get_weeknumber(year,12,31);
temp += -1;
}
else {
if ((day == 1) &&
((dayofweek(year,month,day) == SATURDAY) ||
(dayofweek(year,month,day) == SUNDAY))) {
year += -1;
week_no = get_weeknumber(year,12,31);
temp += -1;
}
}
}
if ((week_no >= 53) && (dayofweek(year,12,31) < FRIDAY)) {
temp++;
week_no = 1;
}
week = temp * 100 + week_no;
weekday = dayofweek(year,month,day);
}
/*
*
* determine the weeknumber without under- &
* overflow detection
*/
get_weeknumber(year,month,day)
int year;
int month;
int day;
{
int i;
int week_no;
int no_days;
int leapyear;
int rest;
leapyear = ((year%4) == 0) && (((year%400) == 0) || (year%100 != 0));
no_days = 0;
for (i=1; i < month; i++) {
no_days += ((i == 2 && leapyear) ? 29 : day_month[i]);
}
no_days += (day - 1);
week_no = (no_days / 7);
rest = no_days - (week_no * 7);
week_no += 1;
if (dayofweek(year,1,1) > FRIDAY) week_no += -1;
if ((dayofweek(year,month,day) -rest) <= MONDAY) week_no +=1;
return(week_no);
}
/*
*
* determine the date (year,month and day)
* from a given weeknumver and weekday
*
*/
proces_week(week,weekday)
int week;
int weekday;
{
int leapyear;
int mark;
year = DECENIUM + (week / 100);
week = week - (week / 100) * 100;
leapyear = ((year %4 == 0) && (((year %400) == 0) || (year%100 != 0)));
day = (week - 1) * 7 + weekday - dayofweek(year,1,1);
if (day < 0) {
month = 12;
year--;
day = day + 32;
}
else
{
for (month = 1; day > 0; month++) {
day -= ((month == 2 && leapyear) ? 29 :
day_month[month]);
}
month--;
day += day_month[month] +1;
month = (month == 0) ? 1 : month;
}
mark = FALSE;
if (day > day_month[month]) {
day -= day_month[month++];
if (month > 12) {
month = 1;
year++;
mark = TRUE;
}
}
if ((mark == TRUE) && (month == 1) &&
(dayofweek(year,month,day) <= FRIDAY)) {
return(TRUE);
}
return(FALSE);
}
/*
* determine the weekday from a given date
* day of the week : Sunday = 6, Monday = 0
*
*/
dayofweek(year,month,day)
int year;
int month;
int day;
{
register int yearfactor;
int dow;
yearfactor = year + (month - 14)/12;
dow = (( (13 * (month + 10 - (month + 10)/13*12) -1)/5
+ day + 77 + 5 * (yearfactor % 100)/4
+ yearfactor / 400
- yearfactor / 100 * 2) % 7);
return ( (dow == 0) ? 6 : --dow);
}
/*
*
* read the monthname from input
*
*/
getmonthname(length)
int length;
{
int l;
getstr(length);
for (month=1; month<13; month++) {
for (l=0; ((l<length) &&
(word[l] == monthnames[month][l])); l++);
if (l == length) break;
}
return ((month == 13) ? TRUE : FALSE);
}
/*
*
* read the weekday from input
*
*/
getweekdayname(length)
int length;
{
int l;
getstr(length);
for (weekday = 0; (weekday <=7); weekday++) {
for (l = 0; ((l<length) &&
(word[l] == daynames[weekday][l])); l++);
if (l == length) break;
}
if (weekday == 8) return(TRUE);
weekday = ++weekday%7;
return (FALSE);
}
/*
* return 1e param value if 2nd = -1
* else 2nd param.
*
*/
rlength(p1,p2)
int p1;
int p2;
{
return( (p2 == -1) ? p1 : p2);
}
/*
*
* Read text to global line[].
*
*/
getline()
{
register char *t;
return (gets(line) == NULL);
}
/*
*
* read a value from the inputstring
* given a low and high bound
* given a max. length of the number
* given a following delimite
*
*/
getval(value,low,high,length)
int *value;
int low;
int high;
int length;
{
register int i;
register int temp;
if (*valptr == '\0') return(TRUE);
while (*valptr && (*valptr == ' ')) *valptr++;
for (*value = i = 0;((i < length) && (is_digit(*valptr))); i++) {
temp = *valptr++ - '0';
if (temp < 0 || temp > 9) return(TRUE);
*value = (*value * 10) + temp;
}
return((*value >= low && *value <= high) ? FALSE : TRUE);
}
/*
* read a string of a given length
*
*/
getstr(length)
int length;
{
int i;
for (i=0; i < length ; i++) {
word[i] = *valptr++;
}
word[i]='\0';
}
putval(value,length)
int value;
int length;
{
char *form = "%02d";
form[2] = length + '0';
sprintf(TEMP,form,value);
strcat(OUT,TEMP);
return(0);
}
putstr(string,length)
char *string;
int length;
{
char *form = "%3s";
form[1] = length + '0';
sprintf(TEMP,form,string);
strcat(OUT,TEMP);
return(0);
}
is_digit(digit)
char digit;
{
return (((digit < '0') || (digit > '9')) ? FALSE : digit);
}
/* ETERNAL CALLABLE ROUTINES */
int d2d(inf,in,outf,out)
char *inf; /* informat must start with - */
char *in; /* instring with format as in inf */
char *outf; /* outformat must start with +*/
char *out; /* will hold output must be large enough */
/* return ERROR = 0 if all ok
/* ERROR = 1 if error in inf
/* ERROR = 2 if error in in
/* ERROR = 3 if error in outf */
{
ERROR = 0;
OUT = out; /* initialize out */
strcpy(OUT,"");
informat = inf;
outformat = outf;
dotextline(in);
return(ERROR);
}
More information about the Comp.sources.unix
mailing list