summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/include/nuttx/time.h17
-rw-r--r--nuttx/include/time.h11
-rw-r--r--nuttx/lib/Makefile3
-rw-r--r--nuttx/lib/lib_calendar2utc.c (renamed from nuttx/lib/lib_timeutils.c)27
-rw-r--r--nuttx/lib/lib_daysbeforemonth.c99
-rw-r--r--nuttx/lib/lib_gmtimer.c67
-rw-r--r--nuttx/lib/lib_isleapyear.c88
-rw-r--r--nuttx/lib/lib_mktime.c15
-rw-r--r--nuttx/lib/lib_strftime.c389
9 files changed, 654 insertions, 62 deletions
diff --git a/nuttx/include/nuttx/time.h b/nuttx/include/nuttx/time.h
index 1e5e50cb5..837e3a180 100644
--- a/nuttx/include/nuttx/time.h
+++ b/nuttx/include/nuttx/time.h
@@ -42,6 +42,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
+#include <time.h>
/****************************************************************************
* Pre-Processor Definitions
@@ -66,10 +67,6 @@
* Public Data
****************************************************************************/
-#ifndef CONFIG_GREGORIAN_TIME
-extern uint16 g_daysbeforemonth[13];
-#endif
-
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@@ -89,9 +86,17 @@ extern "C" {
*
****************************************************************************/
-#ifndef CONFIG_GREGORIAN_TIME
EXTERN int clock_isleapyear(int year);
-#endif
+
+/****************************************************************************
+ * Function: clock_daysbeforemonth
+ *
+ * Description:
+ * Get the number of days that occurred before the beginning of the month.
+ *
+ ****************************************************************************/
+
+EXTERN int clock_daysbeforemonth(int month, boolean leapyear);
/****************************************************************************
* Function: clock_calendar2utc
diff --git a/nuttx/include/time.h b/nuttx/include/time.h
index ce18c1350..bffde1041 100644
--- a/nuttx/include/time.h
+++ b/nuttx/include/time.h
@@ -73,6 +73,11 @@
#define TIMER_ABSTIME 1
+/* Local time is the same as gmtime in this implementation */
+
+#define localtime(c) gmtime(c)
+#define localtime_r(c,r) gmtime_r(c,r)
+
/********************************************************************************
* Global Type Declarations
********************************************************************************/
@@ -142,12 +147,10 @@ EXTERN int clock_settime(clockid_t clockid, const struct timespec *tp);
EXTERN int clock_gettime(clockid_t clockid, struct timespec *tp);
EXTERN int clock_getres(clockid_t clockid, struct timespec *res);
-EXTERN time_t mktime(struct tm *tp);
+EXTERN time_t mktime(const struct tm *tp);
EXTERN struct tm *gmtime(const time_t *clock);
EXTERN struct tm *gmtime_r(const time_t *clock, struct tm *result);
-
-#define localtime(c) gmtime(c)
-#define localtime_r(c,r) gmtime_r(c,r)
+EXTERN size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
EXTERN int timer_create(clockid_t clockid, FAR struct sigevent *evp, FAR timer_t *timerid);
EXTERN int timer_delete(timer_t timerid);
diff --git a/nuttx/lib/Makefile b/nuttx/lib/Makefile
index 63264bc36..0255234ac 100644
--- a/nuttx/lib/Makefile
+++ b/nuttx/lib/Makefile
@@ -83,7 +83,8 @@ UNISTD_SRCS += lib_chdir.c lib_getcwd.c
endif
endif
-TIME_SRCS = lib_mktime.c lib_gmtime.c lib_gmtimer.c lib_timeutils.c
+TIME_SRCS = lib_mktime.c lib_gmtime.c lib_gmtimer.c lib_strftime.c \
+ lib_calendar2utc.c lib_daysbeforemonth.c lib_isleapyear.c
NET_SRCS = lib_htons.c lib_htonl.c lib_inetntoa.c lib_etherntoa.c
diff --git a/nuttx/lib/lib_timeutils.c b/nuttx/lib/lib_calendar2utc.c
index 31404edde..ead92958f 100644
--- a/nuttx/lib/lib_timeutils.c
+++ b/nuttx/lib/lib_calendar2utc.c
@@ -65,13 +65,6 @@
* Public Variables
****************************************************************************/
-#ifndef CONFIG_GREGORIAN_TIME
-uint16 g_daysbeforemonth[13] =
-{
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
-};
-#endif
-
/****************************************************************************
* Private Variables
****************************************************************************/
@@ -121,21 +114,6 @@ static time_t clock_julian2utc(int year, int month, int day)
****************************************************************************/
/****************************************************************************
- * Function: clock_isleapyear
- *
- * Description:
- * Return true if the specified year is a leap year
- *
- ****************************************************************************/
-
-#ifndef CONFIG_GREGORIAN_TIME
-int clock_isleapyear(int year)
-{
- return year % 400 ? (year % 100 ? (year % 4 ? 0 : 1) : 0) : 1;
-}
-#endif /* !CONFIG_GREGORIAN_TIME */
-
-/****************************************************************************
* Function: clock_calendar2utc
*
* Description:
@@ -208,6 +186,11 @@ time_t clock_calendar2utc(int year, int month, int day)
#endif /* CONFIG_JULIAN_TIME */
}
#else
+
+/* A highly simplified version that only handles days in the time
+ * since Jan 1, 1970.
+ */
+
time_t clock_calendar2utc(int year, int month, int day)
{
struct tm t;
diff --git a/nuttx/lib/lib_daysbeforemonth.c b/nuttx/lib/lib_daysbeforemonth.c
new file mode 100644
index 000000000..e9c4d0026
--- /dev/null
+++ b/nuttx/lib/lib_daysbeforemonth.c
@@ -0,0 +1,99 @@
+/****************************************************************************
+ * lib/lib_daysbeforemonth.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <nuttx/time.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+uint16 g_daysbeforemonth[13] =
+{
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
+};
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: clock_daysbeforemonth
+ *
+ * Description:
+ * Get the number of days that occurred before the beginning of the month.
+ *
+ ****************************************************************************/
+
+int clock_daysbeforemonth(int month, boolean leapyear)
+{
+ int retval = g_daysbeforemonth[month];
+ if (month >= 2 && leapyear)
+ {
+ retval++;
+ }
+ return retval;
+}
+
+
diff --git a/nuttx/lib/lib_gmtimer.c b/nuttx/lib/lib_gmtimer.c
index 2758acd1a..03e1a2058 100644
--- a/nuttx/lib/lib_gmtimer.c
+++ b/nuttx/lib/lib_gmtimer.c
@@ -163,15 +163,26 @@ static void clock_utc2julian(time_t jd, int *year, int *month, int *day)
#endif /* CONFIG_JULIAN_TIME */
#else/* CONFIG_GREGORIAN_TIME */
+/* Only handles dates since Jan 1, 1970 */
+
static void clock_utc2calendar(time_t days, int *year, int *month, int *day)
{
int value;
+ int min;
+ int max;
int tmp;
boolean leapyear;
- /* There must be a better way to do this than the brute for method below */
+ /* There is one leap year every four years, so we can get close with the
+ * following:
+ */
+
+ value = days / (4*365 + 1); /* Number of 4-years periods */
+ days -= value * (4*365 + 1); /* Remaining days */
+ value = 70 + (value << 2); /* 1970 plus the 4 year groups */
+
+ /* Then we will brute force the next 0-3 years */
- value = 70;
for (;;)
{
/* Is this year a leap year (we'll need this later too) */
@@ -203,43 +214,63 @@ static void clock_utc2calendar(time_t days, int *year, int *month, int *day)
*year = value;
- /* Handle the month */
+ /* Handle the month (zero based) */
- value = 0; /* zero-based */
- for (;;)
+ min = 0;
+ max = 11;
+
+ do
{
- /* Get the number of days that occurred before the beginning of the next month */
+ /* Get the midpoint */
- tmp = g_daysbeforemonth[value + 1];
- if (value >= 2 && leapyear)
- {
- tmp++;
- }
+ value = (min + max) >> 1;
+
+ /* Get the number of days that occurred before the beginning month
+ * following the midpoint.
+ */
+
+ tmp = clock_daysbeforemonth(value + 1, leapyear);
/* Does that equal or exceed the number of days we have remaining? */
if (tmp >= days)
{
- /* Yes.. this is the one we want. The 'days' for this number of days that
- * occurred before this month.
+ /* Yes.. then the month we want is somewhere between 'min' and the.
+ * midpoint, 'value'. Check if it is the midpoint.
*/
- days -= g_daysbeforemonth[value];
- break;
+ tmp = clock_daysbeforemonth(value, leapyear);
+ if (tmp >= days)
+ {
+ /* No... The one we want is somewhere between min and value-1 */
+
+ max = value - 1;
+ }
+ else
+ {
+ /* Yes.. 'value' contains the month that we want */
+
+ break;
+ }
}
else
{
- /* No... try the next month */
+ /* No... The one we want is somwhere between value+1 and max */
- value++;
+ min = value + 1;
}
}
+ while (min < max);
+
+ /* Subtract the number of days in the selected month */
+
+ days -= clock_daysbeforemonth(value, leapyear);
/* At this point, value has the month into this year (zero based) and days has
* number of days into this month (zero based)
*/
- *month = value;
+ *month = value; /* Zero based */
*day = days + 1; /* 1-based */
}
diff --git a/nuttx/lib/lib_isleapyear.c b/nuttx/lib/lib_isleapyear.c
new file mode 100644
index 000000000..f27f14109
--- /dev/null
+++ b/nuttx/lib/lib_isleapyear.c
@@ -0,0 +1,88 @@
+/****************************************************************************
+ * lib/lib_isleapyear.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <nuttx/time.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: clock_isleapyear
+ *
+ * Description:
+ * Return true if the specified year is a leap year
+ *
+ ****************************************************************************/
+
+int clock_isleapyear(int year)
+{
+ return year % 400 ? (year % 100 ? (year % 4 ? 0 : 1) : 0) : 1;
+}
+
diff --git a/nuttx/lib/lib_mktime.c b/nuttx/lib/lib_mktime.c
index 594a0672b..46e16c50f 100644
--- a/nuttx/lib/lib_mktime.c
+++ b/nuttx/lib/lib_mktime.c
@@ -86,7 +86,7 @@
****************************************************************************/
#ifdef CONFIG_GREGORIAN_TIME
-time_t mktime(struct tm *tp)
+time_t mktime(const struct tm *tp)
{
time_t ret;
time_t jdn;
@@ -114,7 +114,7 @@ time_t mktime(struct tm *tp)
* seconds, etc. apply.
*/
-time_t mktime(struct tm *tp)
+time_t mktime(const struct tm *tp)
{
unsigned int days;
@@ -126,16 +126,9 @@ time_t mktime(struct tm *tp)
days += (tp->tm_year - 69) >> 2;
- /* Add in the days up to the beginning of this month (ignoring any possible leap day). */
+ /* Add in the days up to the beginning of this month. */
- days += (time_t)g_daysbeforemonth[tp->tm_mon];
-
- /* Add in the leap day for this year (months are zero based) */
-
- if (tp->tm_mon >= 2 && clock_isleapyear(tp->tm_year + 1900))
- {
- days++;
- }
+ days += (time_t)clock_daysbeforemonth(tp->tm_mon, clock_isleapyear(tp->tm_year + 1900));
/* Add in the days since the beginning of this month (days are 1-based). */
diff --git a/nuttx/lib/lib_strftime.c b/nuttx/lib/lib_strftime.c
new file mode 100644
index 000000000..02cce388b
--- /dev/null
+++ b/nuttx/lib/lib_strftime.c
@@ -0,0 +1,389 @@
+/****************************************************************************
+ * lib/lib_strftime.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <debug.h>
+
+#include <nuttx/time.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const char *g_abbrevmonthname[12] =
+{
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const char *g_monthname[12] =
+{
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: strftime
+ *
+ * Description:
+ * The strftime() function formats the broken-down time tm according to
+ * the format specification format and places the result in the character
+ * array s of size max.
+ *
+ * Ordinary characters placed in the format string are copied to s without
+ * conversion. Conversion specifications are introduced by a '%' charac-
+ * ter, and terminated by a conversion specifier character, and are
+ * replaced in s as follows:
+ *
+ * %b The abbreviated month name according to the current locale.
+ * %B The full month name according to the current locale.
+ * %C The century number (year/100) as a 2-digit integer. (SU)
+ * %d The day of the month as a decimal number (range 01 to 31).
+ * %e Like %d, the day of the month as a decimal number, but a leading
+ * zero is replaced by a space.
+ * %h Equivalent to %b. (SU)
+ * %H The hour as a decimal number using a 24-hour clock (range 00 to 23).
+ * %I The hour as a decimal number using a 12-hour clock (range 01 to 12).
+ * %j The day of the year as a decimal number (range 001 to 366).
+ * %k The hour (24-hour clock) as a decimal number (range 0 to 23);
+ * single digits are preceded by a blank. (See also %H.) (TZ)
+ * %l The hour (12-hour clock) as a decimal number (range 1 to 12);
+ * single digits are preceded by a blank. (See also %I.) (TZ)
+ * %m The month as a decimal number (range 01 to 12).
+ * %M The minute as a decimal number (range 00 to 59).
+ * %n A newline character. (SU)
+ * %p Either "AM" or "PM" according to the given time value, or the
+ * corresponding strings for the current locale. Noon is treated
+ * as "PM" and midnight as "AM".
+ * %P Like %p but in lowercase: "am" or "pm" or a corresponding string
+ * for the current locale. (GNU)
+ * %s The number of seconds since the Epoch, that is, since 1970-01-01
+ * 00:00:00 UTC. (TZ)
+ * %S The second as a decimal number (range 00 to 60). (The range is
+ * up to 60 to allow for occasional leap seconds.)
+ * %t A tab character. (SU)
+ * %y The year as a decimal number without a century (range 00 to 99).
+ * %Y The year as a decimal number including the century.
+ * %% A literal '%' character.
+ *
+ * Returned Value:
+ * The strftime() function returns the number of characters placed in the
+ * array s, not including the terminating null byte, provided the string,
+ * including the terminating null byte, fits. Otherwise, it returns 0,
+ * and the contents of the array is undefined.
+ *
+ ****************************************************************************/
+
+size_t strftime(char *s, size_t max, const char *format, const struct tm *tm)
+{
+ const char *str;
+ char *dest = s;
+ int chleft = max;
+ int value;
+ int len;
+
+ while (*format && chleft > 0)
+ {
+ /* Just copy regular characters */
+
+ if (*format != '%')
+ {
+ *dest++ = *format++;
+ chleft--;
+ continue;
+ }
+
+ /* Handle the format character */
+
+ len = 0;
+ value = 0;
+ str = "??";
+
+ switch (*++format)
+ {
+ /* %h: Equivalent to %b */
+
+ case 'h':
+
+ /* %b: The abbreviated month name according to the current locale. */
+
+ case 'b':
+ {
+ if (tm->tm_mon < 12)
+ {
+ str = g_abbrevmonthname[tm->tm_mon];
+ }
+ len = snprintf(dest, chleft, "%s", str);
+ }
+ break;
+
+ /* %B: The full month name according to the current locale. */
+
+ case 'B':
+ {
+ if (tm->tm_mon < 12)
+ {
+ str = g_monthname[tm->tm_mon];
+ }
+ len = snprintf(dest, chleft, "%s", str);
+ }
+ break;
+
+ /* %y: The year as a decimal number without a century (range 00 to 99). */
+
+ case 'y':
+
+ /* %C: The century number (year/100) as a 2-digit integer. */
+
+ case 'C':
+ {
+ len = snprintf(dest, chleft, "%02d", tm->tm_year);
+ }
+ break;
+
+ /* %d: The day of the month as a decimal number (range 01 to 31). */
+
+ case 'd':
+ {
+ len = snprintf(dest, chleft, "%02d", tm->tm_mday);
+ }
+ break;
+
+ /* %e: Like %d, the day of the month as a decimal number, but a leading
+ * zero is replaced by a space.
+ */
+
+ case 'e':
+ {
+ len = snprintf(dest, chleft, "%2d", tm->tm_mday);
+ }
+ break;
+
+ /* %H: The hour as a decimal number using a 24-hour clock (range 00 to 23). */
+
+ case 'H':
+ {
+ len = snprintf(dest, chleft, "%02d", tm->tm_hour);
+ }
+ break;
+
+ /* %I: The hour as a decimal number using a 12-hour clock (range 01 to 12). */
+
+ case 'I':
+ {
+ len = snprintf(dest, chleft, "%02d", tm->tm_hour % 12);
+ }
+ break;
+
+ /* %j: The day of the year as a decimal number (range 001 to 366). */
+
+ case 'j':
+ {
+ if (tm->tm_mon < 12)
+ {
+ value = clock_daysbeforemonth(tm->tm_mon, clock_isleapyear(tm->tm_year)) + tm->tm_mday;
+ }
+ len = snprintf(dest, chleft, "%03d", value);
+ }
+ break;
+
+ /* %k: The hour (24-hour clock) as a decimal number (range 0 to 23);
+ * single digits are preceded by a blank.
+ */
+
+ case 'k':
+ {
+ len = snprintf(dest, chleft, "%2d", tm->tm_hour);
+ }
+ break;
+
+ /* %l: The hour (12-hour clock) as a decimal number (range 1 to 12);
+ * single digits are preceded by a blank.
+ */
+
+ case 'l':
+ {
+ len = snprintf(dest, chleft, "%2d", tm->tm_hour % 12);
+ }
+ break;
+
+ /* %m: The month as a decimal number (range 01 to 12). */
+
+ case 'm':
+ {
+ len = snprintf(dest, chleft, "%02d", tm->tm_mon + 1);
+ }
+ break;
+
+ /* %M: The minute as a decimal number (range 00 to 59). */
+
+ case 'M':
+ {
+ len = snprintf(dest, chleft, "%02d", tm->tm_min);
+ }
+ break;
+
+ /* %n: A newline character. */
+
+ case 'n':
+ {
+ *dest = '\n';
+ len = 1;
+ }
+ break;
+
+ /* %p: Either "AM" or "PM" according to the given time value. */
+
+ case 'p':
+ {
+ if (tm->tm_hour >= 12)
+ {
+ str = "PM";
+ }
+ else
+ {
+ str = "AM";
+ }
+ len = snprintf(dest, chleft, "%s", str);
+ }
+ break;
+
+ /* %P: Like %p but in lowercase: "am" or "pm" */
+
+ case 'P':
+ {
+ if (tm->tm_hour >= 12)
+ {
+ str = "pm";
+ }
+ else
+ {
+ str = "am";
+ }
+ len = snprintf(dest, chleft, "%s", str);
+ }
+ break;
+
+ /* %s: The number of seconds since the Epoch, that is, since 1970-01-01
+ * 00:00:00 UTC.
+ */
+
+ case 's':
+ {
+ len = snprintf(dest, chleft, "%d", mktime(tm));
+ }
+ break;
+
+ /* %S: The second as a decimal number (range 00 to 60). (The range is
+ * up to 60 to allow for occasional leap seconds.)
+ */
+
+ case 'S':
+ {
+ len = snprintf(dest, chleft, "%02d", tm->tm_sec);
+ }
+ break;
+
+ /* %t: A tab character. */
+
+ case 't':
+ {
+ *dest = '\t';
+ len = 1;
+ }
+ break;
+
+ /* %Y: The year as a decimal number including the century. */
+
+ case 'Y':
+ {
+ len = snprintf(dest, chleft, "%04d", tm->tm_year + 1900);
+ }
+ break;
+
+ /* %%: A literal '%' character. */
+
+ case '%':
+ {
+ *dest = '%';
+ len = 1;
+ }
+ break;
+ }
+
+ /* Update counts and pointers */
+
+ dest += len;
+ chleft -= len;
+ }
+
+ return max - chleft;
+}