Как получить текущий локализованный шаблон для даты и времени std::locale

Пока я могу получить текущую локаль, но я хочу получить формат даты для этой конкретной локали. Можно ли это сделать с помощью стандартной библиотеки.

#include <locale>

int _tmain(int argc, _TCHAR* argv[])
{
   // Print the current locale
    std::cout << std::locale("").name().c_str() << "\n";

    // TODO: get the locale's date pattern, example for US it's (mm/dd/yyyy)
    std::cout << "date pattern:  \n";
}

person Flethuseo    schedule 12.01.2016    source источник
comment
Есть std::time_get::date_order   -  person    schedule 12.01.2016
comment
на самом деле boost::date_time очень полезен для такого рода работы   -  person ead    schedule 14.01.2016


Ответы (1)


Если вы просто хотите указать дату в соответствующей строке, вы можете использовать std::time_put<char>:

#include <locale>
#include <ctime>
#include <string>
#include <sstream>
std::string get_date_string(const std::time_t &input_time, const std::locale &loc){   
     std::tm * time = std::localtime ( &input_time );
     // get time_put facet:
     const std::time_put<char>& tmput = std::use_facet <std::time_put<char> > (loc);

     std::stringstream s;
     s.imbue(loc);//set locale loc to the stream, no matter which global locale

     std::tm *my_time=std::localtime( &input_time );
     tmput.put (s, s, ' ', my_time, 'x');

     return s.str(); 
  }

'x' говорит, что вам нужна только дата. Возможны и другие форматы - они такие же, как для strftime. Теперь, после запуска программы

int main(){

      std::time_t timestamp;
      std::time( &timestamp );

      std::cout<<"user settings: "<<get_date_string(timestamp, std::locale(""))<<"\n";
      std::cout<<"C settings: "<<get_date_string(timestamp, std::locale::classic())<<"\n";
}

на своей немецкой машине вижу:

user settings: 13.01.2016
C settings: 01/13/16

Если вы можете использовать boost, то это будет немного проще с boost::data_time:

#include <boost/date_time/gregorian/gregorian.hpp

using namespace boost::gregorian;


std::string get_date_string_boost(const date &d, const std::locale &loc){ 
    date_facet* f = new date_facet("%x");
    std::stringstream s;
    s.imbue(std::locale(loc, f));
    s<<d;
    return s.str();
}

и сейчас

int main(){
  date d(2015, Jan, 13);
  std::cout<<"user settings with boost: "<<get_date_string_boost(d, std::locale(""))<<"\n";
  std::cout<<"C settings with boost: "<<get_date_string_boost(d, std::locale::classic())<<"\n";

}

дает тот же результат, что и выше.

Если вы хотите явно узнать порядок дат, я не думаю, что вы можете попросить больше, чем узнать, является ли это ddmmyy (yy) или mmddyy (yy) или подобным:

  std::string date_order(const std::locale &loc){

      std::time_get<char>::dateorder order = std::use_facet<std::time_get<char> >(loc).date_order();
      switch (order) {
        case std::time_get<char>::dmy : return "dd/mm/yyyy"; 
        case std::time_get<char>::mdy : return "mm/dd/yyyy"; 
        case std::time_get<char>::ymd : return "yyyy/mm/dd"; 
        case std::time_get<char>::ydm : return "yyyy/dd/mm"; 
        default:
           return "no_order";//case std::time_get<char>::no_order
      }

  }

Не знаю, как устроен дистрибутив, на моей машине он "no_order", так что не ждите от него слишком много информации.

person ead    schedule 12.01.2016