0

I have a map with string date-time keys, and int values. I would like to sort my map by the date and time (by the map keys actually) which are in format like this: 30/11/2012:13:49:55. Is that possible? How to sort them? When sorting only string there's no such a big deal, but I really don't know how to do this with date/time string.

#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
    map<string, int> mymap;

    mymap["30/11/2012:13:49:09"] = 122;
    mymap["30/11/2012:13:49:55"] = 100;
    mymap["30/11/2012:13:49:12"] = 123;
    mymap["29/11/2012:19:26:11"] = 45;

    for (std::map<string, int>::iterator i = mymap.begin(); i != mymap.end(); i++)
    {
        cout << i->first << "\n";
    }

};

The output of the program suggests that this map is already ordered, however, I'm not quite sure if it always (in every case) sort it like I want it to.

enter image description here

Ok folks, will something like this work fine?

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <ctime>

using namespace std;

time_t string_to_time_t(string s)
{
    struct tm tmp;
    time_t t;

    memset(&tmp, 0, sizeof(struct tm));
    strptime(s.c_str(), "%d/%m/%Y:%H:%M:%S", &tmp);
    t = mktime(&tmp);

    return t;
}

int main()
{
    time_t t, u;

    t = string_to_time_t("30/11/2012:13:49:09");
    u = string_to_time_t("30/11/2012:13:49:08");

    if (u>t)
    {
        cout << "true" << endl;
    }
    else if (u==t)
    {
        cout << "same" << endl;
    }
    else
    {
        cout << "false" << endl;
    }

    return 0;
}

EDIT:

Huh, it seems to work now, thanks!

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <map>
using namespace std;

time_t string_to_time_t(string s)
{
    struct tm tmp;
    time_t t;

    memset(&tmp, 0, sizeof(struct tm));
    strptime(s.c_str(), "%d/%m/%Y:%H:%M:%S", &tmp);
    t = mktime(&tmp);

    return t;
}

int main()
{
    map<time_t, int> mymap;

    mymap[string_to_time_t("30/11/2012:13:49:09")] = 122;
    mymap[string_to_time_t("30/11/2012:13:49:55")] = 100;
    mymap[string_to_time_t("30/11/2012:13:49:12")] = 123;
    mymap[string_to_time_t("29/11/2012:19:26:11")] = 45;

    for (std::map<time_t, int>::iterator i = mymap.begin(); i != mymap.end(); i++)
    {
        cout << i->first << " " <<  i->second << "\n";

    }

};
mirx
  • 606
  • 1
  • 9
  • 21
  • 11
    You basically have two questions: 1) [Convert a string to a timestamp](https://stackoverflow.com/questions/17681439/convert-string-time-to-unix-timestamp) and 2) Use a timestamp as a map key, which is trivial after 1 is solved. Or keep using `std::string` as a key, but write a custom sort functor for your map – Cory Kramer Sep 24 '15 at 12:25
  • 4
    or just put the date into YYYY/MM/DD:hh:mm:ss format and sort as a string – Richard Critten Sep 24 '15 at 12:27
  • 1
    are you sure you want to use a string as key? why don't use a timestamp? – Ruggero Turra Sep 24 '15 at 12:28
  • I would like to use a time stamp, but have problems converting my string key to time stamp, that's why I used strings – mirx Sep 24 '15 at 12:30
  • map takes a third comparator argument ( lambda function or struct). So you can use that and define your own comparator. As folks suggested, converting the date to timestamp in your comparator and and comparing seems an easy implementation of your comparator. – Misgevolution Sep 24 '15 at 12:36

1 Answers1

0

You can provide your own functor as a template argument when instantiating your map, cf. std::map - how to change key sorting?. The sort functor should parse the string and give the proper relations.

That said, I am a big fan of date strings whose alphabetical order is the same as their logical one, e.g. 2015-12-31-23-59-49.999 or such (for 11.59 pm plus a few sconds on new year's eve). I use such strings when I name pictures and when I print to log files.

Community
  • 1
  • 1
Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62