Fix time zones with QDateTime fromMSecsSinceEpoch/toMSecsSinceEpoch.

Overwrite locale display for qml date to avoid taking account of timezone when using only dates.
This commit is contained in:
Julien Wadel 2022-12-05 12:02:19 +01:00
parent 1b8b57664c
commit e7767224a0
5 changed files with 47 additions and 29 deletions

View file

@ -89,7 +89,7 @@ QVariant ConferenceInfoListModel::data (const QModelIndex &index, int role ) con
if (role == Qt::DisplayRole)
return QVariant::fromValue(mList[row].get());
else if (role == Qt::DisplayRole +1 )
return QVariant::fromValue(mList[row].objectCast<ConferenceInfoModel>()->getDateTimeUtc().date());
return QVariant::fromValue(mList[row].objectCast<ConferenceInfoModel>()->getDateTimeSystem().date());
return QVariant();
}

View file

@ -141,14 +141,15 @@ std::shared_ptr<linphone::ConferenceInfo> ConferenceInfoModel::findConferenceInf
//------------------------------------------------------------------------------------------------
//Note conferenceInfo->getDateTime uses system timezone.
QDateTime ConferenceInfoModel::getDateTimeUtc() const{
return QDateTime::fromMSecsSinceEpoch(mConferenceInfo->getDateTime() * 1000).toUTC();
//Note conferenceInfo->getDateTime uses system timezone and fromMSecsSinceEpoch need a UTC
QDateTime ConferenceInfoModel::getDateTimeSystem() const{
QDateTime reference(QDateTime::fromMSecsSinceEpoch(mConferenceInfo->getDateTime() * 1000));// Get a reference for timezone offset computing
qint64 utcMs = (mConferenceInfo->getDateTime() - QTimeZone::systemTimeZone().offsetFromUtc(reference)) * 1000;// Remove system timezone offset to get UTC
return QDateTime::fromMSecsSinceEpoch(utcMs, QTimeZone::systemTimeZone()); // Return a System Timezone datetime based
}
QDateTime ConferenceInfoModel::getDateTimeSystem() const{
QDateTime utc = getDateTimeUtc();
return utc.addSecs(QTimeZone::systemTimeZone().offsetFromUtc(utc));
QDateTime ConferenceInfoModel::getDateTimeUtc() const{
return getDateTimeSystem().toUTC();
}
int ConferenceInfoModel::getDuration() const{
@ -230,11 +231,13 @@ LinphoneEnums::ConferenceSchedulerState ConferenceInfoModel::getConferenceSchedu
}
//------------------------------------------------------------------------------------------------
// Convert into UTC with TimeZone and pass system timezone to conference info
// Datetime is in Custom (Locale/UTC/System). Convert into system timezone for conference info
void ConferenceInfoModel::setDateTime(const QDateTime& dateTime){
QDateTime utc = dateTime.addSecs( -mTimeZone.offsetFromUtc(dateTime));
QDateTime system = utc.addSecs(QTimeZone::systemTimeZone().offsetFromUtc(utc));
mConferenceInfo->setDateTime(system.toMSecsSinceEpoch() / 1000);
QDateTime system = dateTime.toTimeZone(QTimeZone::systemTimeZone());//System
int offset = QTimeZone::systemTimeZone().offsetFromUtc(system);//Get UTC offset in system coordinate
system = system.addSecs( offset - mTimeZone.offsetFromUtc(dateTime));// Delta on offsets
mConferenceInfo->setDateTime(system.toMSecsSinceEpoch() / 1000 + offset);// toMSecsSinceEpoch() is UTC, add system reference.
emit dateTimeChanged();
}
@ -321,12 +324,11 @@ void ConferenceInfoModel::createConference(const int& securityLevel) {
CoreManager::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = false;
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
static std::shared_ptr<linphone::Conference> conference;
qInfo() << "Conference creation of " << getSubject() << " at " << securityLevel << " security, organized by " << getOrganizer();
qInfo() << "Conference creation of " << getSubject() << " at " << securityLevel << " security, organized by " << getOrganizer() << " for " << getDateTimeSystem().toString();
qInfo() << "Participants:";
for(auto p : mConferenceInfo->getParticipants())
qInfo() << "\t" << p->asString().c_str();
mConferenceScheduler = ConferenceScheduler::create();
mConferenceScheduler->mSendInvite = mInviteMode;
connect(mConferenceScheduler.get(), &ConferenceScheduler::invitationsSent, this, &ConferenceInfoModel::onInvitationsSent);

View file

@ -5,6 +5,8 @@ import Common 1.0
import Common.Styles 1.0
import Units 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
Item{
id: mainItem
property bool allYears : false // if false : years from today
@ -33,9 +35,10 @@ Item{
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
horizontalAlignment: Qt.AlignCenter
text: new Date(monthList.currentYear, monthList.currentMonth, 1).toLocaleString(Qt.locale(), 'MMMM yyyy')
text: new Date(monthList.currentYear, monthList.currentMonth, 15).toLocaleString(Qt.locale(), 'MMMM yyyy')// 15 because of timezones that can change the date for localeString
color: DatePickerStyle.title.color
font.pointSize: DatePickerStyle.title.pointSize
font.capitalization: Font.Capitalize
}
ActionButton{
isCustom: true
@ -62,7 +65,7 @@ Item{
}
property date selectedDate: new Date()
property int minYear: mainItem.allYears ? new Date(0,0,0).getFullYear() : new Date().getFullYear()
property int minYear: mainItem.allYears ? new Date(0,0,1).getFullYear() : new Date().getFullYear()
snapMode: ListView.SnapOneItem
orientation: Qt.Horizontal
@ -70,7 +73,7 @@ Item{
// One model per month
model: (new Date().getFullYear()- minYear + maxYears) * 12
currentIndex: 0
property int currentYear: Math.floor(currentIndex / 12) + minYear
property int currentMonth: currentIndex % 12
@ -87,7 +90,7 @@ Item{
property int year: Math.floor(index / 12) + monthList.minYear
property int month: index % 12
property int firstDay: new Date(year, month, 1).getDay()
GridLayout { // 1 month calender
id: grid
@ -105,9 +108,12 @@ Item{
delegate: Item{
id: cellItem
property int day: index - 7 // 0 = top left below Sunday (-7 to 41)
property int day: index - 7 // 0 = top left below Sunday (-7 to 41)
property int date: day - firstDay + 1 // 1-31
property bool selected : text.text != '-' && new Date(year, month, date).toDateString() == monthList.selectedDate.toDateString() && text.text && day >= 0
property date cellDate: new Date(year, month, date)
property bool selected : text.text != '-'
&& Utils.equalDate(cellDate, monthList.selectedDate)
&& text.text && day >= 0
width: grid.cellMinSize
height: width
@ -132,12 +138,12 @@ Item{
: cellItem.day < 0
? DatePickerStyle.cell.dayHeaderPointSize
: DatePickerStyle.cell.dayPointSize
font.bold: cellItem.day < 0 || cellItem.selected || new Date(year, month, cellItem.date).toDateString() == new Date().toDateString() // today
font.bold: cellItem.day < 0 || cellItem.selected || Utils.equalDate(cellItem.cellDate, new Date()) // today
text: {
if(cellItem.day < 0)
if(cellItem.day < 0){
// Magic date to set day names in this order : 'S', 'M', 'T', 'W', 'T', 'F', 'S' in Locale
return new Date(1,3,index).toLocaleString(Qt.locale(), 'ddd')[0]
else if(new Date(year, month, cellItem.date).getMonth() == month && (!hideOldDates || new Date(year, month, cellItem.date+1) >= new Date())) // new Date use time too
return Utils.exactDate(new Date(2000,9,index+1)).toLocaleString(Qt.locale(), 'ddd')[0].toUpperCase()
}else if(cellItem.cellDate.getMonth() == month && (!hideOldDates || new Date(year, month, cellItem.date+1) >= new Date())) // new Date use time too
return cellItem.date
else
return '-'
@ -152,7 +158,7 @@ Item{
enabled: text.text && text.text != '-' && cellItem.day >= 0
onClicked: {
monthList.selectedDate = new Date(year, month, cellItem.date)
monthList.selectedDate = cellItem.cellDate
mainItem.clicked(monthList.selectedDate)
}
}

View file

@ -563,12 +563,22 @@ function buildDate(date, time){
return dateTime
}
function equalDate(date1, date2){
return date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth() && date1.getDate() == date2.getDate()
}
function fromUTC(date){
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(),
date.getUTCDate(), date.getUTCHours(),
date.getUTCMinutes(), date.getUTCSeconds()));
}
// return EXACTLY what date has been set (not take account of Locale timezones, eg. Date(2000,0,1) will print january and not december if timezone lead there.)
// Use this function for toLocaleString/toLocaleDateString or other
function exactDate(date) {
var timeOffset = date.getTimezoneOffset() * 60000
var exactDate = new Date(date.valueOf() - timeOffset)
return exactDate
}
// -----------------------------------------------------------------------------
@ -796,4 +806,4 @@ function printObject(o) {
out += p + ': ' + o[p] + '\n';
}
return out;
}
}

View file

@ -20,8 +20,8 @@ DialogPlus {
property bool isNew: !conferenceInfoModel || conferenceInfoModel.uri === ''
property ConferenceInfoModel conferenceInfoModel: ConferenceInfoModel{}
onConferenceInfoModelChanged: {
dateField.setDate(conferenceManager.conferenceInfoModel.dateTimeUtc);
timeField.setTime(conferenceManager.conferenceInfoModel.dateTimeUtc);
dateField.setDate(conferenceManager.conferenceInfoModel.dateTime);
timeField.setTime(conferenceManager.conferenceInfoModel.dateTime);
selectedParticipants.setAddresses(conferenceInfoModel)
}
property bool forceSchedule : false
@ -299,9 +299,9 @@ DialogPlus {
}
function setDate(date){
currentDate = date
text = date.toLocaleDateString(scheduleForm.locale, Qt.ISODate)
text = Utils.exactDate(date).toLocaleDateString(scheduleForm.locale, Qt.ISODate)
}
text: conferenceManager.conferenceInfoModel ? conferenceManager.conferenceInfoModel.dateTime.toLocaleDateString(scheduleForm.locale, Qt.ISODate) : ''
text: conferenceManager.conferenceInfoModel ? Utils.exactDate(conferenceManager.conferenceInfoModel.dateTime).toLocaleDateString(scheduleForm.locale, Qt.ISODate) : ''
icon: 'drop_down_custom'
MouseArea{
anchors.fill: parent