Changing the way QDate displays date format - qt

My app has a has a QTreeWidget that takes a QDate in one of its columns. Since the columns accept QVariants they can hold practically any kind of data. I've found that the TreeWidget must use the actual QDate objects instead of QStrings for the column sorting functionality to work correctly. If I use QStrings for dates, they won't sort in the proper chronological order but rather by the numerical values of the strings. (which is wrong!) My program supports several date formats: USA Style, European style, and ISO-8601 style. I would like to keep everything consistent throughout the app depending on which date format the user has chosen.
However, I noticed that QDate only displays dates in MM/DD/YYYY format. There's also a strange bug where the QDate displays MM/DD/YYYY on Windows but the exact same code displays MM/DD/YY on Linux. How can I get the QDate to show dates in YYYY/MM/DD or DD/MM/YYYY format without converting to a QString? It is essential to keep everything in QDate format so I don't break the column sort function in the QTreeWidget.
Here's my code that converts the QString to a QDate: (nextitem is a QStringList)
// Convert QString date to QDate to make it sort correctly
QDate entrydate;
QString id=nextitem.at(2);
id=id.remove("/");
QString datepattern;
switch(Buffer::date_format){
case 0: // European
datepattern="ddMMyyyy";
break;
case 1: // USA Style
datepattern="MMddyyyy";
break;
case 2: // ISO
datepattern="yyyyMMdd";
break;
}
entrydate=QDate::fromString(id,datepattern);

QDate follows the current settings in the operating system. If that setting happens to be MM/DD/YY, then that's what you'll get. Note: this is what the user wants. A uniform date format in all applications.
The setting is also influenced by the current locale settings in the OS. In the USA for example the default would be MM/DD/YY, while in most European countries it's DD/MM/YY.
In other words: don't worry about it. It's not a bug, it's a feature. And you shouldn't try to work around it. Users don't want their applications ignoring their system settings. If my system is set to display dates in MM/DD/YY, I certainly wouldn't want your app doing its own thing and showing me dates in YYYY/MM/DD format instead.

You can use this code:
QVariant var = item->data(i, Qt::DisplayRole);
if (var.type() == QVariant::DateTime)
{
QDateTime dt = var.value<QDateTime>();
QString value = dt.toString("yyyyMMdd"); // Or whatever format you need
}
else
QString value = item->text(i);

Related

Default text format for QTextEdit

I don't understand. I setup char format, block format, root frame format, and page size for all of the text in QTextEdit control. And then if I manually delete all the text, and start to type new one, or if I select all text and paste new one from buffer, then voilĂ ! - all the formatting loses.
Is it possible to set some default format for QTextEdit (char's, block's, page, etc.)?
I've solved it the next way.
Handled QTextEdit::currentCharFormatChanged signal(as vahancho promted), and call QTextEdit::setTextCursor with needed formatting cursor. It solves the problem with char and block format.
For the pageSize and rootFrame's format, I've handled QTextEdit::document::documentLayout's update signal and if rootFrame format or pageSize of the document was changed, then resetup the needed sizes again.

Qt LineEdit setInputMask() with setText() and QRegExp

I have a QLineEdit for Date in mm/dd/yyyy format. I am getting input using the keyboard and not using QDateEdit because of the requirement. And when the lineEdit comes to view, it has to show to the user the current date. I need the following for the lineEdit.
I need the two slashes always to be displayed and the cursor has to skip while entering or deleting.
I should not allow the user to enter an invalid date i.e while entering itself the lineEdit should not get invalid numbers.
I have to set the current date as the default text when the lineEdit comes to view.
For the first point, I tried using setInputMask("99/99/9999") but with this I can't set the current date using setText(). And how to use QRegExp to not to allow lineEdit get an invalid number while employing setInputMask()?
QDateEdit will serve your purpose.
use setDisplayFormat("dd/MM/yyyy").
QDateEdit wont allow invalid dates
You can use QDateEdit::setDate() obtained from
QDateTime::currentDateTime()
For setting text into QLineEdit with setInputMask("99/99/9999") you should format text depending on your mask:
lineEdit.setText("{:02d}/{:02d}/{:04d}".format(m, d, y))
Alternatively, you can temporary disable InputMask, format your date without /, set it and re-enable InputMask. But make sure that number of symbols in every part is correct.
lineEdit.setInputMask("")
lineEdit.setText(date_str.replace("/", ""))
lineEdit.setInputMask("99/99/9999")

getTimezoneOffset does not work all the time

