[bookmarks] Added timestamp conversion helper functions

This commit is contained in:
Alex Zolotarev 2012-12-02 13:23:48 -08:00 committed by Alex Zolotarev
parent e2f51b92de
commit bd8abc8b5a
3 changed files with 87 additions and 0 deletions

View file

@ -15,6 +15,68 @@
#include "../std/algorithm.hpp"
////////////////////////////////////////////////////////
time_t const Bookmark::INVALID_TIME_STAMP = static_cast<time_t>(-1);
/// @name Helper functions to convert kml timestamps
//@{
/// Always creates strings in UTC time: 1997-07-16T07:30:15Z
/// Returns empty string on error
string TimestampToString(time_t time)
{
struct tm * t = gmtime(&time);
char buf[21] = { 0 };
::snprintf(buf, ARRAY_SIZE(buf), "%04d-%02d-%02dT%02d:%02d:%02dZ", t->tm_year + 1900,
t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
return buf;
}
/// Accepts strings in UTC format: 1997-07-16T07:30:15Z
/// And with custom time offset: 1997-07-16T10:30:15+03:00
/// @return INVALID_TIME_STAMP if string is invalid
time_t StringToTimestamp(string const & timeStr)
{
struct tm t;
memset(&t, 0, sizeof(t));
// Return current time in the case of failure
time_t res = Bookmark::INVALID_TIME_STAMP;
// Parse UTC format
if (timeStr.size() == 20)
{
if (6 == sscanf(timeStr.c_str(), "%4d-%2d-%2dT%2d:%2d:%2dZ", &t.tm_year,
&t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec))
{
t.tm_year -= 1900;
t.tm_mon -= 1;
res = timegm(&t);
}
}
else if (timeStr.size() == 25)
{
// Parse custom time zone offset format
char sign;
int tzHours, tzMinutes;
if (9 == sscanf(timeStr.c_str(), "%4d-%2d-%2dT%2d:%2d:%2d%c%2d:%2d", &t.tm_year,
&t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec,
&sign, &tzHours, &tzMinutes))
{
t.tm_year -= 1900;
t.tm_mon -= 1;
time_t const tt = timegm(&t);
// Fix timezone offset
if (sign == '-')
res = tt + tzHours * 3600 + tzMinutes * 60;
else if (sign == '+')
res = tt - tzHours * 3600 - tzMinutes * 60;
}
}
return res;
}
//@}
void BookmarkCategory::AddBookmarkImpl(Bookmark const & bm, double scale)
{
Bookmark * p = new Bookmark(bm);

View file

@ -8,6 +8,7 @@
#include "../std/string.hpp"
#include "../std/noncopyable.hpp"
#include "../std/iostream.hpp"
#include "../std/ctime.hpp"
class Bookmark
@ -33,6 +34,8 @@ public:
string const & GetType() const { return m_type; }
m2::RectD GetViewport() const { return m2::RectD(m_org, m_org); }
static time_t const INVALID_TIME_STAMP;
double GetScale() const { return m_scale; }
void SetScale(double scale) { m_scale = scale; }
};

View file

@ -9,6 +9,10 @@
#include "../../std/fstream.hpp"
// Prototypes for private functions in bookmarks.cpp
string TimestampToString(time_t time);
time_t StringToTimestamp(string const & timeStr);
namespace
{
char const * kmlString =
@ -373,3 +377,21 @@ UNIT_TEST(Bookmarks_AddingMoving)
DeleteCategoryFiles();
}
UNIT_TEST(TimestampConversion)
{
TEST_EQUAL(TimestampToString(0), "1970-01-01T00:00:00Z", ());
TEST_EQUAL(TimestampToString(1354482514), "2012-12-02T21:08:34Z", ());
TEST_EQUAL(StringToTimestamp("1970-01-01T00:00:00Z"), 0, ());
TEST_EQUAL(StringToTimestamp("2012-12-02T21:08:34Z"), 1354482514, ());
TEST_EQUAL(StringToTimestamp("2012-12-03T00:38:34+03:30"), 1354482514, ());
TEST_EQUAL(StringToTimestamp("2012-12-02T11:08:34-10:00"), 1354482514, ());
time_t now = time(0);
TEST_EQUAL(now, StringToTimestamp(TimestampToString(now)), ());
TEST_EQUAL(Bookmark::INVALID_TIME_STAMP, StringToTimestamp("asd23423adsfbhj657"), ());
TEST_EQUAL(Bookmark::INVALID_TIME_STAMP, StringToTimestamp("2012-aa-02T21:08:34Z"), ());
TEST_EQUAL(Bookmark::INVALID_TIME_STAMP, StringToTimestamp("2012-12-0ZT21:08:34Z"), ());
TEST_EQUAL(Bookmark::INVALID_TIME_STAMP, StringToTimestamp("2012:12:02T21-08-34Z"), ());
}