CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Windows 7 - program napisany w BCB 6.0 - format daty

Windows 7 - program napisany w BCB 6.0 - format daty

dział ogólny

Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez scorp1on » czwartek, 4 listopada 2010, 17:30

Witam
Jest program napisany w BCB 6.0, po uruchomieniu w Windows 7 pojawia się błąd związany z formatem daty, pomimo ustawień w panelu sterowania na polskę program wyświetla amerykański format stąd są problemy. Ten sam program uruchomiony na Viście działa ok. Czy jest na to jakiś sposób aby program ustawił odpowiednio lokalizację pod Windows 7. Problem dotyczy też wyświetlania waluty jest dolar zamiast złotówki.
Avatar użytkownika
scorp1on
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): poniedziałek, 14 lipca 2008, 23:30
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP, Windows 7, Ubuntu 10.10
Kompilator: C++ Builder 6 pro, C++ Builder 2010 pro
Gadu Gadu: 0
    Windows VistaFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez Cyfrowy Baron » czwartek, 4 listopada 2010, 17:58

Podaj kod, którego używasz do wyświetlania daty.



Tutaj masz kod pokazujący jak to można zrobić pobierając format daty i czasu ustawiony w systemie:

KOD cpp:     UKRYJ  
 TFormatSettings fSettings;
 GetLocaleFormatSettings(1045, fSettings);
 TDateTime  DateTime = Now();
 Edit1->Text = DateTime.FormatString(fSettings.LongDateFormat +  " " + fSettings.LongTimeFormat);



GetLocaleFormatSettings(LCID: Integer; var FormatSettings: TFormatSettings);



LCID - lokalny kod języka - polska 1045. Jeżeli wprowadzisz niewłaściwy, to niezależnie od formatowania zdefiniowanego w systemie, data zostanie uporządkowana w sposób typowy dla danego języka. Porównaj z kodem 1033 - USA.

TFormatSettings - struktura do której funkcja zwróci ustawienia zdefiniowane w systemie. Struktura przechowuje następujące ustawienia:


TFormatSettings :
Byte CurrencyFormat;
Byte NegCurrFormat;
Char ThousandSeparator;
Char DecimalSeparator;
Byte CurrencyDecimals;
Char DateSeparator;
Char TimeSeparator;
Char ListSeparator;
String CurrencyString;
String ShortDateFormat;
String LongDateFormat;
String TimeAMString;
String TimePMString;
String ShortTimeFormat;
String LongTimeFormat;
TFormatSettings.:1 ShortMonthNames;
TFormatSettings.:2 LongMonthNames;
TFormatSettings.:3 ShortDayNames;
TFormatSettings.:4 LongDayNames;
WORD TwoDigitYearCenturyWindow;



Jeżeli chodzi o te elementy struktury:


TFormatSettings.:1 ShortMonthNames;
TFormatSettings.:2 LongMonthNames;
TFormatSettings.:3 ShortDayNames;
TFormatSettings.:4 LongDayNames;



To nie wiem jak je stosować, ale chętnie bym się dowiedział.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez scorp1on » czwartek, 4 listopada 2010, 20:54

Cyfrowy Baron napisał(a):Podaj kod, którego używasz do wyświetlania daty.


Używam w BCB 6 funkcji Date(); zwraca na Viście/XP ciąg "2010-11-04", w przypadku Windows 7 zwraca "11/04/2010"
W przypadku BCB 2010 tego problemu nie ma na obu systemach funkcja Date() zwraca "2010-11-04".

Dzięki za pomoc.
Avatar użytkownika
scorp1on
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): poniedziałek, 14 lipca 2008, 23:30
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP, Windows 7, Ubuntu 10.10
Kompilator: C++ Builder 6 pro, C++ Builder 2010 pro
Gadu Gadu: 0
    Windows VistaFirefox

Różne sposoby formatowania daty i czasu - TDateTime

Nowy postprzez Cyfrowy Baron » piątek, 5 listopada 2010, 10:04

Używasz po prostu funkcji Date() w ten np. sposób:

KOD cpp:     UKRYJ  
 Edit1->Text = Date();

W ten sposób na ogół wyświetlona zostanie data krótka ustawiona w systemie. By jednak mieć pewność, że zawsze tak będzie, należałoby to zrobić tak:

KOD cpp:     UKRYJ  
 TFormatSettings fSettings;
 GetLocaleFormatSettings(1045, fSettings);
 Edit1->Text = Date().FormatString(fSettings.ShortDateFormat);

Datę podobnie jak czas możesz też formatować po swojemu, np:

KOD cpp:     UKRYJ  
 Edit1->Text = Date().FormatString("dddd dd mmmm yyyy");
 Edit2->Text = Time().FormatString("hh-nn-ss");
 Edit3->Text = TDateTime::CurrentDateTime().FormatString("dd-mmmm-yyyy hh-nn-ss");;

