Commit 53153260 authored by Claudio Cambra's avatar Claudio Cambra
Browse files

Add a date parser that works around JS dumb handling of shortened year strings

It works by filling in, from left to right, the digits missing from a shortened year string according to the current year.

For instance, if the user provides '01/01/7', this will be amended to be '01/01/2027', '01/01/07' to '01/01/2007', etc.

Fixes #95
parent b1dd5583
Pipeline #187169 failed with stage
in 4 minutes and 3 seconds
......@@ -6,15 +6,17 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
import "dateutils.js" as DateUtils
QQC2.ComboBox {
id: root
signal newDateChosen(int day, int month, int year)
property int timeZoneOffset: 0
property string display: dateTime.toLocaleString(Qt.locale(), Locale.NarrowFormat) // Can override for better C++ time strings
property string display: dateTime.toLocaleDateString(Qt.locale(), Locale.NarrowFormat) // Can override for better C++ time strings
property date dateTime: new Date()
property date dateFromText: Date.fromLocaleDateString(Qt.locale(), editText, Locale.NarrowFormat)
property date dateFromText: DateUtils.parseDateString(editText)
property bool validDate: !isNaN(dateFromText.getTime())
onDateTimeChanged: {
......@@ -25,14 +27,17 @@ QQC2.ComboBox {
editable: true
editText: activeFocus ? editText : display
onEditTextChanged: {
onActiveFocusChanged: {
// Set date from text here because it otherwise updates after this handler
dateFromText = Date.fromLocaleDateString(Qt.locale(), editText, Locale.NarrowFormat);
// Also make sure to only update after we switch from this field's focus to something else
if(!activeFocus) {
dateFromText = DateUtils.parseDateString(editText);
if (validDate && activeFocus) {
datePicker.selectedDate = dateFromText;
datePicker.clickedDate = dateFromText;
newDateChosen(dateFromText.getDate(), dateFromText.getMonth() + 1, dateFromText.getFullYear());
if (validDate) {
datePicker.selectedDate = dateFromText;
datePicker.clickedDate = dateFromText;
newDateChosen(dateFromText.getDate(), dateFromText.getMonth() + 1, dateFromText.getFullYear());
}
}
}
......
......@@ -149,3 +149,43 @@ function unadjustDateTimeToLocalTimeZone(dateTime, timeZoneOffset) {
// Undoes what prior func does
return new Date(dateTime.getTime() - (timeZoneOffset * 1000) - (new Date().getTimezoneOffset() * 60 * 1000));
}
function parseDateString(dateString) {
function defaultParse() {
return Date.fromLocaleDateString(Qt.locale(), dateString, Locale.NarrowFormat);
}
const dateStringDelimiterMatches = dateString.match(/\D/);
if(dateStringDelimiterMatches.length === 0) { // Let the date method figure out this weirdness
return defaultParse();
}
const dateStringDelimiter = dateStringDelimiterMatches[0];
const localisedDateFormatSplit = Qt.locale().dateFormat(Locale.NarrowFormat).split(dateStringDelimiter);
const localisedDateYearPosition = localisedDateFormatSplit.findIndex((x) => /y/gi.test(x));
let splitDateString = dateString.split(dateStringDelimiter);
let userProvidedYear = splitDateString[localisedDateYearPosition]
const dateNow = new Date();
const stringifiedCurrentYear = dateNow.getFullYear().toString();
// If we have any input weirdness, or if we have a fully-written year (e.g. 2022 instead of 22) then use default parse
if(splitDateString.length === 0 || splitDateString.length > 3 || userProvidedYear.length >= stringifiedCurrentYear.length) {
return defaultParse();
}
let fullyWrittenYear = userProvidedYear.split("");
const digitsToAdd = stringifiedCurrentYear.length - fullyWrittenYear.length;
for(let i = 0; i < digitsToAdd; i++) {
fullyWrittenYear.splice(i, 0, stringifiedCurrentYear[i])
}
fullyWrittenYear = fullyWrittenYear.join("");
let fixedSplitDateString = splitDateString;
fixedSplitDateString[localisedDateYearPosition] = fullyWrittenYear;
const fixedDateString = fixedSplitDateString.join(dateStringDelimiter);
return Date.fromLocaleDateString(Qt.locale(), fixedDateString, Locale.NarrowFormat);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment