122695Sdist /* 234920Sbostic * Copyright (c) 1983 Eric P. Allman 333728Sbostic * Copyright (c) 1988 Regents of the University of California. 433728Sbostic * All rights reserved. 533728Sbostic * 642824Sbostic * %sccs.include.redist.c% 733728Sbostic */ 822695Sdist 922695Sdist #ifndef lint 10*56304Seric static char sccsid[] = "@(#)arpadate.c 5.13 (Berkeley) 09/21/92"; 1133728Sbostic #endif /* not lint */ 1222695Sdist 139152Seric # include "conf.h" 1416895Seric # include <time.h> 152897Seric # include <sys/types.h> 164437Seric # include "useful.h" 17293Seric 18293Seric /* 19293Seric ** ARPADATE -- Create date in ARPANET format 20293Seric ** 21293Seric ** Parameters: 222897Seric ** ud -- unix style date string. if NULL, one is created. 23293Seric ** 24293Seric ** Returns: 25293Seric ** pointer to an ARPANET date field 26293Seric ** 27293Seric ** Side Effects: 28293Seric ** none 29293Seric ** 30293Seric ** WARNING: 31293Seric ** date is stored in a local buffer -- subsequent 32293Seric ** calls will overwrite. 333185Seric ** 343185Seric ** Bugs: 353185Seric ** Timezone is computed from local time, rather than 363185Seric ** from whereever (and whenever) the message was sent. 373185Seric ** To do better is very hard. 384315Seric ** 394315Seric ** Some sites are now inserting the timezone into the 404315Seric ** local date. This routine should figure out what 414315Seric ** the format is and work appropriately. 42293Seric */ 43293Seric 441586Seric char * 452897Seric arpadate(ud) 462897Seric register char *ud; 47293Seric { 48293Seric register char *p; 492897Seric register char *q; 5036529Sbostic register int off; 5136529Sbostic register int i; 5236529Sbostic register struct tm *lt; 5336529Sbostic time_t t; 5436529Sbostic struct tm gmt; 55293Seric static char b[40]; 5636529Sbostic extern struct tm *localtime(), *gmtime(); 571586Seric extern char *ctime(); 5836529Sbostic extern time_t time(); 59293Seric 604315Seric /* 614315Seric ** Get current time. 624315Seric ** This will be used if a null argument is passed and 634315Seric ** to resolve the timezone. 644315Seric */ 654315Seric 664315Seric (void) time(&t); 672897Seric if (ud == NULL) 682897Seric ud = ctime(&t); 69293Seric 704315Seric /* 714315Seric ** Crack the UNIX date line in a singularly unoriginal way. 724315Seric */ 734315Seric 742897Seric q = b; 752897Seric 7613932Seric p = &ud[0]; /* Mon */ 7713932Seric *q++ = *p++; 7813932Seric *q++ = *p++; 7913932Seric *q++ = *p++; 8013932Seric *q++ = ','; 8113932Seric *q++ = ' '; 8213932Seric 83293Seric p = &ud[8]; /* 16 */ 84293Seric if (*p == ' ') 85293Seric p++; 862897Seric else 872897Seric *q++ = *p++; 882897Seric *q++ = *p++; 8910251Seric *q++ = ' '; 902897Seric 915184Seric p = &ud[4]; /* Sep */ 925184Seric *q++ = *p++; 935184Seric *q++ = *p++; 945184Seric *q++ = *p++; 9510251Seric *q++ = ' '; 962897Seric 97*56304Seric p = &ud[20]; /* 1979 */ 985184Seric *q++ = *p++; 995184Seric *q++ = *p++; 100*56304Seric *q++ = *p++; 101*56304Seric *q++ = *p++; 1022897Seric *q++ = ' '; 1032897Seric 1042897Seric p = &ud[11]; /* 01:03:52 */ 1055184Seric for (i = 8; i > 0; i--) 1062897Seric *q++ = *p++; 1072897Seric 10836529Sbostic /* 10936529Sbostic * should really get the timezone from the time in "ud" (which 11036529Sbostic * is only different if a non-null arg was passed which is different 11136529Sbostic * from the current time), but for all practical purposes, returning 11236529Sbostic * the current local zone will do (its all that is ever needed). 11336529Sbostic */ 11436529Sbostic gmt = *gmtime(&t); 11536529Sbostic lt = localtime(&t); 1162897Seric 11736529Sbostic off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; 11815109Skarels 11936529Sbostic /* assume that offset isn't more than a day ... */ 12036529Sbostic if (lt->tm_year < gmt.tm_year) 12136529Sbostic off -= 24 * 60; 12236529Sbostic else if (lt->tm_year > gmt.tm_year) 12336529Sbostic off += 24 * 60; 12436529Sbostic else if (lt->tm_yday < gmt.tm_yday) 12536529Sbostic off -= 24 * 60; 12636529Sbostic else if (lt->tm_yday > gmt.tm_yday) 12736529Sbostic off += 24 * 60; 12815109Skarels 12936529Sbostic *q++ = ' '; 13036529Sbostic if (off == 0) { 13136529Sbostic *q++ = 'G'; 13236529Sbostic *q++ = 'M'; 13336529Sbostic *q++ = 'T'; 13436529Sbostic } else { 13536529Sbostic if (off < 0) { 13636529Sbostic off = -off; 13736529Sbostic *q++ = '-'; 13836529Sbostic } else 13936529Sbostic *q++ = '+'; 14015109Skarels 14136529Sbostic if (off >= 24*60) /* should be impossible */ 14236529Sbostic off = 23*60+59; /* if not, insert silly value */ 14315137Seric 14436529Sbostic *q++ = (off / 600) + '0'; 14536529Sbostic *q++ = (off / 60) % 10 + '0'; 14636529Sbostic off %= 60; 14736529Sbostic *q++ = (off / 10) + '0'; 14836529Sbostic *q++ = (off % 10) + '0'; 14915137Seric } 15036529Sbostic *q = '\0'; 15136529Sbostic 15236529Sbostic return (b); 15315109Skarels } 154