strptime.c revision 28019
128019Sjoerg/* 228019Sjoerg * Copyright (c) 1994 Powerdog Industries. All rights reserved. 328019Sjoerg * 428019Sjoerg * Redistribution and use in source and binary forms, without 528019Sjoerg * modification, are permitted provided that the following conditions 628019Sjoerg * are met: 728019Sjoerg * 1. Redistributions of source code must retain the above copyright 828019Sjoerg * notice, this list of conditions and the following disclaimer. 928019Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 1028019Sjoerg * notice, this list of conditions and the following disclaimer 1128019Sjoerg * in the documentation and/or other materials provided with the 1228019Sjoerg * distribution. 1328019Sjoerg * 3. All advertising materials mentioning features or use of this 1428019Sjoerg * software must display the following acknowledgement: 1528019Sjoerg * This product includes software developed by Powerdog Industries. 1628019Sjoerg * 4. The name of Powerdog Industries may not be used to endorse or 1728019Sjoerg * promote products derived from this software without specific prior 1828019Sjoerg * written permission. 1928019Sjoerg * 2028019Sjoerg * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY 2128019Sjoerg * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2228019Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2328019Sjoerg * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE 2428019Sjoerg * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2528019Sjoerg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2628019Sjoerg * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 2728019Sjoerg * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2828019Sjoerg * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 2928019Sjoerg * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 3028019Sjoerg * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3128019Sjoerg */ 3228019Sjoerg 3328019Sjoerg#ifndef lint 3428019Sjoergstatic char copyright[] = 3528019Sjoerg"@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; 3628019Sjoergstatic char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; 3728019Sjoerg#endif /* not lint */ 3828019Sjoerg 3928019Sjoerg#include <time.h> 4028019Sjoerg#include <ctype.h> 4128019Sjoerg#include <locale.h> 4228019Sjoerg#include <string.h> 4328019Sjoerg 4428019Sjoerg#define asizeof(a) (sizeof (a) / sizeof ((a)[0])) 4528019Sjoerg 4628019Sjoerg/* #ifndef sun */ 4728019Sjoergstruct dtconv { 4828019Sjoerg char *abbrev_month_names[12]; 4928019Sjoerg char *month_names[12]; 5028019Sjoerg char *abbrev_weekday_names[7]; 5128019Sjoerg char *weekday_names[7]; 5228019Sjoerg char *time_format; 5328019Sjoerg char *sdate_format; 5428019Sjoerg char *dtime_format; 5528019Sjoerg char *am_string; 5628019Sjoerg char *pm_string; 5728019Sjoerg char *ldate_format; 5828019Sjoerg}; 5928019Sjoerg/* #endif */ 6028019Sjoerg 6128019Sjoergstatic struct dtconv En_US = { 6228019Sjoerg { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 6328019Sjoerg "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }, 6428019Sjoerg { "January", "February", "March", "April", 6528019Sjoerg "May", "June", "July", "August", 6628019Sjoerg "September", "October", "November", "December" }, 6728019Sjoerg { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, 6828019Sjoerg { "Sunday", "Monday", "Tuesday", "Wednesday", 6928019Sjoerg "Thursday", "Friday", "Saturday" }, 7028019Sjoerg "%H:%M:%S", 7128019Sjoerg "%m/%d/%y", 7228019Sjoerg "%a %b %e %T %Z %Y", 7328019Sjoerg "AM", 7428019Sjoerg "PM", 7528019Sjoerg "%A, %B, %e, %Y" 7628019Sjoerg}; 7728019Sjoerg 7828019Sjoerg#ifdef SUNOS4 7928019Sjoergextern int strncasecmp(); 8028019Sjoerg#endif 8128019Sjoerg 8228019Sjoergchar * 8328019Sjoergstrptime(char *buf, char *fmt, struct tm *tm) 8428019Sjoerg{ 8528019Sjoerg char c, 8628019Sjoerg *ptr; 8728019Sjoerg int i, 8828019Sjoerg len; 8928019Sjoerg 9028019Sjoerg ptr = fmt; 9128019Sjoerg while (*ptr != 0) { 9228019Sjoerg if (*buf == 0) 9328019Sjoerg break; 9428019Sjoerg 9528019Sjoerg c = *ptr++; 9628019Sjoerg 9728019Sjoerg if (c != '%') { 9828019Sjoerg if (isspace(c)) 9928019Sjoerg while (*buf != 0 && isspace(*buf)) 10028019Sjoerg buf++; 10128019Sjoerg else if (c != *buf++) 10228019Sjoerg return 0; 10328019Sjoerg continue; 10428019Sjoerg } 10528019Sjoerg 10628019Sjoerg c = *ptr++; 10728019Sjoerg switch (c) { 10828019Sjoerg case 0: 10928019Sjoerg case '%': 11028019Sjoerg if (*buf++ != '%') 11128019Sjoerg return 0; 11228019Sjoerg break; 11328019Sjoerg 11428019Sjoerg case 'C': 11528019Sjoerg buf = strptime(buf, En_US.ldate_format, tm); 11628019Sjoerg if (buf == 0) 11728019Sjoerg return 0; 11828019Sjoerg break; 11928019Sjoerg 12028019Sjoerg case 'c': 12128019Sjoerg buf = strptime(buf, "%x %X", tm); 12228019Sjoerg if (buf == 0) 12328019Sjoerg return 0; 12428019Sjoerg break; 12528019Sjoerg 12628019Sjoerg case 'D': 12728019Sjoerg buf = strptime(buf, "%m/%d/%y", tm); 12828019Sjoerg if (buf == 0) 12928019Sjoerg return 0; 13028019Sjoerg break; 13128019Sjoerg 13228019Sjoerg case 'R': 13328019Sjoerg buf = strptime(buf, "%H:%M", tm); 13428019Sjoerg if (buf == 0) 13528019Sjoerg return 0; 13628019Sjoerg break; 13728019Sjoerg 13828019Sjoerg case 'r': 13928019Sjoerg buf = strptime(buf, "%I:%M:%S %p", tm); 14028019Sjoerg if (buf == 0) 14128019Sjoerg return 0; 14228019Sjoerg break; 14328019Sjoerg 14428019Sjoerg case 'T': 14528019Sjoerg buf = strptime(buf, "%H:%M:%S", tm); 14628019Sjoerg if (buf == 0) 14728019Sjoerg return 0; 14828019Sjoerg break; 14928019Sjoerg 15028019Sjoerg case 'X': 15128019Sjoerg buf = strptime(buf, En_US.time_format, tm); 15228019Sjoerg if (buf == 0) 15328019Sjoerg return 0; 15428019Sjoerg break; 15528019Sjoerg 15628019Sjoerg case 'x': 15728019Sjoerg buf = strptime(buf, En_US.sdate_format, tm); 15828019Sjoerg if (buf == 0) 15928019Sjoerg return 0; 16028019Sjoerg break; 16128019Sjoerg 16228019Sjoerg case 'j': 16328019Sjoerg if (!isdigit(*buf)) 16428019Sjoerg return 0; 16528019Sjoerg 16628019Sjoerg for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 16728019Sjoerg i *= 10; 16828019Sjoerg i += *buf - '0'; 16928019Sjoerg } 17028019Sjoerg if (i > 365) 17128019Sjoerg return 0; 17228019Sjoerg 17328019Sjoerg tm->tm_yday = i; 17428019Sjoerg break; 17528019Sjoerg 17628019Sjoerg case 'M': 17728019Sjoerg case 'S': 17828019Sjoerg if (*buf == 0 || isspace(*buf)) 17928019Sjoerg break; 18028019Sjoerg 18128019Sjoerg if (!isdigit(*buf)) 18228019Sjoerg return 0; 18328019Sjoerg 18428019Sjoerg for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 18528019Sjoerg i *= 10; 18628019Sjoerg i += *buf - '0'; 18728019Sjoerg } 18828019Sjoerg if (i > 59) 18928019Sjoerg return 0; 19028019Sjoerg 19128019Sjoerg if (c == 'M') 19228019Sjoerg tm->tm_min = i; 19328019Sjoerg else 19428019Sjoerg tm->tm_sec = i; 19528019Sjoerg 19628019Sjoerg if (*buf != 0 && isspace(*buf)) 19728019Sjoerg while (*ptr != 0 && !isspace(*ptr)) 19828019Sjoerg ptr++; 19928019Sjoerg break; 20028019Sjoerg 20128019Sjoerg case 'H': 20228019Sjoerg case 'I': 20328019Sjoerg case 'k': 20428019Sjoerg case 'l': 20528019Sjoerg if (!isdigit(*buf)) 20628019Sjoerg return 0; 20728019Sjoerg 20828019Sjoerg for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 20928019Sjoerg i *= 10; 21028019Sjoerg i += *buf - '0'; 21128019Sjoerg } 21228019Sjoerg if (c == 'H' || c == 'k') { 21328019Sjoerg if (i > 23) 21428019Sjoerg return 0; 21528019Sjoerg } else if (i > 11) 21628019Sjoerg return 0; 21728019Sjoerg 21828019Sjoerg tm->tm_hour = i; 21928019Sjoerg 22028019Sjoerg if (*buf != 0 && isspace(*buf)) 22128019Sjoerg while (*ptr != 0 && !isspace(*ptr)) 22228019Sjoerg ptr++; 22328019Sjoerg break; 22428019Sjoerg 22528019Sjoerg case 'p': 22628019Sjoerg len = strlen(En_US.am_string); 22728019Sjoerg if (strncasecmp(buf, En_US.am_string, len) == 0) { 22828019Sjoerg if (tm->tm_hour > 12) 22928019Sjoerg return 0; 23028019Sjoerg if (tm->tm_hour == 12) 23128019Sjoerg tm->tm_hour = 0; 23228019Sjoerg buf += len; 23328019Sjoerg break; 23428019Sjoerg } 23528019Sjoerg 23628019Sjoerg len = strlen(En_US.pm_string); 23728019Sjoerg if (strncasecmp(buf, En_US.pm_string, len) == 0) { 23828019Sjoerg if (tm->tm_hour > 12) 23928019Sjoerg return 0; 24028019Sjoerg if (tm->tm_hour != 12) 24128019Sjoerg tm->tm_hour += 12; 24228019Sjoerg buf += len; 24328019Sjoerg break; 24428019Sjoerg } 24528019Sjoerg 24628019Sjoerg return 0; 24728019Sjoerg 24828019Sjoerg case 'A': 24928019Sjoerg case 'a': 25028019Sjoerg for (i = 0; i < asizeof(En_US.weekday_names); i++) { 25128019Sjoerg len = strlen(En_US.weekday_names[i]); 25228019Sjoerg if (strncasecmp(buf, 25328019Sjoerg En_US.weekday_names[i], 25428019Sjoerg len) == 0) 25528019Sjoerg break; 25628019Sjoerg 25728019Sjoerg len = strlen(En_US.abbrev_weekday_names[i]); 25828019Sjoerg if (strncasecmp(buf, 25928019Sjoerg En_US.abbrev_weekday_names[i], 26028019Sjoerg len) == 0) 26128019Sjoerg break; 26228019Sjoerg } 26328019Sjoerg if (i == asizeof(En_US.weekday_names)) 26428019Sjoerg return 0; 26528019Sjoerg 26628019Sjoerg tm->tm_wday = i; 26728019Sjoerg buf += len; 26828019Sjoerg break; 26928019Sjoerg 27028019Sjoerg case 'd': 27128019Sjoerg case 'e': 27228019Sjoerg if (!isdigit(*buf)) 27328019Sjoerg return 0; 27428019Sjoerg 27528019Sjoerg for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 27628019Sjoerg i *= 10; 27728019Sjoerg i += *buf - '0'; 27828019Sjoerg } 27928019Sjoerg if (i > 31) 28028019Sjoerg return 0; 28128019Sjoerg 28228019Sjoerg tm->tm_mday = i; 28328019Sjoerg 28428019Sjoerg if (*buf != 0 && isspace(*buf)) 28528019Sjoerg while (*ptr != 0 && !isspace(*ptr)) 28628019Sjoerg ptr++; 28728019Sjoerg break; 28828019Sjoerg 28928019Sjoerg case 'B': 29028019Sjoerg case 'b': 29128019Sjoerg case 'h': 29228019Sjoerg for (i = 0; i < asizeof(En_US.month_names); i++) { 29328019Sjoerg len = strlen(En_US.month_names[i]); 29428019Sjoerg if (strncasecmp(buf, 29528019Sjoerg En_US.month_names[i], 29628019Sjoerg len) == 0) 29728019Sjoerg break; 29828019Sjoerg 29928019Sjoerg len = strlen(En_US.abbrev_month_names[i]); 30028019Sjoerg if (strncasecmp(buf, 30128019Sjoerg En_US.abbrev_month_names[i], 30228019Sjoerg len) == 0) 30328019Sjoerg break; 30428019Sjoerg } 30528019Sjoerg if (i == asizeof(En_US.month_names)) 30628019Sjoerg return 0; 30728019Sjoerg 30828019Sjoerg tm->tm_mon = i; 30928019Sjoerg buf += len; 31028019Sjoerg break; 31128019Sjoerg 31228019Sjoerg case 'm': 31328019Sjoerg if (!isdigit(*buf)) 31428019Sjoerg return 0; 31528019Sjoerg 31628019Sjoerg for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 31728019Sjoerg i *= 10; 31828019Sjoerg i += *buf - '0'; 31928019Sjoerg } 32028019Sjoerg if (i < 1 || i > 12) 32128019Sjoerg return 0; 32228019Sjoerg 32328019Sjoerg tm->tm_mon = i - 1; 32428019Sjoerg 32528019Sjoerg if (*buf != 0 && isspace(*buf)) 32628019Sjoerg while (*ptr != 0 && !isspace(*ptr)) 32728019Sjoerg ptr++; 32828019Sjoerg break; 32928019Sjoerg 33028019Sjoerg case 'Y': 33128019Sjoerg case 'y': 33228019Sjoerg if (*buf == 0 || isspace(*buf)) 33328019Sjoerg break; 33428019Sjoerg 33528019Sjoerg if (!isdigit(*buf)) 33628019Sjoerg return 0; 33728019Sjoerg 33828019Sjoerg for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 33928019Sjoerg i *= 10; 34028019Sjoerg i += *buf - '0'; 34128019Sjoerg } 34228019Sjoerg if (c == 'Y') 34328019Sjoerg i -= 1900; 34428019Sjoerg if (i < 0) 34528019Sjoerg return 0; 34628019Sjoerg 34728019Sjoerg tm->tm_year = i; 34828019Sjoerg 34928019Sjoerg if (*buf != 0 && isspace(*buf)) 35028019Sjoerg while (*ptr != 0 && !isspace(*ptr)) 35128019Sjoerg ptr++; 35228019Sjoerg break; 35328019Sjoerg } 35428019Sjoerg } 35528019Sjoerg 35628019Sjoerg return buf; 35728019Sjoerg} 35828019Sjoerg 359