122695Sdist /* 234920Sbostic * Copyright (c) 1983 Eric P. Allman 333728Sbostic * Copyright (c) 1988 Regents of the University of California. 433728Sbostic * All rights reserved. 533728Sbostic * 6*42824Sbostic * %sccs.include.redist.c% 733728Sbostic */ 822695Sdist 922695Sdist #ifndef lint 10*42824Sbostic static char sccsid[] = "@(#)arpadate.c 5.11 (Berkeley) 06/01/90"; 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 9713932Seric p = &ud[22]; /* 79 */ 985184Seric *q++ = *p++; 995184Seric *q++ = *p++; 1002897Seric *q++ = ' '; 1012897Seric 1022897Seric p = &ud[11]; /* 01:03:52 */ 1035184Seric for (i = 8; i > 0; i--) 1042897Seric *q++ = *p++; 1052897Seric 10636529Sbostic /* 10736529Sbostic * should really get the timezone from the time in "ud" (which 10836529Sbostic * is only different if a non-null arg was passed which is different 10936529Sbostic * from the current time), but for all practical purposes, returning 11036529Sbostic * the current local zone will do (its all that is ever needed). 11136529Sbostic */ 11236529Sbostic gmt = *gmtime(&t); 11336529Sbostic lt = localtime(&t); 1142897Seric 11536529Sbostic off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; 11615109Skarels 11736529Sbostic /* assume that offset isn't more than a day ... */ 11836529Sbostic if (lt->tm_year < gmt.tm_year) 11936529Sbostic off -= 24 * 60; 12036529Sbostic else if (lt->tm_year > gmt.tm_year) 12136529Sbostic off += 24 * 60; 12236529Sbostic else if (lt->tm_yday < gmt.tm_yday) 12336529Sbostic off -= 24 * 60; 12436529Sbostic else if (lt->tm_yday > gmt.tm_yday) 12536529Sbostic off += 24 * 60; 12615109Skarels 12736529Sbostic *q++ = ' '; 12836529Sbostic if (off == 0) { 12936529Sbostic *q++ = 'G'; 13036529Sbostic *q++ = 'M'; 13136529Sbostic *q++ = 'T'; 13236529Sbostic } else { 13336529Sbostic if (off < 0) { 13436529Sbostic off = -off; 13536529Sbostic *q++ = '-'; 13636529Sbostic } else 13736529Sbostic *q++ = '+'; 13815109Skarels 13936529Sbostic if (off >= 24*60) /* should be impossible */ 14036529Sbostic off = 23*60+59; /* if not, insert silly value */ 14115137Seric 14236529Sbostic *q++ = (off / 600) + '0'; 14336529Sbostic *q++ = (off / 60) % 10 + '0'; 14436529Sbostic off %= 60; 14536529Sbostic *q++ = (off / 10) + '0'; 14636529Sbostic *q++ = (off % 10) + '0'; 14715137Seric } 14836529Sbostic *q = '\0'; 14936529Sbostic 15036529Sbostic return (b); 15115109Skarels } 152