1 /* 2 * Copyright (c) 1983 Eric P. Allman 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)arpadate.c 5.13 (Berkeley) 09/21/92"; 11 #endif /* not lint */ 12 13 # include "conf.h" 14 # include <time.h> 15 # include <sys/types.h> 16 # include "useful.h" 17 18 /* 19 ** ARPADATE -- Create date in ARPANET format 20 ** 21 ** Parameters: 22 ** ud -- unix style date string. if NULL, one is created. 23 ** 24 ** Returns: 25 ** pointer to an ARPANET date field 26 ** 27 ** Side Effects: 28 ** none 29 ** 30 ** WARNING: 31 ** date is stored in a local buffer -- subsequent 32 ** calls will overwrite. 33 ** 34 ** Bugs: 35 ** Timezone is computed from local time, rather than 36 ** from whereever (and whenever) the message was sent. 37 ** To do better is very hard. 38 ** 39 ** Some sites are now inserting the timezone into the 40 ** local date. This routine should figure out what 41 ** the format is and work appropriately. 42 */ 43 44 char * 45 arpadate(ud) 46 register char *ud; 47 { 48 register char *p; 49 register char *q; 50 register int off; 51 register int i; 52 register struct tm *lt; 53 time_t t; 54 struct tm gmt; 55 static char b[40]; 56 extern struct tm *localtime(), *gmtime(); 57 extern char *ctime(); 58 extern time_t time(); 59 60 /* 61 ** Get current time. 62 ** This will be used if a null argument is passed and 63 ** to resolve the timezone. 64 */ 65 66 (void) time(&t); 67 if (ud == NULL) 68 ud = ctime(&t); 69 70 /* 71 ** Crack the UNIX date line in a singularly unoriginal way. 72 */ 73 74 q = b; 75 76 p = &ud[0]; /* Mon */ 77 *q++ = *p++; 78 *q++ = *p++; 79 *q++ = *p++; 80 *q++ = ','; 81 *q++ = ' '; 82 83 p = &ud[8]; /* 16 */ 84 if (*p == ' ') 85 p++; 86 else 87 *q++ = *p++; 88 *q++ = *p++; 89 *q++ = ' '; 90 91 p = &ud[4]; /* Sep */ 92 *q++ = *p++; 93 *q++ = *p++; 94 *q++ = *p++; 95 *q++ = ' '; 96 97 p = &ud[20]; /* 1979 */ 98 *q++ = *p++; 99 *q++ = *p++; 100 *q++ = *p++; 101 *q++ = *p++; 102 *q++ = ' '; 103 104 p = &ud[11]; /* 01:03:52 */ 105 for (i = 8; i > 0; i--) 106 *q++ = *p++; 107 108 /* 109 * should really get the timezone from the time in "ud" (which 110 * is only different if a non-null arg was passed which is different 111 * from the current time), but for all practical purposes, returning 112 * the current local zone will do (its all that is ever needed). 113 */ 114 gmt = *gmtime(&t); 115 lt = localtime(&t); 116 117 off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; 118 119 /* assume that offset isn't more than a day ... */ 120 if (lt->tm_year < gmt.tm_year) 121 off -= 24 * 60; 122 else if (lt->tm_year > gmt.tm_year) 123 off += 24 * 60; 124 else if (lt->tm_yday < gmt.tm_yday) 125 off -= 24 * 60; 126 else if (lt->tm_yday > gmt.tm_yday) 127 off += 24 * 60; 128 129 *q++ = ' '; 130 if (off == 0) { 131 *q++ = 'G'; 132 *q++ = 'M'; 133 *q++ = 'T'; 134 } else { 135 if (off < 0) { 136 off = -off; 137 *q++ = '-'; 138 } else 139 *q++ = '+'; 140 141 if (off >= 24*60) /* should be impossible */ 142 off = 23*60+59; /* if not, insert silly value */ 143 144 *q++ = (off / 600) + '0'; 145 *q++ = (off / 60) % 10 + '0'; 146 off %= 60; 147 *q++ = (off / 10) + '0'; 148 *q++ = (off % 10) + '0'; 149 } 150 *q = '\0'; 151 152 return (b); 153 } 154