diff --git a/athenasub/include/athenasub/athenatime.h b/athenasub/include/athenasub/athenatime.h index a45a1a2d1..3686bf75c 100644 --- a/athenasub/include/athenasub/athenatime.h +++ b/athenasub/include/athenasub/athenatime.h @@ -47,10 +47,17 @@ namespace Athenasub { public: Time(); Time(int milliseconds); + Time(const String& timestamp); + Time(int hours,int minutes,int seconds,int milliseconds); int GetMS() const; void SetMS(int milliseconds); + int GetHoursComponent() const; + int GetMinutesComponent() const; + int GetSecondsComponent() const; + int GetMillisecondsComponent() const; + String GetString(int ms_precision=3,int h_precision=1) const; void ParseString(const String &data); diff --git a/athenasub/src/athenatime.cpp b/athenasub/src/athenatime.cpp index 432efc83a..5b66456e7 100644 --- a/athenasub/src/athenatime.cpp +++ b/athenasub/src/athenatime.cpp @@ -35,6 +35,7 @@ #include "athenatime.h" #include "utils.h" +#include "exception.h" using namespace Athenasub; @@ -50,6 +51,16 @@ Time::Time(int milliseconds) SetMS(milliseconds); } +Time::Time(const String& timestamp) +{ + ParseString(timestamp); +} + +Time::Time(int hours,int minutes,int seconds,int milliseconds) +{ + SetMS(hours*3600000 + minutes*60000 + seconds*1000 + milliseconds); +} + /////////////////// // Getters/setters @@ -70,7 +81,7 @@ String Time::GetString(int ms_precision,int h_precision) const { // Enforce sanity ms_precision = Mid(0,ms_precision,3); - h_precision = Mid(0,h_precision,2); + h_precision = Max(0,h_precision); // Generate values int _ms = GetMS(); @@ -81,9 +92,15 @@ String Time::GetString(int ms_precision,int h_precision) const int s = _ms / 1000; _ms -= s*1000; + // Find maximum hour value + int maxH = 0; + for (int i=0;i 9 && h_precision == 1) { - h = 9; + if (h > maxH) { + h = maxH; min = 59; s = 59; _ms = 999; @@ -95,33 +112,37 @@ String Time::GetString(int ms_precision,int h_precision) const else if (ms_precision == 0) _ms = 0; // Asserts - assert(h >= 0 && h <= 9); + assert(h >= 0 && h <= maxH); assert(min >= 0 && min <= 59); assert(s >= 0 && s <= 59); assert(_ms >= 0 && _ms <= 999); // Get write buffer String final; - size_t size = 7+h_precision+ms_precision; + size_t size = 5 + (h_precision > 0 ? h_precision+1 : 0) + (ms_precision > 0 ? ms_precision + 1 : 0); size_t pos = 0; //wxChar *buffer = final.GetWriteBuf(size); Character temp[16]; final.resize(size); // Write time - final.WriteNumber(temp,h,h_precision,pos); - final.WriteChar(':',pos); + if (h_precision > 0) { + final.WriteNumber(temp,h,h_precision,pos); + final.WriteChar(':',pos); + } final.WriteNumber(temp,min,2,pos); final.WriteChar(':',pos); final.WriteNumber(temp,s,2,pos); - final.WriteChar('.',pos); - final.WriteNumber(temp,_ms,ms_precision,pos); + if (ms_precision > 0) { + final.WriteChar('.',pos); + final.WriteNumber(temp,_ms,ms_precision,pos); + } // Write terminator //final.WriteText("\0",1,pos); // Restore string's state and return - final.SetSize(pos-1); + //final.SetSize(pos-1); return final; } @@ -157,7 +178,8 @@ void Time::ParseString(const String &data) } // Got a digit - else { + else if (cur != ' ') { + if (cur < '0' || cur > '9') THROW_ATHENA_EXCEPTION(Exception::Parse_Error); curValue = curValue * 10 + (int)(cur-'0'); nDigits++; diff --git a/unit_test/src/athenasub/test_time.cpp b/unit_test/src/athenasub/test_time.cpp index f63070d19..e2991537f 100644 --- a/unit_test/src/athenasub/test_time.cpp +++ b/unit_test/src/athenasub/test_time.cpp @@ -50,6 +50,7 @@ class AthenasubTimeTest : public CppUnit::TestFixture { CPPUNIT_TEST(testOperators); CPPUNIT_TEST(testSetGet); CPPUNIT_TEST(testParse); + CPPUNIT_TEST(testToString); CPPUNIT_TEST_SUITE_END(); private: @@ -109,45 +110,45 @@ public: void testParse() { - Time a; - a.ParseString("0"); - CPPUNIT_ASSERT(a.GetMS() == 0); - a.ParseString("5"); - CPPUNIT_ASSERT(a.GetMS() == 5000); - a.ParseString("5.0"); - CPPUNIT_ASSERT(a.GetMS() == 5000); - a.ParseString("5,0"); - CPPUNIT_ASSERT(a.GetMS() == 5000); - a.ParseString("5.00"); - CPPUNIT_ASSERT(a.GetMS() == 5000); - a.ParseString("5.000"); - CPPUNIT_ASSERT(a.GetMS() == 5000); - a.ParseString("5.1"); - CPPUNIT_ASSERT(a.GetMS() == 5100); - a.ParseString("5.12"); - CPPUNIT_ASSERT(a.GetMS() == 5120); - a.ParseString("5.123"); - CPPUNIT_ASSERT(a.GetMS() == 5123); - a.ParseString("5,123"); - CPPUNIT_ASSERT(a.GetMS() == 5123); - a.ParseString("5,1234"); - CPPUNIT_ASSERT(a.GetMS() == 5123); - a.ParseString("5,"); - CPPUNIT_ASSERT(a.GetMS() == 5000); - a.ParseString("05.12"); - CPPUNIT_ASSERT(a.GetMS() == 5120); - a.ParseString("0:05.12"); - CPPUNIT_ASSERT(a.GetMS() == 5120); - a.ParseString("0:15.12"); - CPPUNIT_ASSERT(a.GetMS() == 15120); - a.ParseString("1:15.12"); - CPPUNIT_ASSERT(a.GetMS() == 75120); - a.ParseString("11:15.12"); - CPPUNIT_ASSERT(a.GetMS() == 675120); - a.ParseString("2:11:15.12"); - CPPUNIT_ASSERT(a.GetMS() == 675120+7200000); - a.ParseString("10:11:15.12"); - CPPUNIT_ASSERT(a.GetMS() == 675120+36000000); + CPPUNIT_ASSERT(Time("0").GetMS() == 0); + CPPUNIT_ASSERT(Time("5").GetMS() == 5000); + CPPUNIT_ASSERT(Time("5.0").GetMS() == 5000); + CPPUNIT_ASSERT(Time("5,0").GetMS() == 5000); + CPPUNIT_ASSERT(Time("5.00").GetMS() == 5000); + CPPUNIT_ASSERT(Time("5.000").GetMS() == 5000); + CPPUNIT_ASSERT(Time("5.1").GetMS() == 5100); + CPPUNIT_ASSERT(Time("5.12").GetMS() == 5120); + CPPUNIT_ASSERT(Time("5.123").GetMS() == 5123); + CPPUNIT_ASSERT(Time("5,123").GetMS() == 5123); + CPPUNIT_ASSERT(Time("5,1234").GetMS() == 5123); + CPPUNIT_ASSERT(Time("5,").GetMS() == 5000); + CPPUNIT_ASSERT(Time("5.").GetMS() == 5000); + CPPUNIT_ASSERT(Time("05.12").GetMS() == 5120); + CPPUNIT_ASSERT(Time("0:05.12").GetMS() == 5120); + CPPUNIT_ASSERT(Time("0:15.12").GetMS() == 15120); + CPPUNIT_ASSERT(Time("1:15.12").GetMS() == 75120); + CPPUNIT_ASSERT(Time("11:15.12").GetMS() == 675120); + CPPUNIT_ASSERT(Time("2:11:15.12").GetMS() == 675120+7200000); + CPPUNIT_ASSERT(Time("10:11:15.12").GetMS() == 675120+36000000); + CPPUNIT_ASSERT(Time(" 10 : 11 : 15 . 12 ").GetMS() == 675120+36000000); + CPPUNIT_ASSERT_THROW(Time("10:1-1:15.12"),Athenasub::Exception); + } + + void testToString() + { + Time a(1,23,45,678); + Time b(11,23,45,678); + Time c(111,23,45,678); + CPPUNIT_ASSERT(a.GetString() == "1:23:45.678"); + CPPUNIT_ASSERT(a.GetString(2,1) == "1:23:45.67"); + CPPUNIT_ASSERT(a.GetString(3,2) == "01:23:45.678"); + CPPUNIT_ASSERT(a.GetString(0,1) == "1:23:45"); + CPPUNIT_ASSERT(a.GetString(0,0) == "59:59"); + CPPUNIT_ASSERT(b.GetString(3,2) == "11:23:45.678"); + CPPUNIT_ASSERT(b.GetString() == "9:59:59.999"); + CPPUNIT_ASSERT(b.GetString(2,1) == "9:59:59.99"); + CPPUNIT_ASSERT(c.GetString(3,2) == "99:59:59.999"); + CPPUNIT_ASSERT(c.GetString(3,3) == "111:23:45.678"); } };