Display month and day in localized format - qt

I need to get correct month and day format for various locales.
I have QLable and QDate, label must display month and day. I try format date by QLocale.
//Yes, I got system locale and set is as default
QLocale::toString(date, "MMMM d");
But result is incorrect.
For example, "MMMM d" in German locale equal to:
"d. MMMM"
for French is:
"d MMMM"
How to transform "MMMM d" format to locale settings in Qt 4.8?
Thanks!
P.S. In javascript I use following code
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
var options = {month: 'long', day: 'numeric' };
console.log(date.toLocaleDateString('de-DE', options));

One way to do it would be to parse QLocale::LongFormat:
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QList<QLocale> locales;
locales << QLocale(QLocale::English);
locales << QLocale(QLocale::German);
locales << QLocale(QLocale::French);
locales << QLocale(QLocale::Russian);
locales << QLocale(QLocale::Chinese);
locales << QLocale(QLocale::Korean);
foreach(QLocale locale, locales) {
QString format = locale.dateFormat(QLocale::LongFormat);
QRegExp rx("([^d]d(?!d)[^,;]?\\s?|M+.?){2}");
rx.indexIn(format);
QString localed = rx.cap(0).trimmed();
qDebug() << locale.bcp47Name() << "\t" << localed << "\t" << locale.toString(QDateTime::currentDateTime(), localed);
}
return app.exec();
}
Outputs:
"en-US" "MMMM d" "March 17"
"de-DE" "d. MMMM" "17. März"
"fr-FR" "d MMMM" "17 mars"
"ru-RU" "d MMMM" "17 марта"
"zh-CN" "M月d日" "3月17日"
"ko-KR" "M월 d일" "3월 17일"

So, I used ICU library. DateTimePatternGenerator solve my problem

Related

Do QString's toUpper()/toLower() member functions only convert Latin alpha characters?

According to the documentation QString's toUpper() and toLower() member functions convert in the C-locale. Does it mean that only Posix Portable Character Set characters (Latin A-Z/a-z) are converted and any international unicode characters are left as-is?
We can easily test this with the simple test program here:
#include <QString>
#include <iostream>
int main()
{
QString s("БΣTest3φب");
std::cout << "String: " << s.toStdString() << std::endl;
std::cout << "Lower: " << s.toLower().toStdString() << std::endl;
std::cout << "Upper: " << s.toUpper().toStdString() << std::endl;
return 0;
}
Which returns:
09:48:48: Starting /home/tzig/test/test ...
String: БΣTest3φب
Lower: бσtest3φب
Upper: БΣTEST3Φب
09:48:49: /home/tzig/test/test exited with code 0
So we know that:
Cyrillic letters work fine
Latin letters work fine
Numbers are untouched
Greek letters work fine
Arabic letters don't have uppercase/lowercase so they are untouched
Feel free to test other Unicode characters with the test program.

Converting ISO::DateTime to number format

I want to change the date time format to numbers only so that it can be incremented.
Current Implementation is saved as QString 2019-03-13T09:01:22+01:0
Expected result: 201903120858031
qt is a really powerful framework, you are just coding a solution in a wrong way.
Imagine the pain in the back just validating dates, leap years etc etc
every date and dateTime has the methods to do calendar math operations.
see this example as ref:
//
QDateTime dateOrigin = QDateTime::currentDateTime();
QDateTime ReturnDate = QDateTime::currentDateTime();
QString isoDate{dateOrigin.toString(Qt::ISODate)};
qDebug() << "before: " << isoDate;
ReturnDate = dateOrigin.addDays(1);
ReturnDate = dateOrigin.addMonths(1);
ReturnDate = dateOrigin.addYears(1);
qDebug() << "after: " << ReturnDate.toString(Qt::ISODate);
//
update:
lets suppose that 201903120858031 is a date time formated as yyyyMMddHHmmss, then you can convert that to a long
//201903120858031
//yyyyMMddHHmmss
qDebug() << "after: " << ReturnDate.toString("yyyyMMddHHmmss");
qDebug() << "after as long number: " << ReturnDate.toString("yyyyMMddHHmmss").toLong();
producing the output:
before: "2019-02-28T12:43:33"
after: "20200228124333"
after as number: 20200228124333

Unexpected Behavior of QRegularExpression