I register the following javascript on my web page. When the user posts back, SOMETIMES the txtTimeZoneOffSet hidden field comes back as blank. When I test on my computer, I always get a value. It happens on different browsers (I.E, FireFox, and Safari).
I am trying to get the users offset, so when they enter a date, I can convert it to UTC on the server and deal with everything in the same timezone, then when I render dates back out to them, I make sure it is in their timezone.
<script type='text/javascript'>
$(window).load(function () {
var d = new Date();
var tz = d.getTimezoneOffset();
$('#txtTimeZoneOffSet').val(tz / 60);
});
</script>
Does anyone see why this would not work 100% of the time?
The jQuery looks fine to me, so I don't see why it wouldn't work unless JavaScript was disabled or you didn't load jQuery.
However, you are worked on a flawed assumption that the user's current offset will be the same for all dates. In any time zone that has daylight saving time, it could be wrong.
The better approach would be to convert to UTC on the browser. Or at least use the date/time in question in the call to getTimezoneOffset.
UPDATED ANSWER
In response to your question, the code you have now will get the current offset already. You are just not guaranteed that it will be the same offset for any date they might enter. For example:
<input type="text" id="someDate" />
var someDateString = $('#someDate').val();
var dt = new Date(someDateString);
var offset = dt.getTimezoneOffset();
Since the value of the text input is variable, in many time zones you will get a different offset for January than you will for June. So the better thing would be to just convert it to UTC on the browser:
var someDateString = $('#someDate').val();
var dt = new Date(someDateString);
var s = dt.toISOString();
The string s will be in ISO8601 format, and will already be converted to UTC.
Of course, if it were me I would do this using moment.js - since it gives you much better control of how the input string is parsed.
This approach is usually good enough. HOWEVER, if there is any chance you will have to do this conversion on the server, perhaps because the user is not present, then you must know their time zone. Not just the offset, but the actual time zone. See "Time Zone != Offset" in the timezone tag wiki.
The best way is to ask them for it. A map-based picker like this one is a nice touch. You can even guess at a default selection using jsTimezoneDetect. Ultimately you are after a string identifier like America/New_York that you can use on your server. In .Net you can use these with the TZDB provider in Noda Time.
If you don't want any fancy libraries, you can stick with Windows time zones, and present a dropdown list from TimeZoneInfo.GetSystemTimeZones(), where the .Id is the key and the .DisplayName is the value.

How can I make input fields accept locale dependent number formatting?

I'm working on a Spring MVC Project and ran into a problem with the internationalization in forms, especially the number formatting.
I already use fmt:formatNumber to format the numbers according to the current selected locale.
<fmt:formatNumber value="${object[field]}"/>
Like this, number formatting works well when I display numbers. But how about the forms?
At the moment, the input fields that are supposed to receive float values are prefilled with 0.0 and expect me to use "." as decimal separator, no matter what locale is selected. Values containing "," are refused by the server (...can not convert String to required type float...).
How can I make my input fields use and accept the appropriate number format as well?
Did you have a look at #NumberFormat? If you annotate the property the input field is bound to, this should result in the proper formatting. Something like:
#NumberFormat(style = Style.NUMBER)
private BigDecimal something;
This style is the "general-purpose number format for the current locale". I guess, the current locale is determined threadwise from the LocaleContextHolder.
Your app needs to be annotation-driven, also see the section "Annotation-driven Formatting" in the docs.
You might want to take a look at the DecimalFormatSymbols as suggested in this answer.

Displaying UTF-8 characters in a PlainTextEdit

I'm trying to display Chinese characters encoded in UTF-8 in a PlainTextEdit control, but it doesn't render them properly.
My data comes from a database and I know that the string I get in Qt is correct (the bytes are the same as in the database). Once I have the Chinese character in a QString, I tried various things to display it but always results in either question marks or random ASCII characters:
QString chineseChar = query.value(fieldNo).toString(); // get the character
ui->plainTextEdit->appendPlainText(chineseChar); // doesn't work
ui->plainTextEdit->appendPlainText(chineseChar.toUtf8()); // doesn't work
ui->plainTextEdit->appendPlainText(QString::fromUtf8(chineseChar.toAscii()); // doesn't work
Any suggestion on how to handle that?
"My data comes from a database and I know that the string I get in Qt is correct (the bytes are the same as in the database)."
How did you check that? Try with chineseChar.toUtf8().toHex().
Once your string data is in a QString, all UI elements accepting a QString will handle it correctly. Usually the error happens when converting from plain text data(const char*/QByteArray) to the QString.
The conversions here:
ui->plainTextEdit->appendPlainText(chineseChar.toUtf8()); // doesn't work
ui->plainTextEdit->appendPlainText(QString::fromUtf8(chineseChar.toAscii()); // doesn't work
convert the unicode string to a bytearray, and then implicitely back to a QString, as those methods expect a QString.
I suggest you define QT_NO_CAST_FROM_ASCII and QT_NO_CAST_TO_ASCII to avoid any unwanted QByteArray<->QString conversions.
If the string is wrong, the error usually happened before, when converting from QByteArray/const char* to QString, i.e. in query.value(fieldNo).toString(). Try with:
QString chineseChar = QString::fromUtf8( query.value(fieldNo).toByteArray() );
If that doesn't help, the problem is somewhere in QtSQL assuming the wrong encoding for the data it receives from the database.

Resources