122695Sdist /* 234920Sbostic * Copyright (c) 1983 Eric P. Allman 333728Sbostic * Copyright (c) 1988 Regents of the University of California. 433728Sbostic * All rights reserved. 533728Sbostic * 633728Sbostic * Redistribution and use in source and binary forms are permitted 734920Sbostic * provided that the above copyright notice and this paragraph are 834920Sbostic * duplicated in all such forms and that any documentation, 934920Sbostic * advertising materials, and other materials related to such 1034920Sbostic * distribution and use acknowledge that the software was developed 1134920Sbostic * by the University of California, Berkeley. The name of the 1234920Sbostic * University may not be used to endorse or promote products derived 1334920Sbostic * from this software without specific prior written permission. 1434920Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1534920Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1634920Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1733728Sbostic */ 1822695Sdist 1922695Sdist #ifndef lint 20*36529Sbostic static char sccsid[] = "@(#)arpadate.c 5.10 (Berkeley) 01/08/89"; 2133728Sbostic #endif /* not lint */ 2222695Sdist 239152Seric # include "conf.h" 2416895Seric # include <time.h> 252897Seric # include <sys/types.h> 264437Seric # include "useful.h" 27293Seric 28293Seric /* 29293Seric ** ARPADATE -- Create date in ARPANET format 30293Seric ** 31293Seric ** Parameters: 322897Seric ** ud -- unix style date string. if NULL, one is created. 33293Seric ** 34293Seric ** Returns: 35293Seric ** pointer to an ARPANET date field 36293Seric ** 37293Seric ** Side Effects: 38293Seric ** none 39293Seric ** 40293Seric ** WARNING: 41293Seric ** date is stored in a local buffer -- subsequent 42293Seric ** calls will overwrite. 433185Seric ** 443185Seric ** Bugs: 453185Seric ** Timezone is computed from local time, rather than 463185Seric ** from whereever (and whenever) the message was sent. 473185Seric ** To do better is very hard. 484315Seric ** 494315Seric ** Some sites are now inserting the timezone into the 504315Seric ** local date. This routine should figure out what 514315Seric ** the format is and work appropriately. 52293Seric */ 53293Seric 541586Seric char * 552897Seric arpadate(ud) 562897Seric register char *ud; 57293Seric { 58293Seric register char *p; 592897Seric register char *q; 60*36529Sbostic register int off; 61*36529Sbostic register int i; 62*36529Sbostic register struct tm *lt; 63*36529Sbostic time_t t; 64*36529Sbostic struct tm gmt; 65293Seric static char b[40]; 66*36529Sbostic extern struct tm *localtime(), *gmtime(); 671586Seric extern char *ctime(); 68*36529Sbostic extern time_t time(); 69293Seric 704315Seric /* 714315Seric ** Get current time. 724315Seric ** This will be used if a null argument is passed and 734315Seric ** to resolve the timezone. 744315Seric */ 754315Seric 764315Seric (void) time(&t); 772897Seric if (ud == NULL) 782897Seric ud = ctime(&t); 79293Seric 804315Seric /* 814315Seric ** Crack the UNIX date line in a singularly unoriginal way. 824315Seric */ 834315Seric 842897Seric q = b; 852897Seric 8613932Seric p = &ud[0]; /* Mon */ 8713932Seric *q++ = *p++; 8813932Seric *q++ = *p++; 8913932Seric *q++ = *p++; 9013932Seric *q++ = ','; 9113932Seric *q++ = ' '; 9213932Seric 93293Seric p = &ud[8]; /* 16 */ 94293Seric if (*p == ' ') 95293Seric p++; 962897Seric else 972897Seric *q++ = *p++; 982897Seric *q++ = *p++; 9910251Seric *q++ = ' '; 1002897Seric 1015184Seric p = &ud[4]; /* Sep */ 1025184Seric *q++ = *p++; 1035184Seric *q++ = *p++; 1045184Seric *q++ = *p++; 10510251Seric *q++ = ' '; 1062897Seric 10713932Seric p = &ud[22]; /* 79 */ 1085184Seric *q++ = *p++; 1095184Seric *q++ = *p++; 1102897Seric *q++ = ' '; 1112897Seric 1122897Seric p = &ud[11]; /* 01:03:52 */ 1135184Seric for (i = 8; i > 0; i--) 1142897Seric *q++ = *p++; 1152897Seric 116*36529Sbostic /* 117*36529Sbostic * should really get the timezone from the time in "ud" (which 118*36529Sbostic * is only different if a non-null arg was passed which is different 119*36529Sbostic * from the current time), but for all practical purposes, returning 120*36529Sbostic * the current local zone will do (its all that is ever needed). 121*36529Sbostic */ 122*36529Sbostic gmt = *gmtime(&t); 123*36529Sbostic lt = localtime(&t); 1242897Seric 125*36529Sbostic off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; 12615109Skarels 127*36529Sbostic /* assume that offset isn't more than a day ... */ 128*36529Sbostic if (lt->tm_year < gmt.tm_year) 129*36529Sbostic off -= 24 * 60; 130*36529Sbostic else if (lt->tm_year > gmt.tm_year) 131*36529Sbostic off += 24 * 60; 132*36529Sbostic else if (lt->tm_yday < gmt.tm_yday) 133*36529Sbostic off -= 24 * 60; 134*36529Sbostic else if (lt->tm_yday > gmt.tm_yday) 135*36529Sbostic off += 24 * 60; 13615109Skarels 137*36529Sbostic *q++ = ' '; 138*36529Sbostic if (off == 0) { 139*36529Sbostic *q++ = 'G'; 140*36529Sbostic *q++ = 'M'; 141*36529Sbostic *q++ = 'T'; 142*36529Sbostic } else { 143*36529Sbostic if (off < 0) { 144*36529Sbostic off = -off; 145*36529Sbostic *q++ = '-'; 146*36529Sbostic } else 147*36529Sbostic *q++ = '+'; 14815109Skarels 149*36529Sbostic if (off >= 24*60) /* should be impossible */ 150*36529Sbostic off = 23*60+59; /* if not, insert silly value */ 15115137Seric 152*36529Sbostic *q++ = (off / 600) + '0'; 153*36529Sbostic *q++ = (off / 60) % 10 + '0'; 154*36529Sbostic off %= 60; 155*36529Sbostic *q++ = (off / 10) + '0'; 156*36529Sbostic *q++ = (off % 10) + '0'; 15715137Seric } 158*36529Sbostic *q = '\0'; 159*36529Sbostic 160*36529Sbostic return (b); 16115109Skarels } 162