I've just started switching to QRegularExpression, and I'm using it to tokenize a string with multiple delimiter possibilities. I've encountered a surprising behavior, which seems to me to be a bug. I'm using Qt 5.5.1 on Windows.
Here's sample code:
#include <QRegularExpression>
#include <QString>
#include <QtDebug>
int main(int argc, char *argv[])
{
Q_UNUSED (argc);
Q_UNUSED (argv);
QRegularExpression regex ("^ ");
qDebug () << "Expected: " << QString ("M 100").indexOf(regex);
qDebug () << "NOT expected:" << QString ("M 100").indexOf(regex, 1);
qDebug () << "Expected: " << QString (" 100").indexOf(regex);
QRegularExpression regex1 (" ");
qDebug () << "Expected: " << QString ("M 100").indexOf(regex1);
}
And the output:
Expected: -1
NOT expected: -1
Expected: 0
Expected: 1
The use of the caret (^) when used with a starting position other than 0 in the "indexOf" call is preventing the expression from matching. Intuitively, I expected that the caret matches the string at the position that I specified. Instead, it simply never matches.
I'm going to switch my tokenizing to use splitRref to avoid this problem. While that's probably slightly cleaner anyway, I need to understand whether this is correct behavior or if I should be reporting a bug to Qt.
UPDATE: Using splitRef doesn't entirely solve my problem because I need to use a regular expression to detect if some tokens are floating point numbers, and I can't use a QRegularExpression with QStringRef. For that possibility, I have to convert my QStringRef token into an actual QString, which was what I was trying to avoid in the first place.
^ matches at the beginning of the subject string, or after a newline when in multiline mode. The offset does not alter these semantics. Hence, matching /^ / (in regex notation) against M 100 at offset 1 correctly results in no match.
Perhaps you want \G? From pcrepattern(3):
\G matches at the first matching position in the subject
The \G assertion is true only when the current matching position is at the start point of the match, as specified by the startoffset argument of pcre_exec(). It differs from \A when the value of startoffset is non-zero.
With that, this code:
QRegularExpression regex ("\\G ");
qDebug () << "Expected: " << QString ("M 100").indexOf(regex);
qDebug () << "NOT expected:" << QString ("M 100").indexOf(regex, 1);
qDebug () << "Expected: " << QString (" 100").indexOf(regex);
prints
Expected: -1
NOT expected: 1
Expected: 0

Qt QDateTime toString("h:m:s ap") ap/a/AP/a missing

I've noted the "ap/a/AP/a" is missing while converting a date to string. For "h:m:s ap", i.e., I get "11:5:42 ". The same happens for each of the "ap/a/AP/a" forms.
What I'm missing?
void DecoderBr1::recordOnFile(QDateTime dateTime, QByteArray ba)
{
QString filename(dateTime.toString("yyyy MMMM dd#HH.mm.ss zzz ap"));
filename.append(".log");
Recorder recorder;
recorder.recordFile(filename, ba);
}
It depends on your locale. Not every locale support AM/PM format.
For example, my default locale is "it_IT" and does not print "AM/PM". Setting another locale (e.g. "en_EN") instead works as expected.
QDateTime t = QDateTime::fromString("2015-07-16T19:20:30+01:00", Qt::ISODate);
QString st = t.toString("yyyy MMMM dd#HH.mm.ss zzz ap");
QString locale_st_HH = QLocale("en_EN").toString(t, "yyyy MMMM dd#HH.mm.ss zzz ap");
QString locale_st_hh = QLocale("en_EN").toString(t, "yyyy MMMM dd#hh.mm.ss zzz ap");
qDebug() << st;
// With italian locale does not print AM/PM
// "2015 luglio 16#19.20.30 000 "
qDebug() << locale_st_HH;
// With en_EN locale it works
//"2015 July 16#19.20.30 000 pm"
qDebug() << locale_st_hh;
// With en_EN locale it works
// With hh it prints 07 pm instead of 19 pm // Credits to #t3ft3l--i
//"2015 July 16#07.20.30 000 pm"
Not all locale support this format of QDateTime output.
For result you are need create variable QLocale with parameters locale(language, country), which support it. For example:
QLocale eng(QLocale::English, QLocale::UnitedStates);
Then you can use QLocale::toString() method with chosen locale like this:
qDebug() << eng.toString(datetime, "yyyy MMMM dd#HH.mm.ss zzz ap");
Works for me at your example. And this way don't substitute your native locale.

Reading more than one value into variables using QInputDialog

I have to write a small QT program that reads in 3 mark percentages separated by commas and then do some further calculations on the marks... I have to use QInputDialog to do this but it seems like it's only possible to read in one value at a time.
at this stage I am only trying to read in and display the three marks.
When I run this code QTCreator stops working and I have to end the process in task manager.
Any idea how I can approach this would be much appreciated. Should I read in a string and then convert that to double values or is there a simpler way?
Thanks in advance.
Code:
#include <QTGui>
#include <QApplication>
#include <QString>
#include <QTextStream>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextStream cin(stdin, QIODevice::ReadOnly);
QTextStream cout(stdout, QIODevice::WriteOnly);
double mark1, mark2, mark3;
double passMarkNeeded = 0;
QInputDialog::getDouble(0, "Enter marks", "Marks", 1);
cin >> mark1 >> mark2 >> mark3;
cout << "User entered " << mark1 << mark2 << mark3;
return EXIT_SUCCESS;
}
Obviously you cannot use QInputDialog::getDouble because it won't allow you to input 3 values separated by commas. You should use QInputDialog::getText, QString::split and QString::toDouble:
QStringList list = QInputDialog::getText(0, "Input values", "Input values:").split(",");
if (list.count() == 3) {
double a = list[0].toDouble(),
b = list[1].toDouble(),
c = list[2].toDouble();
qDebug() << "Values:" << a << b << c;
}
I'm not sure why you use QInputDialog and the standard input (cin). QInputDialog is for GUI apps, and cin is console apps. It's strange and pointless to use them together in such a way.

Resources