alpar@1: /* glpmpl05.c */ alpar@1: alpar@1: /*********************************************************************** alpar@1: * This code is part of GLPK (GNU Linear Programming Kit). alpar@1: * alpar@1: * Authors: Andrew Makhorin alpar@1: * Heinrich Schuchardt alpar@1: * alpar@1: * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, alpar@1: * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, alpar@1: * Moscow Aviation Institute, Moscow, Russia. All rights reserved. alpar@1: * E-mail: . alpar@1: * alpar@1: * GLPK is free software: you can redistribute it and/or modify it alpar@1: * under the terms of the GNU General Public License as published by alpar@1: * the Free Software Foundation, either version 3 of the License, or alpar@1: * (at your option) any later version. alpar@1: * alpar@1: * GLPK is distributed in the hope that it will be useful, but WITHOUT alpar@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY alpar@1: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public alpar@1: * License for more details. alpar@1: * alpar@1: * You should have received a copy of the GNU General Public License alpar@1: * along with GLPK. If not, see . alpar@1: ***********************************************************************/ alpar@1: alpar@1: #define _GLPSTD_STDIO alpar@1: #define _GLPSTD_TIME alpar@1: #include "glpmpl.h" alpar@1: alpar@1: double fn_gmtime(MPL *mpl) alpar@1: { /* obtain the current calendar time (UTC) */ alpar@1: time_t timer; alpar@1: struct tm *tm; alpar@1: int j; alpar@1: time(&timer); alpar@1: if (timer == (time_t)(-1)) alpar@1: err: error(mpl, "gmtime(); unable to obtain current calendar time"); alpar@1: tm = gmtime(&timer); alpar@1: if (tm == NULL) goto err; alpar@1: j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); alpar@1: if (j < 0) goto err; alpar@1: return (((double)(j - jday(1, 1, 1970)) * 24.0 + alpar@1: (double)tm->tm_hour) * 60.0 + (double)tm->tm_min) * 60.0 + alpar@1: (double)tm->tm_sec; alpar@1: } alpar@1: alpar@1: static char *week[] = { "Monday", "Tuesday", "Wednesday", "Thursday", alpar@1: "Friday", "Saturday", "Sunday" }; alpar@1: alpar@1: static char *moon[] = { "January", "February", "March", "April", "May", alpar@1: "June", "July", "August", "September", "October", "November", alpar@1: "December" }; alpar@1: alpar@1: static void error1(MPL *mpl, const char *str, const char *s, alpar@1: const char *fmt, const char *f, const char *msg) alpar@1: { xprintf("Input string passed to str2time:\n"); alpar@1: xprintf("%s\n", str); alpar@1: xprintf("%*s\n", (s - str) + 1, "^"); alpar@1: xprintf("Format string passed to str2time:\n"); alpar@1: xprintf("%s\n", fmt); alpar@1: xprintf("%*s\n", (f - fmt) + 1, "^"); alpar@1: error(mpl, "%s", msg); alpar@1: /* no return */ alpar@1: } alpar@1: alpar@1: double fn_str2time(MPL *mpl, const char *str, const char *fmt) alpar@1: { /* convert character string to the calendar time */ alpar@1: int j, year, month, day, hh, mm, ss, zone; alpar@1: const char *s, *f; alpar@1: year = month = day = hh = mm = ss = -1, zone = INT_MAX; alpar@1: s = str; alpar@1: for (f = fmt; *f != '\0'; f++) alpar@1: { if (*f == '%') alpar@1: { f++; alpar@1: if (*f == 'b' || *f == 'h') alpar@1: { /* the abbreviated month name */ alpar@1: int k; alpar@1: char *name; alpar@1: if (month >= 0) alpar@1: error1(mpl, str, s, fmt, f, "month multiply specified" alpar@1: ); alpar@1: while (*s == ' ') s++; alpar@1: for (month = 1; month <= 12; month++) alpar@1: { name = moon[month-1]; alpar@1: for (k = 0; k <= 2; k++) alpar@1: { if (toupper((unsigned char)s[k]) != alpar@1: toupper((unsigned char)name[k])) goto next; alpar@1: } alpar@1: s += 3; alpar@1: for (k = 3; name[k] != '\0'; k++) alpar@1: { if (toupper((unsigned char)*s) != alpar@1: toupper((unsigned char)name[k])) break; alpar@1: s++; alpar@1: } alpar@1: break; alpar@1: next: ; alpar@1: } alpar@1: if (month > 12) alpar@1: error1(mpl, str, s, fmt, f, "abbreviated month name m" alpar@1: "issing or invalid"); alpar@1: } alpar@1: else if (*f == 'd') alpar@1: { /* the day of the month as a decimal number (01..31) */ alpar@1: if (day >= 0) alpar@1: error1(mpl, str, s, fmt, f, "day multiply specified"); alpar@1: while (*s == ' ') s++; alpar@1: if (!('0' <= *s && *s <= '9')) alpar@1: error1(mpl, str, s, fmt, f, "day missing or invalid"); alpar@1: day = (*s++) - '0'; alpar@1: if ('0' <= *s && *s <= '9') alpar@1: day = 10 * day + ((*s++) - '0'); alpar@1: if (!(1 <= day && day <= 31)) alpar@1: error1(mpl, str, s, fmt, f, "day out of range"); alpar@1: } alpar@1: else if (*f == 'H') alpar@1: { /* the hour as a decimal number, using a 24-hour clock alpar@1: (00..23) */ alpar@1: if (hh >= 0) alpar@1: error1(mpl, str, s, fmt, f, "hour multiply specified") alpar@1: ; alpar@1: while (*s == ' ') s++; alpar@1: if (!('0' <= *s && *s <= '9')) alpar@1: error1(mpl, str, s, fmt, f, "hour missing or invalid") alpar@1: ; alpar@1: hh = (*s++) - '0'; alpar@1: if ('0' <= *s && *s <= '9') alpar@1: hh = 10 * hh + ((*s++) - '0'); alpar@1: if (!(0 <= hh && hh <= 23)) alpar@1: error1(mpl, str, s, fmt, f, "hour out of range"); alpar@1: } alpar@1: else if (*f == 'm') alpar@1: { /* the month as a decimal number (01..12) */ alpar@1: if (month >= 0) alpar@1: error1(mpl, str, s, fmt, f, "month multiply specified" alpar@1: ); alpar@1: while (*s == ' ') s++; alpar@1: if (!('0' <= *s && *s <= '9')) alpar@1: error1(mpl, str, s, fmt, f, "month missing or invalid" alpar@1: ); alpar@1: month = (*s++) - '0'; alpar@1: if ('0' <= *s && *s <= '9') alpar@1: month = 10 * month + ((*s++) - '0'); alpar@1: if (!(1 <= month && month <= 12)) alpar@1: error1(mpl, str, s, fmt, f, "month out of range"); alpar@1: } alpar@1: else if (*f == 'M') alpar@1: { /* the minute as a decimal number (00..59) */ alpar@1: if (mm >= 0) alpar@1: error1(mpl, str, s, fmt, f, "minute multiply specifie" alpar@1: "d"); alpar@1: while (*s == ' ') s++; alpar@1: if (!('0' <= *s && *s <= '9')) alpar@1: error1(mpl, str, s, fmt, f, "minute missing or invali" alpar@1: "d"); alpar@1: mm = (*s++) - '0'; alpar@1: if ('0' <= *s && *s <= '9') alpar@1: mm = 10 * mm + ((*s++) - '0'); alpar@1: if (!(0 <= mm && mm <= 59)) alpar@1: error1(mpl, str, s, fmt, f, "minute out of range"); alpar@1: } alpar@1: else if (*f == 'S') alpar@1: { /* the second as a decimal number (00..60) */ alpar@1: if (ss >= 0) alpar@1: error1(mpl, str, s, fmt, f, "second multiply specifie" alpar@1: "d"); alpar@1: while (*s == ' ') s++; alpar@1: if (!('0' <= *s && *s <= '9')) alpar@1: error1(mpl, str, s, fmt, f, "second missing or invali" alpar@1: "d"); alpar@1: ss = (*s++) - '0'; alpar@1: if ('0' <= *s && *s <= '9') alpar@1: ss = 10 * ss + ((*s++) - '0'); alpar@1: if (!(0 <= ss && ss <= 60)) alpar@1: error1(mpl, str, s, fmt, f, "second out of range"); alpar@1: } alpar@1: else if (*f == 'y') alpar@1: { /* the year without a century as a decimal number alpar@1: (00..99); the values 00 to 68 mean the years 2000 to alpar@1: 2068 while the values 69 to 99 mean the years 1969 to alpar@1: 1999 */ alpar@1: if (year >= 0) alpar@1: error1(mpl, str, s, fmt, f, "year multiply specified") alpar@1: ; alpar@1: while (*s == ' ') s++; alpar@1: if (!('0' <= *s && *s <= '9')) alpar@1: error1(mpl, str, s, fmt, f, "year missing or invalid") alpar@1: ; alpar@1: year = (*s++) - '0'; alpar@1: if ('0' <= *s && *s <= '9') alpar@1: year = 10 * year + ((*s++) - '0'); alpar@1: year += (year >= 69 ? 1900 : 2000); alpar@1: } alpar@1: else if (*f == 'Y') alpar@1: { /* the year as a decimal number, using the Gregorian alpar@1: calendar */ alpar@1: if (year >= 0) alpar@1: error1(mpl, str, s, fmt, f, "year multiply specified") alpar@1: ; alpar@1: while (*s == ' ') s++; alpar@1: if (!('0' <= *s && *s <= '9')) alpar@1: error1(mpl, str, s, fmt, f, "year missing or invalid") alpar@1: ; alpar@1: year = 0; alpar@1: for (j = 1; j <= 4; j++) alpar@1: { if (!('0' <= *s && *s <= '9')) break; alpar@1: year = 10 * year + ((*s++) - '0'); alpar@1: } alpar@1: if (!(1 <= year && year <= 4000)) alpar@1: error1(mpl, str, s, fmt, f, "year out of range"); alpar@1: } alpar@1: else if (*f == 'z') alpar@1: { /* time zone offset in the form zhhmm */ alpar@1: int z, hh, mm; alpar@1: if (zone != INT_MAX) alpar@1: error1(mpl, str, s, fmt, f, "time zone offset multipl" alpar@1: "y specified"); alpar@1: while (*s == ' ') s++; alpar@1: if (*s == 'Z') alpar@1: { z = hh = mm = 0, s++; alpar@1: goto skip; alpar@1: } alpar@1: if (*s == '+') alpar@1: z = +1, s++; alpar@1: else if (*s == '-') alpar@1: z = -1, s++; alpar@1: else alpar@1: error1(mpl, str, s, fmt, f, "time zone offset sign mi" alpar@1: "ssing"); alpar@1: hh = 0; alpar@1: for (j = 1; j <= 2; j++) alpar@1: { if (!('0' <= *s && *s <= '9')) alpar@1: err1: error1(mpl, str, s, fmt, f, "time zone offset valu" alpar@1: "e incomplete or invalid"); alpar@1: hh = 10 * hh + ((*s++) - '0'); alpar@1: } alpar@1: if (hh > 23) alpar@1: err2: error1(mpl, str, s, fmt, f, "time zone offset value o" alpar@1: "ut of range"); alpar@1: if (*s == ':') alpar@1: { s++; alpar@1: if (!('0' <= *s && *s <= '9')) goto err1; alpar@1: } alpar@1: mm = 0; alpar@1: if (!('0' <= *s && *s <= '9')) goto skip; alpar@1: for (j = 1; j <= 2; j++) alpar@1: { if (!('0' <= *s && *s <= '9')) goto err1; alpar@1: mm = 10 * mm + ((*s++) - '0'); alpar@1: } alpar@1: if (mm > 59) goto err2; alpar@1: skip: zone = z * (60 * hh + mm); alpar@1: } alpar@1: else if (*f == '%') alpar@1: { /* literal % character */ alpar@1: goto test; alpar@1: } alpar@1: else alpar@1: error1(mpl, str, s, fmt, f, "invalid conversion specifie" alpar@1: "r"); alpar@1: } alpar@1: else if (*f == ' ') alpar@1: ; alpar@1: else alpar@1: test: { /* check a matching character in the input string */ alpar@1: if (*s != *f) alpar@1: error1(mpl, str, s, fmt, f, "character mismatch"); alpar@1: s++; alpar@1: } alpar@1: } alpar@1: if (year < 0) year = 1970; alpar@1: if (month < 0) month = 1; alpar@1: if (day < 0) day = 1; alpar@1: if (hh < 0) hh = 0; alpar@1: if (mm < 0) mm = 0; alpar@1: if (ss < 0) ss = 0; alpar@1: if (zone == INT_MAX) zone = 0; alpar@1: j = jday(day, month, year); alpar@1: xassert(j >= 0); alpar@1: return (((double)(j - jday(1, 1, 1970)) * 24.0 + (double)hh) * alpar@1: 60.0 + (double)mm) * 60.0 + (double)ss - 60.0 * (double)zone; alpar@1: } alpar@1: alpar@1: static void error2(MPL *mpl, const char *fmt, const char *f, alpar@1: const char *msg) alpar@1: { xprintf("Format string passed to time2str:\n"); alpar@1: xprintf("%s\n", fmt); alpar@1: xprintf("%*s\n", (f - fmt) + 1, "^"); alpar@1: error(mpl, "%s", msg); alpar@1: /* no return */ alpar@1: } alpar@1: alpar@1: static int weekday(int j) alpar@1: { /* determine weekday number (1 = Mon, ..., 7 = Sun) */ alpar@1: return (j + jday(1, 1, 1970)) % 7 + 1; alpar@1: } alpar@1: alpar@1: static int firstday(int year) alpar@1: { /* determine the first day of the first week for a specified year alpar@1: according to ISO 8601 */ alpar@1: int j; alpar@1: /* if 1 January is Monday, Tuesday, Wednesday or Thursday, it is alpar@1: in week 01; if 1 January is Friday, Saturday or Sunday, it is alpar@1: in week 52 or 53 of the previous year */ alpar@1: j = jday(1, 1, year) - jday(1, 1, 1970); alpar@1: switch (weekday(j)) alpar@1: { case 1: /* 1 Jan is Mon */ j += 0; break; alpar@1: case 2: /* 1 Jan is Tue */ j -= 1; break; alpar@1: case 3: /* 1 Jan is Wed */ j -= 2; break; alpar@1: case 4: /* 1 Jan is Thu */ j -= 3; break; alpar@1: case 5: /* 1 Jan is Fri */ j += 3; break; alpar@1: case 6: /* 1 Jan is Sat */ j += 2; break; alpar@1: case 7: /* 1 Jan is Sun */ j += 1; break; alpar@1: default: xassert(j != j); alpar@1: } alpar@1: /* the first day of the week must be Monday */ alpar@1: xassert(weekday(j) == 1); alpar@1: return j; alpar@1: } alpar@1: alpar@1: void fn_time2str(MPL *mpl, char *str, double t, const char *fmt) alpar@1: { /* convert the calendar time to character string */ alpar@1: int j, year, month, day, hh, mm, ss, len; alpar@1: double temp; alpar@1: const char *f; alpar@1: char buf[MAX_LENGTH+1]; alpar@1: if (!(-62135596800.0 <= t && t <= 64092211199.0)) alpar@1: error(mpl, "time2str(%.*g,...); argument out of range", alpar@1: DBL_DIG, t); alpar@1: t = floor(t + 0.5); alpar@1: temp = fabs(t) / 86400.0; alpar@1: j = (int)floor(temp); alpar@1: if (t < 0.0) alpar@1: { if (temp == floor(temp)) alpar@1: j = - j; alpar@1: else alpar@1: j = - (j + 1); alpar@1: } alpar@1: xassert(jdate(j + jday(1, 1, 1970), &day, &month, &year) == 0); alpar@1: ss = (int)(t - 86400.0 * (double)j); alpar@1: xassert(0 <= ss && ss < 86400); alpar@1: mm = ss / 60, ss %= 60; alpar@1: hh = mm / 60, mm %= 60; alpar@1: len = 0; alpar@1: for (f = fmt; *f != '\0'; f++) alpar@1: { if (*f == '%') alpar@1: { f++; alpar@1: if (*f == 'a') alpar@1: { /* the abbreviated weekday name */ alpar@1: memcpy(buf, week[weekday(j)-1], 3), buf[3] = '\0'; alpar@1: } alpar@1: else if (*f == 'A') alpar@1: { /* the full weekday name */ alpar@1: strcpy(buf, week[weekday(j)-1]); alpar@1: } alpar@1: else if (*f == 'b' || *f == 'h') alpar@1: { /* the abbreviated month name */ alpar@1: memcpy(buf, moon[month-1], 3), buf[3] = '\0'; alpar@1: } alpar@1: else if (*f == 'B') alpar@1: { /* the full month name */ alpar@1: strcpy(buf, moon[month-1]); alpar@1: } alpar@1: else if (*f == 'C') alpar@1: { /* the century of the year */ alpar@1: sprintf(buf, "%02d", year / 100); alpar@1: } alpar@1: else if (*f == 'd') alpar@1: { /* the day of the month as a decimal number (01..31) */ alpar@1: sprintf(buf, "%02d", day); alpar@1: } alpar@1: else if (*f == 'D') alpar@1: { /* the date using the format %m/%d/%y */ alpar@1: sprintf(buf, "%02d/%02d/%02d", month, day, year % 100); alpar@1: } alpar@1: else if (*f == 'e') alpar@1: { /* the day of the month like with %d, but padded with alpar@1: blank (1..31) */ alpar@1: sprintf(buf, "%2d", day); alpar@1: } alpar@1: else if (*f == 'F') alpar@1: { /* the date using the format %Y-%m-%d */ alpar@1: sprintf(buf, "%04d-%02d-%02d", year, month, day); alpar@1: } alpar@1: else if (*f == 'g') alpar@1: { /* the year corresponding to the ISO week number, but alpar@1: without the century (range 00 through 99); this has alpar@1: the same format and value as %y, except that if the alpar@1: ISO week number (see %V) belongs to the previous or alpar@1: next year, that year is used instead */ alpar@1: int iso; alpar@1: if (j < firstday(year)) alpar@1: iso = year - 1; alpar@1: else if (j < firstday(year + 1)) alpar@1: iso = year; alpar@1: else alpar@1: iso = year + 1; alpar@1: sprintf(buf, "%02d", iso % 100); alpar@1: } alpar@1: else if (*f == 'G') alpar@1: { /* the year corresponding to the ISO week number; this alpar@1: has the same format and value as %Y, excepth that if alpar@1: the ISO week number (see %V) belongs to the previous alpar@1: or next year, that year is used instead */ alpar@1: int iso; alpar@1: if (j < firstday(year)) alpar@1: iso = year - 1; alpar@1: else if (j < firstday(year + 1)) alpar@1: iso = year; alpar@1: else alpar@1: iso = year + 1; alpar@1: sprintf(buf, "%04d", iso); alpar@1: } alpar@1: else if (*f == 'H') alpar@1: { /* the hour as a decimal number, using a 24-hour clock alpar@1: (00..23) */ alpar@1: sprintf(buf, "%02d", hh); alpar@1: } alpar@1: else if (*f == 'I') alpar@1: { /* the hour as a decimal number, using a 12-hour clock alpar@1: (01..12) */ alpar@1: sprintf(buf, "%02d", alpar@1: hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); alpar@1: } alpar@1: else if (*f == 'j') alpar@1: { /* the day of the year as a decimal number (001..366) */ alpar@1: sprintf(buf, "%03d", alpar@1: jday(day, month, year) - jday(1, 1, year) + 1); alpar@1: } alpar@1: else if (*f == 'k') alpar@1: { /* the hour as a decimal number, using a 24-hour clock alpar@1: like %H, but padded with blank (0..23) */ alpar@1: sprintf(buf, "%2d", hh); alpar@1: } alpar@1: else if (*f == 'l') alpar@1: { /* the hour as a decimal number, using a 12-hour clock alpar@1: like %I, but padded with blank (1..12) */ alpar@1: sprintf(buf, "%2d", alpar@1: hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); alpar@1: } alpar@1: else if (*f == 'm') alpar@1: { /* the month as a decimal number (01..12) */ alpar@1: sprintf(buf, "%02d", month); alpar@1: } alpar@1: else if (*f == 'M') alpar@1: { /* the minute as a decimal number (00..59) */ alpar@1: sprintf(buf, "%02d", mm); alpar@1: } alpar@1: else if (*f == 'p') alpar@1: { /* either AM or PM, according to the given time value; alpar@1: noon is treated as PM and midnight as AM */ alpar@1: strcpy(buf, hh <= 11 ? "AM" : "PM"); alpar@1: } alpar@1: else if (*f == 'P') alpar@1: { /* either am or pm, according to the given time value; alpar@1: noon is treated as pm and midnight as am */ alpar@1: strcpy(buf, hh <= 11 ? "am" : "pm"); alpar@1: } alpar@1: else if (*f == 'r') alpar@1: { /* the calendar time using the format %I:%M:%S %p */ alpar@1: sprintf(buf, "%02d:%02d:%02d %s", alpar@1: hh == 0 ? 12 : hh <= 12 ? hh : hh - 12, alpar@1: mm, ss, hh <= 11 ? "AM" : "PM"); alpar@1: } alpar@1: else if (*f == 'R') alpar@1: { /* the hour and minute using the format %H:%M */ alpar@1: sprintf(buf, "%02d:%02d", hh, mm); alpar@1: } alpar@1: else if (*f == 'S') alpar@1: { /* the second as a decimal number (00..59) */ alpar@1: sprintf(buf, "%02d", ss); alpar@1: } alpar@1: else if (*f == 'T') alpar@1: { /* the time of day using the format %H:%M:%S */ alpar@1: sprintf(buf, "%02d:%02d:%02d", hh, mm, ss); alpar@1: } alpar@1: else if (*f == 'u') alpar@1: { /* the day of the week as a decimal number (1..7), alpar@1: Monday being 1 */ alpar@1: sprintf(buf, "%d", weekday(j)); alpar@1: } alpar@1: else if (*f == 'U') alpar@1: { /* the week number of the current year as a decimal alpar@1: number (range 00 through 53), starting with the first alpar@1: Sunday as the first day of the first week; days alpar@1: preceding the first Sunday in the year are considered alpar@1: to be in week 00 */ alpar@1: #if 1 /* 09/I-2009 */ alpar@1: #undef sun alpar@1: /* causes compilation error in SunOS */ alpar@1: #endif alpar@1: int sun; alpar@1: /* sun = the first Sunday of the year */ alpar@1: sun = jday(1, 1, year) - jday(1, 1, 1970); alpar@1: sun += (7 - weekday(sun)); alpar@1: sprintf(buf, "%02d", (j + 7 - sun) / 7); alpar@1: } alpar@1: else if (*f == 'V') alpar@1: { /* the ISO week number as a decimal number (range 01 alpar@1: through 53); ISO weeks start with Monday and end with alpar@1: Sunday; week 01 of a year is the first week which has alpar@1: the majority of its days in that year; week 01 of alpar@1: a year can contain days from the previous year; the alpar@1: week before week 01 of a year is the last week (52 or alpar@1: 53) of the previous year even if it contains days alpar@1: from the new year */ alpar@1: int iso; alpar@1: if (j < firstday(year)) alpar@1: iso = j - firstday(year - 1); alpar@1: else if (j < firstday(year + 1)) alpar@1: iso = j - firstday(year); alpar@1: else alpar@1: iso = j - firstday(year + 1); alpar@1: sprintf(buf, "%02d", iso / 7 + 1); alpar@1: } alpar@1: else if (*f == 'w') alpar@1: { /* the day of the week as a decimal number (0..6), alpar@1: Sunday being 0 */ alpar@1: sprintf(buf, "%d", weekday(j) % 7); alpar@1: } alpar@1: else if (*f == 'W') alpar@1: { /* the week number of the current year as a decimal alpar@1: number (range 00 through 53), starting with the first alpar@1: Monday as the first day of the first week; days alpar@1: preceding the first Monday in the year are considered alpar@1: to be in week 00 */ alpar@1: int mon; alpar@1: /* mon = the first Monday of the year */ alpar@1: mon = jday(1, 1, year) - jday(1, 1, 1970); alpar@1: mon += (8 - weekday(mon)) % 7; alpar@1: sprintf(buf, "%02d", (j + 7 - mon) / 7); alpar@1: } alpar@1: else if (*f == 'y') alpar@1: { /* the year without a century as a decimal number alpar@1: (00..99) */ alpar@1: sprintf(buf, "%02d", year % 100); alpar@1: } alpar@1: else if (*f == 'Y') alpar@1: { /* the year as a decimal number, using the Gregorian alpar@1: calendar */ alpar@1: sprintf(buf, "%04d", year); alpar@1: } alpar@1: else if (*f == '%') alpar@1: { /* a literal % character */ alpar@1: buf[0] = '%', buf[1] = '\0'; alpar@1: } alpar@1: else alpar@1: error2(mpl, fmt, f, "invalid conversion specifier"); alpar@1: } alpar@1: else alpar@1: buf[0] = *f, buf[1] = '\0'; alpar@1: if (len + strlen(buf) > MAX_LENGTH) alpar@1: error(mpl, "time2str; output string length exceeds %d chara" alpar@1: "cters", MAX_LENGTH); alpar@1: memcpy(str+len, buf, strlen(buf)); alpar@1: len += strlen(buf); alpar@1: } alpar@1: str[len] = '\0'; alpar@1: return; alpar@1: } alpar@1: alpar@1: /* eof */