Możesz również wstawiać dowolny tekst między formatowaną datę, ale ów tekst musi być ujęty w apostrofy:

KOD cpp:     UKRYJ  
 Edit1->Text = Date().FormatString("'dziś jest' dddd 'dnia' dd ', miesiąca' mmmm ', roku' yyyy");

KOD cpp:     UKRYJ  
 TFormatSettings fSettings;
 GetLocaleFormatSettings(1045, fSettings);
 Edit1->Text = Date().FormatString("'Aktualna data: '" + fSettings.ShortDateFormat);

Do pobrania aktualnej daty masz jeszcze funkcję Now():

KOD cpp:     UKRYJ  
 TFormatSettings fSettings;
 GetLocaleFormatSettings(1045, fSettings);

 Edit1->Text = Now();

 Edit2->Text = Now().FormatString("'Aktualna data: '" + fSettings.ShortDateFormat);
 Edit3->Text = Now().FormatString("'Aktualny czas: '" + fSettings.LongTimeFormat);

 Edit4->Text = Now().FormatString("'Dziś jest:' dd-mm-yyyy");
 Edit5->Text = Now().FormatString("'Godz.:' hh:nn:ss");
oraz funkcję TDateTime::CurrentDate():

KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TFormatSettings fSettings;
 GetLocaleFormatSettings(1045, fSettings);

 TDate Today = TDate::CurrentDate();

 Edit1->Text = Today;
 Edit2->Text = Today.FormatString("'Aktualna data: '" + fSettings.ShortDateFormat);
}
Dla czasu masz odpowiednio: TDateTime::CurrentTime(), a dla daty i czasu - TDateTime::CurrentDateTime().
Jeżeli tworzysz obiekt tylko typu TDate, to zwróci on tylko datę, podobnie jak TTime zwróci tylko czas. Jeżeli potrzebujesz jednocześnie daty i czasu, to należy użyć typu TDateTime:

KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TFormatSettings fSettings;
 GetLocaleFormatSettings(1045, fSettings);

 TDateTime Today = TDateTime::CurrentDateTime();

 Edit1->Text = Today;
 Edit2->Text = Today.FormatString("'Aktualna data: '" + fSettings.ShortDateFormat);
 Edit3->Text = Today.FormatString("'Aktualny czas: '" + fSettings.LongTimeFormat);
 Edit4->Text = Today.FormatString("'Dziś jest: '" + fSettings.ShortDateFormat +
                                  "' godz.: '" + fSettings.LongTimeFormat);
}


Można też po prostu tak:

KOD cpp:     UKRYJ  
 Edit1->Text = TDate::CurrentDate().FormatString("dd-mm-yyyy");
 Edit2->Text = TTime::CurrentTime().FormatString("hh:nn:ss");
 Edit3->Text = TDateTime::CurrentTDateTime().FormatString("dddd dd mmmm yyyy',' hh:nn:ss");




Tutaj ciekawe spostrzeżenie, jeżeli użyjesz typy TDate z TDate::CurrentTime(), to pomimo iż TDate zwraca datę, to zwróci również czas:

KOD cpp:     UKRYJ  
 TDate Today = TDate::CurrentTime();


Podobnie z TTime:

KOD cpp:     UKRYJ  
 TTime Today = TTime::CurrentDate();


Nie polecam jednak takich kombinacji, gdyż nigdy nie wiadomo co z tego wyniknie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez scorp1on » piątek, 5 listopada 2010, 10:46

Jaką bibliotekę trzeba dołączyć aby to w BCB 6 zadziałało.
mam błąd

[C++ Error] Unit1.cpp(31): E2451 Undefined symbol 'TFormatSettings'
[C++ Error] Unit1.cpp(31): E2379 Statement missing ;
[C++ Error] Unit1.cpp(32): E2268 Call to undefined function 'GetLocaleFormatSettings'
[C++ Error] Unit1.cpp(32): E2451 Undefined symbol 'fSettings'

Avatar użytkownika
scorp1on
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): poniedziałek, 14 lipca 2008, 23:30
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP, Windows 7, Ubuntu 10.10
Kompilator: C++ Builder 6 pro, C++ Builder 2010 pro
Gadu Gadu: 0
    Windows VistaFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez Corvis » piątek, 5 listopada 2010, 10:51

Weź kod wklej :-)

bo tutaj pokazuje, że średnik zjadłeś.


Edit. TFormatSettings jest w Unicie SysUtils
Ostatnio edytowano piątek, 5 listopada 2010, 10:52 przez Corvis, łącznie edytowano 1 raz
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez Cyfrowy Baron » piątek, 5 listopada 2010, 10:52

