document timefunc api
[libi2ncommon] / src / timefunc.cpp
index f111763..0883055 100644 (file)
@@ -24,6 +24,7 @@ on this file might be covered by the GNU General Public License.
  *
  */
 
+#include <cstdio>
 #include <errno.h>
 #include <string>
 #include <sstream>
@@ -867,7 +868,7 @@ namespace {
  * @param tm      Time to format as broken-down \c struct tm.
  * @param date    Include the day part ([-]YYYY-MM-DD).
  * @param time    Include the time part (hh:mm:ss).
- * @param tz      Include the timezone ([±]ZZZZ); only heeded if
+ * @param tz      Include the timezone ([±]ZZZZ); only needed if
  *                \c time is requested as well.
  *
  * @return        The formatted timestamp.
@@ -889,12 +890,15 @@ std::string format_iso8601 (const struct tm &tm, const bool date,
     }
 
     /*
-     * The sign is *always* handled above so the formatted string her
+     * The sign is *always* handled above so the formatted string here
      * is always one character shorter.
-     * */
-    const size_t n = strftime (start, iso8601::bufsize-1, format, &tmp);
+     */
+    if (strftime (start, iso8601::bufsize-1, format, &tmp) == 0)
+    {
+        return std::string ();
+    }
 
-    buf [n+1] = '\0';
+    buf [iso8601::bufsize-1] = '\0'; /* Just in case. */
 
     return std::string (buf);
 }
@@ -982,6 +986,32 @@ scan_iso8601 (const char *s,
     return tm;
 }
 
+/**
+ * @brief         Format a \c struct timespec in the schema established by
+ *                time(1): “3m14.159s”.
+ *
+ * @param ts      The time spec to format.
+ *
+ * @return        \c boost:none in case of error during formatting, an optional
+ *                \c std::string otherwise.
+ */
+boost::optional<std::string>
+format_min_sec_msec (const struct timespec &ts)
+{
+    char ms [4] = { '\0', '\0', '\0', '\0' };
+
+    if (snprintf (ms, 4, "%.3ld", ts.tv_nsec / 1000000) < 0) {
+        return boost::none;
+    }
+
+    const time_t min = ts.tv_sec / 60;
+    const time_t sec = ts.tv_sec - min * 60;
+
+    return I2n::to_string (min) + "m"
+         + I2n::to_string (sec) + "."
+         + ms + "s"
+         ;
+}
 
 namespace I2n {
 
@@ -989,6 +1019,18 @@ namespace clock {
 
     namespace {
 
+        /**
+         * @brief         <b>For internal use only</b>. Translates clock
+         *                specification flags to kernel clock types.
+         *
+         * @param id      Master clock id: \c mono, \c real, \c boot, or \c
+         *                cpu.
+         * @param var     Variant of clock if appropriate: \c raw, \c exact, \c
+         *                process, or \c thread. Use \c dflt for the base
+         *                variant.
+         *
+         * @return        The clock id for using with kernel APIs.
+         */
         static inline clockid_t
         clockid_of_flags (const enum type::id      id,
                           const enum type::variant var) NOEXCEPT
@@ -1025,9 +1067,7 @@ namespace clock {
                 }
 
                 case type::boot: {
-                    if (var & type::exact) {
-                        cid = CLOCK_BOOTTIME;
-                    }
+                    cid = CLOCK_BOOTTIME;
                     break;
                 }
 
@@ -1103,6 +1143,14 @@ namespace clock {
         return *this;
     }
 
+    /*
+     * @note    This operator is an up-assignment from a type containing less
+     *          information than the structure assigned from. Since the
+     *          operator can only be two valued we must normalize the remaining
+     *          fields to the default clock. When assigning from non-default
+     *          clocks, use the appropriate constructor and pass it the desired
+     *          id and variant so as to assign the result.
+     */
     Time &
     Time::operator= (struct timespec ts) NOEXCEPT
     {
@@ -1213,18 +1261,18 @@ namespace clock {
         return ::format_iso8601 (tm, date, time, tz);
     }
 
-    boost::optional<std::string>
+    std::string
     Time::make_nice_time (void) const
     {
         /* XXX the cast below results in loss of precision with 64 bit time_t! */
         return ::make_nice_time (static_cast<int> (this->value.tv_sec));
     }
 
-    boost::optional<std::string>
+    std::string
     Time::format_full_time (void) const
     { return ::format_full_time (this->value.tv_sec); }
 
-    boost::optional<std::string>
+    std::string
     Time::format_date (void) const
     { return ::format_date (this->value.tv_sec); }