Skip to content

Commit

Permalink
This changes the internal representation of time to UTC.
Browse files Browse the repository at this point in the history
Using UTC rather than localtime makes it possible to record programs during daylight savings time changes without overly complicating the code.

Unfortunately, the QDateTime initializers all either set the DateSpec to localtime or they set it do undefined. This means you can not use QDateTime::setTime_t(), QDateTime::currentDateTime(), QDateTime::fromString(), QDateTime::fromTime_t(), QDateTime::setDate(), QDateTime::setTime(), or QDateTime::setMSecsSinceEpoch() directly unless you follow it with a QDateTime::toUTC() or QDateTime::setDateSpec((Qt::UTC) depending on which method you use. You can use the QDateTime(QDate,QTime,Qt::TimeSpec) constructor, but only if you specify the Qt::TimeSpec.

To make time manipulation in UTC easier given these constraints several utility function have been to the MythDate namespace (currently these live in libmythbase/util.{h,cpp}.

QDateTime as_utc(const QDateTime&) -- Returns a copy of the QDateTime with the TimeSpec set to Qt::UTC, this can be used when pulling DATETIME values from the database. For Example, QDateTime tm = as_utc(query.value(0).toDateTime());

QDateTime current(bool stripped=false) -- Returns the current date and time in UTC. If stripped is set to true the millisecond portion of the time is stripped.

QString current_iso_string(bool stripped=false) -- Returns current(stripped).toString(Qt::ISODate). Purely for convenience.

QDateTime fromTime_t(uint s) -- Returns a QDateTime in UTC initialized from a time_t.

QDateTime fromString(const QString&) -- Returns a QDateTime in UTC initialized from a string in either Qt::ISODate format or "yyyyMMddhhmmss" format.

QDateTime fromString(const QString &date, const QString &format) -- Returns a QDateTime in UTC initialized using an arbitrary format, such as RFC822.

QString toString(const QDateTime &, uint format) -- Returns a formatted string in one of the MythTV recognized formats. The format should be one or more of the flags in MythDate::Format. These come in two flavors, formats intended for use in the database or filesystem such as kISODate, kFilename, kDatabase default to UTC, while formats intended for display default to local time. You can override these defaults with the kOverrideUTC and kOverrideLocal flags.

Traditionally MythTV has not set the timespec to Qt::UTC when dealing with UTC time, this presents problems when comparing times in local time to times in UTC. With the internal represetation of time in UTC it is important to either use these functions for initializing a QDateTime or to properly set the timespec otherwise time comparisons with times from Qt such as that returned from QFileInto::lastModified() will not work correction. As a corrilary, time represented in UTC with the timespec set correctly will compare correctly with a QDateTime in localtime with the timespec set correctly. So if you use these functions when initializing times represented in UTC you won't have any headaches dealing with the times returned from Qt functions.

Since Qt returns times in localtime from it's various functions you will need to convert these to UTC when saving them in a variable for later use. This is accomplished with the toUTC() function. For example, QDateTime mod_time = QFileInfo("x.mpg").toUTC(); This is mainly so that people reading your code can safely assume all times are in UTC which saves them from having to figure out from the code whether you are using localtime or UTC. Another reason for doing this is in case the the variable is saved to the database, we want all times in the database to be in UTC for consistency.
  • Loading branch information
daniel-kristjansson committed Aug 20, 2011
1 parent dd67c15 commit df47df3
Show file tree
Hide file tree
Showing 146 changed files with 1,342 additions and 1,273 deletions.
2 changes: 1 addition & 1 deletion mythplugins/mytharchive/mytharchive/archivesettings.cpp
Expand Up @@ -176,7 +176,7 @@ static HostComboBox *MythArchiveDateFormat()
HostComboBox *gc = new HostComboBox("MythArchiveDateFormat");
gc->setLabel(QObject::tr("Date format"));

QDate sampdate = QDate::currentDate();
QDate sampdate = MythDate::current().toLocalTime().date();
QString sampleStr =
QObject::tr("Samples are shown using today's date.");

Expand Down
2 changes: 1 addition & 1 deletion mythplugins/mytharchive/mytharchive/archiveutil.cpp
Expand Up @@ -191,7 +191,7 @@ ProgramInfo *getProgramInfoForFile(const QString &inFile)
if (bIsMythRecording)
{
uint chanid = chanID.toUInt();
QDateTime recstartts = myth_dt_from_string(startTime);
QDateTime recstartts = MythDate::fromString(startTime);
pinfo = new ProgramInfo(chanid, recstartts);
if (pinfo->GetChanID())
{
Expand Down
9 changes: 6 additions & 3 deletions mythplugins/mytharchive/mytharchive/importnative.cpp
Expand Up @@ -18,6 +18,7 @@
#include <mythdialogbox.h>
#include <mythsystem.h>
#include <exitcodes.h>
#include <util.h>

// mytharchive
#include "importnative.h"
Expand Down Expand Up @@ -84,7 +85,7 @@ static bool loadDetailsFromXML(const QString &filename, FileDetails *details)
details->subtitle = e.text();

if (e.tagName() == "starttime")
details->startTime = QDateTime::fromString(e.text(), Qt::ISODate);
details->startTime = MythDate::fromString(e.text());

if (e.tagName() == "description")
details->description = e.text();
Expand Down Expand Up @@ -248,7 +249,8 @@ void ArchiveFileSelector::itemSelected(MythUIButtonListItem *item)
m_xmlFile = m_curDirectory + "/" + fileData->filename;
m_progTitle->SetText(m_details.title);
m_progSubtitle->SetText(m_details.subtitle);
m_progStartTime->SetText(m_details.startTime.toString("dd MMM yy (hh:mm)"));
m_progStartTime->SetText(m_details.startTime.toLocalTime()
.ToString("dd MMM yy (hh:mm)"));
}
else
{
Expand Down Expand Up @@ -352,7 +354,8 @@ bool ImportNative::Create(void)

m_progTitle_text->SetText(m_details.title);

m_progDateTime_text->SetText(m_details.startTime.toString("dd MMM yy (hh:mm)"));
m_progDateTime_text->SetText(m_details.startTime.toLocalTime()
.ToString("dd MMM yy (hh:mm)"));
m_progDescription_text->SetText(
(m_details.subtitle == "" ? m_details.subtitle + "\n" : "") + m_details.description);

Expand Down
13 changes: 8 additions & 5 deletions mythplugins/mytharchive/mytharchive/recordingselector.cpp
Expand Up @@ -264,8 +264,8 @@ void RecordingSelector::titleChanged(MythUIButtonListItem *item)
m_titleText->SetText(p->GetTitle());

if (m_datetimeText)
m_datetimeText->SetText(p->GetScheduledStartTime()
.toString("dd MMM yy (hh:mm)"));
m_datetimeText->SetText(p->GetScheduledStartTime().toLocalTime()
.ToString("dd MMM yy (hh:mm)"));

if (m_descriptionText)
{
Expand Down Expand Up @@ -362,8 +362,10 @@ void RecordingSelector::OKPressed()
a->title = p->GetTitle();
a->subtitle = p->GetSubtitle();
a->description = p->GetDescription();
a->startDate = p->GetScheduledStartTime().toString("dd MMM yy");
a->startTime = p->GetScheduledStartTime().toString("(hh:mm)");
a->startDate = p->GetScheduledStartTime()
.toLocalTime().ToString("dd MMM yy");
a->startTime = p->GetScheduledStartTime()
.toLocalTime().ToString("(hh:mm)");
a->size = p->GetFilesize();
a->filename = p->GetPlaybackURL(false, true);
a->hasCutlist = p->HasCutlist();
Expand Down Expand Up @@ -410,7 +412,8 @@ void RecordingSelector::updateRecordingList(void)
MythUIButtonListItem* item = new MythUIButtonListItem(
m_recordingButtonList,
p->GetTitle() + " ~ " +
p->GetScheduledStartTime().toString("dd MMM yy (hh:mm)"));
p->GetScheduledStartTime().toLocalTime()
.ToString("dd MMM yy (hh:mm)"));
item->setCheckable(true);
if (m_selectedList.indexOf((ProgramInfo *) p) != -1)
{
Expand Down
21 changes: 14 additions & 7 deletions mythplugins/mytharchive/mytharchivehelper/main.cpp
Expand Up @@ -275,14 +275,16 @@ static int burnISOImage(int mediaType, bool bEraseDVDRW, bool nativeFormat)

static int doBurnDVD(int mediaType, bool bEraseDVDRW, bool nativeFormat)
{
gCoreContext->SaveSetting("MythArchiveLastRunStart",
QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm"));
gCoreContext->SaveSetting(
"MythArchiveLastRunStart",
MythDate::toString(MythDate::current(), MythDate::kDatabase));
gCoreContext->SaveSetting("MythArchiveLastRunStatus", "Running");

int res = burnISOImage(mediaType, bEraseDVDRW, nativeFormat);

gCoreContext->SaveSetting("MythArchiveLastRunEnd",
QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm"));
gCoreContext->SaveSetting(
"MythArchiveLastRunEnd",
MythDate::toString(MythDate::current(), MythDate::kDatabase));
gCoreContext->SaveSetting("MythArchiveLastRunStatus", "Success");
return res;
}
Expand Down Expand Up @@ -1754,13 +1756,18 @@ static void clearArchiveTable(void)
static int doNativeArchive(const QString &jobFile)
{
gCoreContext->SaveSetting("MythArchiveLastRunType", "Native Export");
gCoreContext->SaveSetting("MythArchiveLastRunStart", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm"));
gCoreContext->SaveSetting(
"MythArchiveLastRunStart",
MythDate::toString(MythDate::current(), MythDate::kDatabase));
gCoreContext->SaveSetting("MythArchiveLastRunStatus", "Running");

NativeArchive na;
int res = na.doNativeArchive(jobFile);
gCoreContext->SaveSetting("MythArchiveLastRunEnd", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm"));
gCoreContext->SaveSetting("MythArchiveLastRunStatus", (res == 0 ? "Success" : "Failed"));
gCoreContext->SaveSetting(
"MythArchiveLastRunEnd",
MythDate::toString(MythDate::current(), MythDate::kDatabase));
gCoreContext->SaveSetting("MythArchiveLastRunStatus",
(res == 0 ? "Success" : "Failed"));

// clear the archiveitems table if succesful
if (res == 0)
Expand Down
2 changes: 1 addition & 1 deletion mythplugins/mythgallery/mythgallery/iconview.cpp
Expand Up @@ -1123,7 +1123,7 @@ void IconView::HandleImport(void)

// Makes import directory samba/windows friendly (no colon)
QString idirname = m_currDir + "/" +
QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss");
MythDate::current().ToString("yyyy-MM-dd_hh-mm-ss");

importdir.mkdir(idirname);
importdir.setPath(idirname);
Expand Down
30 changes: 13 additions & 17 deletions mythplugins/mythmusic/mythmusic/filescanner.cpp
Expand Up @@ -200,26 +200,22 @@ int FileScanner::GetDirectoryId(const QString &directory, const int &parentid)
*
* \returns True if file has been modified, otherwise false
*/
bool FileScanner::HasFileChanged(const QString &filename, const QString &date_modified)
bool FileScanner::HasFileChanged(
const QString &filename, const QString &date_modified)
{
struct stat stbuf;

QByteArray fname = filename.toLocal8Bit();
if (stat(fname.constData(), &stbuf) == 0)
QFileInfo fi(filename);
QDateTime dt = fi.lastModified();
if (dt.isValid())
{
if (date_modified.isEmpty() ||
stbuf.st_mtime >
(time_t)QDateTime::fromString(date_modified,
Qt::ISODate).toTime_t())
{
return true;
}
QDateTime old_dt = MythDate::fromString(date_modified);
return !old_dt.isValid() || (dt > old_dt);
}
else {
else
{
LOG(VB_GENERAL, LOG_ERR, QString("Failed to stat file: %1")
.arg(filename));
return false;
}
return false;
}

/*!
Expand Down Expand Up @@ -617,7 +613,7 @@ void FileScanner::SearchDir(QString &directory)
{
if (*iter == kFileSystem)
AddFileToDB(iter.key());
else if (*iter == kDatabase)
else if (*iter == MythDate::kDatabase)
RemoveFileFromDB(iter.key ());
else if (*iter == kNeedUpdate)
UpdateFileInDB(iter.key());
Expand Down Expand Up @@ -685,7 +681,7 @@ void FileScanner::ScanMusic(MusicLoadedMap &music_files)
{
if ((iter = music_files.find(name)) != music_files.end())
{
if (music_files[name] == kDatabase)
if (music_files[name] == MythDate::kDatabase)
{
if (file_checking)
{
Expand Down Expand Up @@ -767,7 +763,7 @@ void FileScanner::ScanArtwork(MusicLoadedMap &music_files)
{
if ((iter = music_files.find(name)) != music_files.end())
{
if (music_files[name] == kDatabase)
if (music_files[name] == MythDate::kDatabase)
{
if (file_checking)
{
Expand Down
12 changes: 6 additions & 6 deletions mythplugins/mythmusic/mythmusic/metadata.cpp
Expand Up @@ -144,7 +144,7 @@ void Metadata::UpdateModTime() const
query.prepare("UPDATE music_songs SET date_modified = :DATE_MOD "
"WHERE song_id= :ID ;");

query.bindValue(":DATE_MOD", QDateTime::currentDateTime());
query.bindValue(":DATE_MOD", MythDate::current());
query.bindValue(":ID", m_id);

if (!query.exec())
Expand Down Expand Up @@ -456,11 +456,11 @@ void Metadata::dumpToDatabase()
query.bindValue(":FILENAME", sqlfilename);
query.bindValue(":RATING", m_rating);
query.bindValue(":FORMAT", m_format);
query.bindValue(":DATE_MOD", QDateTime::currentDateTime());
query.bindValue(":DATE_MOD", MythDate::current());
query.bindValue(":PLAYCOUNT", m_playcount);

if (m_id < 1)
query.bindValue(":DATE_ADD", QDateTime::currentDateTime());
query.bindValue(":DATE_ADD", MythDate::current());
else
query.bindValue(":ID", m_id);

Expand Down Expand Up @@ -699,8 +699,8 @@ void Metadata::toMap(MetadataMap &metadataMap)
else
metadataMap["length"] = QString().sprintf("%02d:%02d", em, es);

metadataMap["lastplayed"] = MythDateTimeToString(m_lastplay,
kDateFull | kSimplify | kAddYear);
metadataMap["lastplayed"] = MythDate::toString(m_lastplay,
MythDate::kDateFull | MythDate::kSimplify | MythDate::kAddYear);

metadataMap["playcount"] = QString::number(m_playcount);
metadataMap["filename"] = m_filename;
Expand All @@ -726,7 +726,7 @@ void Metadata::incRating()

void Metadata::setLastPlay()
{
m_lastplay = QDateTime::currentDateTime();
m_lastplay = MythDate::current();
m_changed = true;
}

Expand Down
4 changes: 2 additions & 2 deletions mythplugins/mythmusic/mythmusic/smartplaylist.cpp
Expand Up @@ -112,7 +112,7 @@ static QString evaluateDateValue(QString sDate)
{
if (sDate.startsWith("$DATE"))
{
QDate date = QDate::currentDate();
QDate date = MythDate::current().toLocalTime().date();

if (sDate.length() > 9)
{
Expand Down Expand Up @@ -2437,7 +2437,7 @@ SmartPLDateDialog::SmartPLDateDialog(MythMainWindow *parent, const char *name)
hbox->addWidget(caption);

// fixed date widgets
QDate date = QDate::currentDate();
QDate date = MythDate::current().toLocalTime().date();
hbox = new Q3HBoxLayout(vbox, (int)(10 * hmult));
fixedRadio = new MythRadioButton(this, "nopopsize");
fixedRadio->setText(tr("Fixed Date"));
Expand Down
12 changes: 7 additions & 5 deletions mythplugins/mythnetvision/mythnetvision/netsearch.cpp
Expand Up @@ -23,6 +23,7 @@
#include <metadata/videoutils.h>
#include <rssparse.h>
#include <mythcoreutil.h>
#include <util.h>

#include "netsearch.h"
#include "netcommon.h"
Expand Down Expand Up @@ -314,7 +315,7 @@ void NetSearch::cleanCacheDir()
LOG(VB_GENERAL, LOG_DEBUG, QString("Deleting file %1").arg(filename));
QFileInfo fi(filename);
QDateTime lastmod = fi.lastModified();
if (lastmod.addDays(7) < QDateTime::currentDateTime())
if (lastmod.addDays(7) < MythDate::current())
QFile::remove(filename);
}
}
Expand Down Expand Up @@ -520,10 +521,11 @@ void NetSearch::streamWebVideo()
return;
}

GetMythMainWindow()->HandleMedia("Internal", item->GetMediaURL(),
item->GetDescription(), item->GetTitle(), item->GetSubtitle(), QString(),
item->GetSeason(), item->GetEpisode(), QString(), item->GetTime().toInt(),
item->GetDate().toString("yyyy"));
GetMythMainWindow()->HandleMedia(
"Internal", item->GetMediaURL(),
item->GetDescription(), item->GetTitle(), item->GetSubtitle(),
QString(), item->GetSeason(), item->GetEpisode(), QString(),
item->GetTime().toInt(), item->GetDate().ToString("yyyy"));
}

void NetSearch::showWebVideo()
Expand Down
12 changes: 7 additions & 5 deletions mythplugins/mythnetvision/mythnetvision/nettree.cpp
Expand Up @@ -4,6 +4,7 @@
#include <QtAlgorithms>

// myth
#include <util.h>
#include <mythdb.h>
#include <mythcontext.h>
#include <mythdirs.h>
Expand Down Expand Up @@ -205,7 +206,7 @@ void NetTree::cleanCacheDir()
LOG(VB_GENERAL, LOG_DEBUG, QString("Deleting file %1").arg(filename));
QFileInfo fi(filename);
QDateTime lastmod = fi.lastModified();
if (lastmod.addDays(7) < QDateTime::currentDateTime())
if (lastmod.addDays(7) < MythDate::current())
QFile::remove(filename);
}
}
Expand Down Expand Up @@ -772,10 +773,11 @@ void NetTree::streamWebVideo()
return;
}

GetMythMainWindow()->HandleMedia("Internal", item->GetMediaURL(),
item->GetDescription(), item->GetTitle(), item->GetSubtitle(), QString(),
item->GetSeason(), item->GetEpisode(), QString(), item->GetTime().toInt(),
item->GetDate().toString("yyyy"));
GetMythMainWindow()->HandleMedia(
"Internal", item->GetMediaURL(),
item->GetDescription(), item->GetTitle(), item->GetSubtitle(),
QString(), item->GetSeason(), item->GetEpisode(), QString(),
item->GetTime().toInt(), item->GetDate().ToString("yyyy"));
}

void NetTree::showWebVideo()
Expand Down
6 changes: 3 additions & 3 deletions mythplugins/mythnetvision/mythnetvision/rsseditor.cpp
Expand Up @@ -164,7 +164,7 @@ void RSSEditPopup::parseAndSave(void)
removeFromDB(m_urlText, VIDEO_PODCAST);

if (insertInDB(new RSSSite(title, filename, VIDEO_PODCAST,
desc, link, author, download, QDateTime::currentDateTime())))
desc, link, author, download, MythDate::current())))
emit saving();
Close();
}
Expand Down Expand Up @@ -271,7 +271,7 @@ void RSSEditPopup::slotSave(QNetworkReply* reply)
else
download = false;

QDateTime updated = QDateTime::currentDateTime();
QDateTime updated = MythDate::current();
QString filename("");

if (file.isEmpty())
Expand Down Expand Up @@ -309,7 +309,7 @@ void RSSEditPopup::slotSave(QNetworkReply* reply)
HttpComms::getHttpFile(filename, thumbnailURL, 20000, 1, 2);
}
if (insertInDB(new RSSSite(title, filename, VIDEO_PODCAST, description, link,
author, download, QDateTime::currentDateTime())))
author, download, MythDate::current())))
emit saving();
}
Close();
Expand Down
6 changes: 3 additions & 3 deletions mythplugins/mythnews/mythnews/mythnews.cpp
Expand Up @@ -189,7 +189,7 @@ void MythNews::loadSites(void)
QString name = query.value(0).toString();
QString url = query.value(1).toString();
QString icon = query.value(2).toString();
QDateTime time; time.setTime_t(query.value(3).toUInt());
QDateTime time = MythDate::fromTime_t(query.value(3).toUInt());
bool podcast = query.value(4).toInt();
m_NewsSites.push_back(new NewsSite(name, url, time, podcast));
}
Expand Down Expand Up @@ -452,8 +452,8 @@ void MythNews::updateInfoView(MythUIButtonListItem *selected)
QString text(tr("Updated") + " - ");
QDateTime updated(site->lastUpdated());
if (updated.toTime_t() != 0) {
text += MythDateTimeToString(site->lastUpdated(),
kDateTimeFull | kSimplify);
text += MythDate::toString(site->lastUpdated(),
MythDate::kDateTimeFull | MythDate::kSimplify);
}
else
text += tr("Unknown");
Expand Down

0 comments on commit df47df3

Please sign in to comment.