Struktura jest zdefiniowana w bibliotece SysUtils.hpp, ale muszę to jeszcze sprawdzić dla BCB 6.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez Cyfrowy Baron » piątek, 5 listopada 2010, 11:13

Z tego co zdążyłem się zorientować to w BCB6 nie ma funkcji GetLocaleFormatSettings i struktury TFormatSettings, więc potrzebne jest inne rozwiązanie. Gdy coś wymyślę dam znać, chociaż będzie trudno gdyż nie mam dostępu do BCB6.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Ustawienia daty i czasu poprzez funkcję GetLocaleInfo.

Nowy postprzez Cyfrowy Baron » piątek, 5 listopada 2010, 12:07

Proponuję skorzystać z funkcji GetLocaleInfo, powinna być dostępna w BCB6:
KOD cpp:     UKRYJ  
 char longDate[255];
 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLONGDATE, longDate, sizeof(longDate));

 char shortDate[11];
 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SSHORTDATE, shortDate, sizeof(shortDate));

 char longTime[9];
 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, longTime, sizeof(longTime));



 Edit1->Text = Date().FormatString("'Aktualna data: '" + (String)longDate);

 Edit2->Text = TDateTime::CurrentDateTime().FormatString("'Dzień: '" +
                        (String)shortDate + "', godz.: '" + (String)longTime);

 Edit3->Text = Time().FormatString("'Aktualna godz.: '" + (String)longTime);




Pytanie do polymorphism: czy dałoby się jakoś zastąpić zmienną char tak by nie trzeba było określać z góry jej rozmiaru, lecz tak by sama dopasowywała sobie rozmiar?! :roll:
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez polymorphism » piątek, 5 listopada 2010, 19:14

KOD cpp:     UKRYJ  
int cch = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, 0, 0);
if(cch > 0)
{
        vector<TCHAR> buf(cch);
        cch = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, &buf[0], buf.size());
        if(cch > 0)
        {
                cout << &buf[0] << '\n';
        }
}
 

O to chodzi?

Z drugiej strony, format daty jest raczej mały, więc nie wiem, czy jest sens się tak bawić, w tablicy 255-elementowej spokojnie się zmieści.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez Cyfrowy Baron » sobota, 6 listopada 2010, 09:01

Nie o to mi chodziło, lecz żeby tak jak w przypadku typy AnsiString, nie podawać rozmiaru bufora typu char, czyli nie określać z góry rozmiaru na 255, gdyż teoretycznie w przypadku LOCALE_SLONGDATE ten rozmiar może być większy. Tak naprawdę jednak jestem ciekaw czy dałoby się coś takiego z tym zrobić.

Zauważyłem, że funkcja GetLocaleInfo odczytuje dane z rejestru, więc można by stworzyć własną pobierającą te dane właśnie z rejestru i zbudować ja na typie AnsiString, a nie char.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Windows 7 - program napisany w BCB 6.0 - format daty

Nowy postprzez polymorphism » sobota, 6 listopada 2010, 11:24

Nie o to mi chodziło, lecz żeby tak jak w przypadku typy AnsiString, nie podawać rozmiaru bufora typu char, czyli nie określać z góry rozmiaru na 255

W przykładzie z vectorem nie musisz określać rozmiaru na sztywno, więc o co chodzi? Czytać bezpośrednio do AnsiStringa też nie możesz. Jedyne co możesz zrobić, to stworzyć bufor o wymaganej wielkości, wywołać funkcję i przepisać zawartość bufora do stringa.


(...) gdyż teoretycznie w przypadku LOCALE_SLONGDATE ten rozmiar może być większy.

U mnie ma 12 bajtów.





Do małych, tymczasowych alokacji można użyć funkcji alloca, która przydziela pamięć ze stosu, dzięki czemu alokacja jest szybsza i zapobiega fragmentacji pamięci:
KOD cpp:     UKRYJ  
int cch = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLONGDATE, 0, 0);
if(cch > 0)
{
        TCHAR* buff = (TCHAR*)alloca(sizeof(TCHAR) * cch); // równoznaczne z niestandardowym TCHAR buff[cch];
               
        cch = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLONGDATE, buff, cch);
        if(cch > 0)
        {
                cout << buff << '\n';
        }
}

Pamięci przydzielonej tą funkcją nie można zwalniać, ponieważ, jak wcześniej pisałem, jest ona pamięcią stosu. Dodatkowo pamięć ta ma zasięg lokalny, tak samo jak zwykła tablica zdefiniowana lokalnie, zatem nie można jej zwracać jako wynik działania funkcji. Ogólnie rzecz biorąc, ostrożnie z tą metodą alokacji pamięci.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości