aboutsummaryrefslogtreecommitdiff
path: root/butl/timestamp.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-01-05 23:18:05 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-07 20:45:51 +0200
commit304b4e97bef93bcbeb82b5339451bacbb72b4f31 (patch)
tree9281eee5194b2c9a7d0c744c9ae29fdac28c6e45 /butl/timestamp.cxx
parent24e05cd878553ad2379d513951f06ec984b08594 (diff)
Fix nanoseconds formatting in to_stream(), operator<<()
Diffstat (limited to 'butl/timestamp.cxx')
-rw-r--r--butl/timestamp.cxx50
1 files changed, 39 insertions, 11 deletions
diff --git a/butl/timestamp.cxx b/butl/timestamp.cxx
index 8c53f60..6b99284 100644
--- a/butl/timestamp.cxx
+++ b/butl/timestamp.cxx
@@ -8,9 +8,10 @@
#include <errno.h> // EINVAL
#include <ctime> // tm, strftime()
-#include <iomanip> // put_time()
+#include <iomanip> // put_time(), setw(), dec, right
#include <cstring> // strlen(), memcpy()
#include <ostream>
+#include <stdexcept> // runtime_error
#include <system_error>
using namespace std;
@@ -101,6 +102,10 @@ namespace butl
{
if (fmt[j + 1] == '[')
{
+ if (os.width () != 0)
+ throw runtime_error (
+ "padding is not supported when printing nanoseconds");
+
// Our fragment. First see if we need to call put_time().
//
if (i != j)
@@ -129,9 +134,12 @@ namespace butl
{
if (d != '\0')
os << d;
- os.width (9);
- os.fill ('0');
- os << ns.count ();
+
+ ostream::fmtflags fl (os.flags ());
+ char fc (os.fill ('0'));
+ os << dec << right << setw (9) << ns.count ();
+ os.fill (fc);
+ os.flags (fl);
}
i = j + 1; // j is incremented in the for-loop header.
@@ -155,6 +163,10 @@ namespace butl
ostream&
operator<< (ostream& os, const duration& d)
{
+ if (os.width () != 0) // We always print nanosecond.
+ throw runtime_error (
+ "padding is not supported when printing nanoseconds");
+
timestamp ts; // Epoch.
ts += d;
@@ -162,17 +174,17 @@ namespace butl
const char* fmt (nullptr);
const char* unt ("nanoseconds");
- if (t >= 365 * 12 * 24 * 60 * 60)
+ if (t >= 365 * 24 * 60 * 60)
{
fmt = "%Y-%m-%d %H:%M:%S";
unt = "years";
}
- else if (t >= 12 * 24 * 60* 60)
+ else if (t >= 31 * 24 * 60 * 60)
{
fmt = "%m-%d %H:%M:%S";
unt = "months";
}
- else if (t >= 24 * 60* 60)
+ else if (t >= 24 * 60 * 60)
{
fmt = "%d %H:%M:%S";
unt = "days";
@@ -199,6 +211,18 @@ namespace butl
if (gmtime_r (&t, &tm) == nullptr)
throw system_error (errno, system_category ());
+ if (t >= 24 * 60 * 60)
+ tm.tm_mday -= 1; // Make day of the month to be a zero-based number.
+
+ if (t >= 31 * 24 * 60 * 60)
+ tm.tm_mon -= 1; // Make month of the year to be a zero-based number.
+
+ if (t >= 365 * 24 * 60 * 60)
+ // Make the year to be a 1970-based number. Negative values allowed
+ // according to the POSIX specification.
+ //
+ tm.tm_year -= 1970;
+
if (!(os << put_time (&tm, fmt)))
return os;
}
@@ -212,12 +236,16 @@ namespace butl
{
if (fmt != nullptr)
{
- os << '.';
- os.width (9);
- os.fill ('0');
+ ostream::fmtflags fl (os.flags ());
+ char fc (os.fill ('0'));
+ os << '.' << dec << right << setw (9) << ns.count ();
+ os.fill (fc);
+ os.flags (fl);
}
+ else
+ os << ns.count ();
- os << ns.count () << ' ' << unt;
+ os << ' ' << unt;
}
else if (fmt == nullptr)
os << '0';