Baron
Baron

Reputation: 87

How to achieve time localization in c++?

I'm using the time_t and ctime header to get the time in my app, and it's all OK. The problem is that, the week days and months are displayed in English and i want them to be displayed in my language (Portuguese). How do I do that?

Here's my code:

time_t tempo = time(NULL);
char *data = ctime(&tempo);
cout << data << endl;

And this is the actual output:

"Fri Aug 21 20:00:55 2015"

I was thinking in something like this:

"20:00:55 Sex 21 Ago 2015"

Where Sex is Fri, and Ago is Aug.

I even used this:

setlocale(LC_ALL,".<code_page>");

My full code is this (It's in Portuguese, so the variables names can be weird):

#include <iostream>
#include <iomanip>
#include <ctime>
#include <string>
#include <fstream>
#include <locale>
#include <stdlib.h>
void titulo();
int numOrdem(int a);

using namespace std;
using namespace boost;//I'm experimenting with this, and not working...

int main()

{
    int ordem = 0;
    int mesa = 0;
    int turno = 0;
    int quantidade = 0;
    int ordemCheck = 0;
    string anterior = " ";
    string atual;


titulo();

while(true)
{
setlocale(LC_ALL,"");
time_t tempo = time(NULL);
char *data = ctime(&tempo);


minhaOrdem:
cout << "Insira o número da ordem: ";
cin >> ordem;
ordemCheck = numOrdem(ordem);
if (ordemCheck < 7 || ordemCheck > 7)
{
    cout << "Ordem incorreta.\n";
    goto minhaOrdem;
}

/*ofstream arquivo;
arquivo.open("ordersOnly.txt", ios::app);
arquivo << ordem << endl;
arquivo.close();

ifstream ler;
ler.open("ordersOnly.txt");

if(ler)
{
    while(ler >> atual)
    {
        if(atual == anterior)
        {
            cout << "Ordem " << atual << " já requisitada!\n";
            goto minhaOrdem;
        }
     anterior = atual;
    }

} Here I'm trying to catch an duplicated value...*/

cout << "Insira a quantidade de peças: ";
cin >> quantidade;

minhaMesa:
cout << "Insira o número da mesa: ";
cin >> mesa;
if(mesa < 1 || mesa > 6)
{
    cout << "Mesa incorreta.\n";
    goto minhaMesa;
}

meuturno:
cout << "Insira seu turno: ";
cin >> turno;
switch (turno)
    {
    case 100:
    break;
    case 200:
    break;
    case 300:
    break;
    default:{cout << "Turno Incorreto.\n";goto meuturno;}
    }
cout << "\n\n";


arquivo.open("ordensDifipro.txt", ios::app);
arquivo << "Ordem: " << ordem << endl;
arquivo << "Quantidade de peças: " << quantidade << endl;
arquivo << "Mesa: RL" << mesa << endl;
arquivo << "Turno: " << turno << endl;
arquivo << "Data: " << data << endl;
arquivo << endl;
arquivo.close();

}//Main while


}// int main


void titulo()
{
  cout << setw(62) << "Requisitor de Ordens - Difipro - v 1.1\n\n\n\n\n";
}

int numOrdem(int a)
{
    int counter = 0;
 while(a > 0)
    {
    a /= 10;
    counter++;
    }
 return counter;
}

I hope it helps!

Upvotes: 1

Views: 888

Answers (2)

user1703394
user1703394

Reputation: 128

You should probably have a look at the Boost Locale library.

http://www.boost.org/doc/libs/1_59_0/libs/locale/doc/html/index.html

Especially the part on formatting and parsing of time formatting:

http://www.boost.org/doc/libs/1_59_0/libs/locale/doc/html/formatting_and_parsing.html

It allows you to portably output things like date time values using the locale settings of the system it's being run on. There is an example doing exactly what tou are trying to do in a just two lines of code. It also does so without asking you to write platform dependant code. You may want to look at other parts of Boost Locale too, including message translation to make it truly work cross language.

Try to avoid using low level platform API's or C++14 features (as an alternate answer seems to suggest) unless you are sure your code will never be used on an other platform or in a C++ project not using C++11/C++14. Boost mostly is your best bet at writing stuff like this portably.

Upvotes: 0

Your question is OS specific, I'm focusing on Linux and perhaps other POSIX OSes

You could parse the time string with strptime(3) and convert the time to string with strftime(3), at least if the time fits in a Unix time_t (this would always be the case for time between 1970 i.e. the Unix Epoch and 2038 because of the Y2038 problem) e.g. using mktime(3) & localtime(3). Read locale(7) about some localization & internationalization things. You might need to call setlocale(3) appropriately.

In C++11 use <chrono> (see also this); see this time_point example to start.

Beware that distant times (e.g. early 1900s) can become quite complex, see this

Addenda: if you want your date to be in Portuguese, either set your LANG or LC_ALL environment variable (see environ(7)) to pt_PT.UTF-8 (perhaps by adding export LANG=pt_PT.UTF-8 in your ~/.bashrc file on Linux, if your login shell is bash) or replace the setlocale(LC_ALL,""); with setlocale(LC_ALL,"pt_PT.UTF-8"); in your program.

BTW, Windows has its documentation on setlocale

Upvotes: 3

Related Questions