diff --git a/doc/src/pg_developer.rst b/doc/src/pg_developer.rst index b6fb10e37b..95fc7ce513 100644 --- a/doc/src/pg_developer.rst +++ b/doc/src/pg_developer.rst @@ -902,6 +902,9 @@ Convenience functions .. doxygenfunction:: timespec2seconds :project: progguide +.. doxygenfunction:: date2num + :project: progguide + --------------------------- Tokenizer classes diff --git a/src/universe.cpp b/src/universe.cpp index e920270c1e..45efb936e3 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -27,8 +27,6 @@ using namespace LAMMPS_NS; #define MAXLINE 256 -static char *date2num(const char *version); - /* ---------------------------------------------------------------------- create & initialize the universe of processors in communicator ------------------------------------------------------------------------- */ @@ -36,7 +34,9 @@ static char *date2num(const char *version); Universe::Universe(LAMMPS *lmp, MPI_Comm communicator) : Pointers(lmp) { version = (const char *) LAMMPS_VERSION; - num_ver = date2num(version); + auto tmp_ver = new char[10]; + snprintf(tmp_ver,10,"%08d",utils::date2num(version)); + num_ver = tmp_ver; uworld = uorig = communicator; MPI_Comm_rank(uworld,&me); @@ -237,43 +237,3 @@ int Universe::consistent() if (n == nprocs) return 1; else return 0; } - -// helper function to convert the LAMMPS date string to a version id -// that can be used for both string and numerical comparisons -// where newer versions are larger than older ones. - -char *date2num(const char *version) -{ - int day,month,year; - day = month = year = 0; - - if (version) { - - day = atoi(version); - - while (*version != '\0' && (isdigit(*version) || *version == ' ')) - ++version; - - if (strncmp(version,"Jan",3) == 0) month = 1; - if (strncmp(version,"Feb",3) == 0) month = 2; - if (strncmp(version,"Mar",3) == 0) month = 3; - if (strncmp(version,"Apr",3) == 0) month = 4; - if (strncmp(version,"May",3) == 0) month = 5; - if (strncmp(version,"Jun",3) == 0) month = 6; - if (strncmp(version,"Jul",3) == 0) month = 7; - if (strncmp(version,"Aug",3) == 0) month = 8; - if (strncmp(version,"Sep",3) == 0) month = 9; - if (strncmp(version,"Oct",3) == 0) month = 10; - if (strncmp(version,"Nov",3) == 0) month = 11; - if (strncmp(version,"Dec",3) == 0) month = 12; - - while (*version != '\0' && !isdigit(*version)) - ++version; - - year = atoi(version); - } - - char *ver = new char[12]; - snprintf(ver,12,"%04d%02d%02d", year % 10000, month, day % 100); - return ver; -} diff --git a/src/utils.cpp b/src/utils.cpp index 45bd629c19..9d60ad01b6 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -983,6 +983,34 @@ double utils::timespec2seconds(const std::string ×pec) return vals[0]; } +/* ---------------------------------------------------------------------- + convert a LAMMPS version date (1Jan01) to a number +------------------------------------------------------------------------- */ + +int utils::date2num(const std::string &date) +{ + std::size_t found = date.find_first_not_of("0123456789 "); + int num = strtol(date.substr(0,found).c_str(),NULL,10); + auto month = date.substr(found); + found = month.find_first_of("0123456789 "); + num += strtol(month.substr(found).c_str(),NULL,10)*10000; + if (num < 1000000) num += 20000000; + + if (strmatch(month,"^Jan")) num += 100; + else if (strmatch(month,"^Feb")) num += 200; + else if (strmatch(month,"^Mar")) num += 300; + else if (strmatch(month,"^Apr")) num += 400; + else if (strmatch(month,"^May")) num += 500; + else if (strmatch(month,"^Jun")) num += 600; + else if (strmatch(month,"^Jul")) num += 700; + else if (strmatch(month,"^Aug")) num += 800; + else if (strmatch(month,"^Sep")) num += 900; + else if (strmatch(month,"^Oct")) num += 1000; + else if (strmatch(month,"^Nov")) num += 1100; + else if (strmatch(month,"^Dec")) num += 1200; + return num; +} + /* ------------------------------------------------------------------ */ extern "C" { diff --git a/src/utils.h b/src/utils.h index a06be39e28..026f46955f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -371,6 +371,24 @@ namespace LAMMPS_NS { * \return total in seconds */ double timespec2seconds(const std::string ×pec); + + /** Convert a LAMMPS version date to a number + * + * This will generate a number YYYYMMDD from a date string + * (with or without blanks) that is suitable for numerical + * comparisons, i.e. later dates will generate a larger number. + * + * The day may or may not have a leading zero, the month + * is identified by the first 3 letters (so there may be more) + * and the year may be 2 or 4 digits (the missing 2 digits will + * be assumed as 20. That is 04 corresponds to 2004). + * + * No check is made whether the date is valid. + * + * \param date string in the format (Day Month Year) + * \return date code + */ + int date2num(const std::string &date); } } diff --git a/unittest/utils/test_utils.cpp b/unittest/utils/test_utils.cpp index 1a3ca9fa0c..69076fcbd9 100644 --- a/unittest/utils/test_utils.cpp +++ b/unittest/utils/test_utils.cpp @@ -611,3 +611,20 @@ TEST(Utils, timespec2seconds_hhmmss) { ASSERT_DOUBLE_EQ(utils::timespec2seconds("2:10:45"), 7845.0); } + + +TEST(Utils, date2num) +{ + ASSERT_EQ(utils::date2num("1Jan05"),20050101); + ASSERT_EQ(utils::date2num("10Feb2005"),20050210); + ASSERT_EQ(utils::date2num("02Mar10"),20100302); + ASSERT_EQ(utils::date2num(" 5Apr1900"),19000405); + ASSERT_EQ(utils::date2num("10May22 "),20220510); + ASSERT_EQ(utils::date2num("1 Jun 05"),20050601); + ASSERT_EQ(utils::date2num("10 Jul 2005"),20050710); + ASSERT_EQ(utils::date2num("02 Aug 10"),20100802); + ASSERT_EQ(utils::date2num(" 5 September 99"),20990905); + ASSERT_EQ(utils::date2num("10October22 "),20221010); + ASSERT_EQ(utils::date2num("30November 02"),20021130); + ASSERT_EQ(utils::date2num("31December100"),1001231); +}