KDE Core/QtMerge/QDateTime
The initial proposal for merging KDE features in Qt5 as presented at QtCS is documented on the QtCS wiki at http://developer.qt.nokia.com/groups/qt_contributors_summit/wiki/QDateTime
This page documents specific API proposals.
Full CLDR Date Format and Calendar System support
The CLDR Date Format support and Calendar System support are closely connected and need to be designed together, although they will be separately implemented.
The following API design is based on the CLDR standard,and is not Source Compatible with Qt4. The Qt4 API is inconsistent, incomplete, and requires modification to fully support CLDR, so the opportunity should be taken to fully overhaul the API. Most apps will be unaffected as they should simply be using the default toString()/fromString() methods.
Object Model
The object model will be:
QLocale - The locale container, provides type of calendar system, date/time formats, and date/time name translations for a given locale which will be used by the QDateTime for formatting. Existing class to be modified.
QCalendarSystem - A private virtual base class implementing Calendar System calculations. Derived implementations like QCalendarSystemGregorian will also be private. It is not intended to expose this class to public access. New class.
QDateTimeParser - Takes a QString, date/time format, QCalendarSystem, and QLocale and returns a QDateTime. Existing class to be modified.
QDateTimeFormatter - Takes a QDateTime and date/time format and returns a QString. New class.
QDate - Holds a date as a Julian Day number, a QCalendarSystem calculator instance for converting the JD to/from YMD, and a QLocale for use converting the JD to/from YMD and string formats. Existing class to be modified.
Note that by default the system QLocale and QCalendarSystem will be used by a default created QDate, but these can both be over-ridden using QDate::setLocale() and/or QDate::setCalendarSystem().
This object model is the inverse of the current KDE model, so some quirks may need to be sorted out during implementation. In particular the QCalendarSystem api will take a int for jd rather than a QDate which is not so good if the api is ever made public. However this scheme has teh advantage of keeping QCalendarSystem private so is good for a first attempt.
Alternative: If the above doesn't work too well then use a variant on the current KDE model. The QCalendarSystem object is embedded in the QLocale, with the QLocale embedded in the QDate. The problems here is that this will force QCalendarSystem to be public, and becomes a problem with setCalendar() needing to be on QLocale which breaks QLocales design.
Implementation Plan
The following phased implementation is planned:
- Create new private QCalendarSystem base class, move current calendar code from QDate into QCalendarSystem, change QDate to embed QCalendarSystem and make calls to it. All existing tests should still pass.
- Create new private QDateTimeFormatter class, move current formatting code from QLocale and QDateTime into QDateTimeFormatter, change QDateTime to make calls to it. All existing tests should still pass.
- Change QDateTimeFormatter and QDateTimeParser to fix the currently supported field codes to be CLDR compliant. Modify existing tests to ensure they still pass.
- Implement new formatting api but making calls to existing backend code, for options that don't yet have the backend coded just translate to a sensible replacement, i.e. for FullDate return LongDate. Only supported CalendarSystem is DefaultCalendar. All existing tests should still pass.
- Add to QDateTimeFormatter and QDateTimeParser the CLDR field codes that are already supported by existing QDate api. Write new tests.
- Convert unit tests from old api to new api. All existing tests should still pass.
- Convert widgets and other Qt code to new api. All existing tests should still pass.
- Remove old api. All existing tests should still pass.
- Modify QLocale CLDR backend to return full set of values for new api. Write new tests.
- Modify QLocale Mac backend to return full set of values for new api. Write new tests.
- Modify QLocale Windows backend to return full set of values for new api. Write new tests.
- Add QDateTime setLocale() support
- Add Era support
- Add Quarters support
- Add Ordinal Date support
- Add Week Date support
- Add Date Maths support
- Add more Calendar Systems
- Add QDate setCalendarSystem() support
API Changes
Replace the old Qt, QLocale and QDate enums:
// Merges both format and field type!
enum QLocale::FormatType { LongFormat, ShortFormat, NarrowFormat };
// Used for both month and day names!
enum QDate::MonthNameType { DateFormat = 0, StandaloneFormat };
enum Qt::DateFormat { TextDate, // default Qt
ISODate, // ISO 8601
SystemLocaleDate, // deprecated
LocalDate = SystemLocaleDate, // deprecated
LocaleDate, // deprecated
SystemLocaleShortDate,
SystemLocaleLongDate,
DefaultLocaleShortDate,
DefaultLocaleLongDate };
with new QLocale enums:
// CLDR format length attribute for date/time/number/currency
enum QLocale::StringFormat { FullFormat,
LongFormat,
MediumFormat,
ShortFormat };
// CLDR field width attribute
enum QLocale::FieldFormat { LongName, // e.g. January
ShortName, // e.g. Jan
NarrowName, // e.g. J
LongNumber, // e.g. 01
ShortNumber }; // e.g. 1
// CLDR context attribute
enum QLocale::FieldContext { FormatContext, // Use in a format
StandaloneContext }; // Use standalone
// CLDR calendar attribute
enum QLocale::CalendarSystem { DefaultCalendar = -1, // i.e. locale default
GregorianCalendar = 0,
... };
// CLDR year type attribute
// Would prefer in QDateTime namespace, but needed for QLocale::monthName()
enum QLocale::YearType { StandardYear, LeapYear }
enum QDateTime::DateTimeFormat { IsoFormat,
RfcFormat,
Rfc3339Format,
WeekFormat,
OrdinalFormat };
Alternative: Put in Qt:: NameSpace.
Replace the old QLocale and QDate name methods:
QString QLocale::monthName(int month, FormatType format = LongFormat) const;
QString QLocale::standaloneMonthName(int month, FormatType format = LongFormat) const;
QString QLocale::dayName(int weekday, FormatType format = LongFormat) const;
QString QLocale::standaloneDayName(int weekday, FormatType format = LongFormat) const;
QString QLocale::amText() const;
QString QLocale::pmText() const;
static QString QDate::shortMonthName(int month, MonthNameType type = QDate::DateFormat);
static QString QDate::shortDayName(int weekday, MonthNameType type = QDate::DateFormat);
static QString QDate::longMonthName(int month, MonthNameType type = QDate::DateFormat);
static QString QDate::longDayName(int weekday, MonthNameType type = QDate::DateFormat);
with new QLocale name methods:
QString QLocale::monthName(int month,
FieldFormat format = LongName,
FieldContext context = FormatContext,
YearType yearType = StandardYear,
CalendarSystem calendar = DefaultCalendar) const;
QString QLocale::weekdayName(int weekday,
FieldFormat format = LongName,
FieldContext context = FormatContext,
CalendarSystem calendar = DefaultCalendar) const;
QString QLocale::dayPeriodName(QTime time,
FieldFormat format = LongName,
FieldContext context = FormatContext,
CalendarSystem calendar = DefaultCalendar) const;
and extend later with new feature name methods:
QString QLocale::eraName(int year,
FieldFormat format = LongName,
FieldContext context = FormatContext,
CalendarSystem calendar = DefaultCalendar) const;
QString QLocale::quarterName(int quarter,
FieldFormat format = LongName,
FieldContext context = FormatContext,
CalendarSystem calendar = DefaultCalendar) const;
QString QLocale::calendarName(CalendarSystem calendar = DefaultCalendar,
FieldFormat format = LongName,
FieldContext context = FormatContext) const;
Note the QDate methods are removed as being redundent, see also the QDate::setLocale() method below. Alternatively they could remain in QDate but not as static's taking month/weekday number, but instead return the name for the QDate's value, however this is easily obtained anyway using toString().
Modify the QLocale date/time format methods to use the new enums:
QString QLocale::dateFormat(StringFormat format = LongFormat);
QString QLocale::timeFormat(StringFormat format = LongFormat);
QString QLocale::dateTimeFormat(StringFormat format = LongFormat);
Remove all the QLocale toString(), toDate(), toTime(), toDateTime() methods, all formatting/parsing to be done in QDate/QTime/QDateTime.
Replace all the QDate toString() and fromString() methods with the following:
QString QDate::toString(const QString &format) const;
QString QDate::toString(QLocale::StringFormat format = QLocale::LongFormat) const;
QString QDate::toString(QDateTime::DateTimeFormat format) const;
static QDate QDate::fromString(const QString &string, const QString &format);
static QDate QDate::fromString(const QString &string, QLocale::StringFormat format = QLocale::LongFormat);
static QDate QDate::fromString(const QString &string, QDateTime::DateTimeFormat format);
Repeat exactly the same for QTime and QDateTime.
Alternative: replace the method names toString() and fromString() with formatDate() and parseDate(), but this would break Source Compatibility for virtually every app.
Modify the existing string date field format codes to be CLDR compliant as follows:
ddd - Weekday - Change to EEE
dddd - Weekday - Change to EEEE
AP - AM/PM - Remove, already have A
ap - am/pm - Remove, already have a
h - Hour - Modify behaviour to match CLDR
hh - Hour - Modify behaviour to match CLDR
t - Timezone - Change to z
Add new CLDR date field format codes for existing or new api:
ddddd - Weekday narrow name
MMMMM - Month narrow name
y - Year without leading zeros
d - Day of Year
w - Week of Year
Y - Week Year
L - Stand-alone Month
e - Weekday
E - Weekday
c - Stand-alone Weekday
G - Era name
z - Timezone
Z - Timezone
v - Timezone
V - Timezone
Q - Quarter of Year
q - Stand-alone Quarter of Year
W - Week of Month
F - Day of Week In Month
Add the following new methods to support calendar systems and related features:
CalendarSystem QLocale::calendarSystem() // locale default calendar
QList<CalendarSystem> QLocale::calendarSystems() // locale preferred list
QList<CalendarSystem> QLocale::allCalendarSystems() // all calendars list
void QDate::setCalendarSystem(KLocale::CalendarSystem calendar);
QLocale::CalendarSystem QDate::calendarSystem();
void QDate::setLocale(const QLocale & locale);
QLocale QDate::locale();
int QDate::eraYear()
int QDate::monthsInYear()
int QDate::weeksInYear()
int QDate::daysInWeek()