wxFileName::Get/SetTimes() finally seem to work under Windows
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14827 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
12132b3789
commit
6dbb903bb9
@ -140,7 +140,10 @@ following functions:
|
||||
\membersection{Operations}
|
||||
|
||||
These methods allow to work with the file creation, access and modification
|
||||
times:
|
||||
times. Note that not all filesystems under all platforms implement these times
|
||||
in the same way. For example, the access time under Windows has a resolution of
|
||||
one day (so it is really the access date and not time). The access time may be
|
||||
updated when the file is executed or not depending on the platform.
|
||||
|
||||
\helpref{GetModificationTime}{wxfilenamegetmodificationtime}\\
|
||||
\helpref{GetTimes}{wxfilenamegettimes}\\
|
||||
@ -400,9 +403,9 @@ Return the short form of the path (returns identity on non-Windows platforms)
|
||||
|
||||
\membersection{wxFileName::GetTimes}\label{wxfilenamegettimes}
|
||||
|
||||
\constfunc{bool}{GetTimes}{\param{wxDateTime* }{dtAccess}, \param{wxDateTime* }{dtMod}, \param{wxDateTime* }{dtChange}}
|
||||
\constfunc{bool}{GetTimes}{\param{wxDateTime* }{dtAccess}, \param{wxDateTime* }{dtMod}, \param{wxDateTime* }{dtCreate}}
|
||||
|
||||
return the last access, last modification and last change times
|
||||
return the last access, last modification and creation times
|
||||
(any of the pointers may be NULL)
|
||||
|
||||
|
||||
@ -584,7 +587,7 @@ full name is the file name + extension (but without the path)
|
||||
|
||||
\membersection{wxFileName::SetTimes}\label{wxfilenamesettimes}
|
||||
|
||||
\func{bool}{SetTimes}{\param{const wxDateTime* }{dtCreate}, \param{const wxDateTime* }{dtAccess}, \param{const wxDateTime* }{dtMod}}
|
||||
\func{bool}{SetTimes}{\param{const wxDateTime* }{dtAccess}, \param{const wxDateTime* }{dtMod}, \param{const wxDateTime* }{dtCreate}}
|
||||
|
||||
set the file creation and last access/mod times
|
||||
(any of the pointers may be NULL)
|
||||
|
@ -173,20 +173,20 @@ public:
|
||||
|
||||
// time functions
|
||||
|
||||
// set the file creation and last access/mod times
|
||||
// set the file last access/mod and creation times
|
||||
// (any of the pointers may be NULL)
|
||||
bool SetTimes(const wxDateTime *dtCreate,
|
||||
const wxDateTime *dtAccess,
|
||||
const wxDateTime *dtMod);
|
||||
bool SetTimes(const wxDateTime *dtAccess,
|
||||
const wxDateTime *dtMod,
|
||||
const wxDateTime *dtCreate);
|
||||
|
||||
// set the access and modification times to the current moment
|
||||
bool Touch();
|
||||
|
||||
// return the last access, last modification and last change times
|
||||
// return the last access, last modification and create times
|
||||
// (any of the pointers may be NULL)
|
||||
bool GetTimes(wxDateTime *dtAccess,
|
||||
wxDateTime *dtMod,
|
||||
wxDateTime *dtChange) const;
|
||||
wxDateTime *dtCreate) const;
|
||||
|
||||
// convenience wrapper: get just the last mod time of the file
|
||||
wxDateTime GetModificationTime() const
|
||||
|
@ -90,7 +90,7 @@
|
||||
#undef TEST_ALL
|
||||
static const bool TEST_ALL = TRUE;
|
||||
#else
|
||||
#define TEST_WCHAR
|
||||
#define TEST_FILETIME
|
||||
|
||||
static const bool TEST_ALL = FALSE;
|
||||
#endif
|
||||
@ -982,8 +982,8 @@ static void TestFileGetTimes()
|
||||
{
|
||||
wxFileName fn(_T("testdata.fc"));
|
||||
|
||||
wxDateTime dtAccess, dtMod, dtChange;
|
||||
if ( !fn.GetTimes(&dtAccess, &dtMod, &dtChange) )
|
||||
wxDateTime dtAccess, dtMod, dtCreate;
|
||||
if ( !fn.GetTimes(&dtAccess, &dtMod, &dtCreate) )
|
||||
{
|
||||
wxPrintf(_T("ERROR: GetTimes() failed.\n"));
|
||||
}
|
||||
@ -992,9 +992,9 @@ static void TestFileGetTimes()
|
||||
static const wxChar *fmt = _T("%Y-%b-%d %H:%M:%S");
|
||||
|
||||
wxPrintf(_T("File times for '%s':\n"), fn.GetFullPath().c_str());
|
||||
wxPrintf(_T("Access: \t%s\n"), dtAccess.Format(fmt).c_str());
|
||||
wxPrintf(_T("Mod/creation:\t%s\n"), dtMod.Format(fmt).c_str());
|
||||
wxPrintf(_T("Change: \t%s\n"), dtChange.Format(fmt).c_str());
|
||||
wxPrintf(_T("Creation: \t%s\n"), dtCreate.Format(fmt).c_str());
|
||||
wxPrintf(_T("Last read: \t%s\n"), dtAccess.Format(fmt).c_str());
|
||||
wxPrintf(_T("Last write: \t%s\n"), dtMod.Format(fmt).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,23 +135,31 @@
|
||||
class wxFileHandle
|
||||
{
|
||||
public:
|
||||
wxFileHandle(const wxString& filename)
|
||||
enum OpenMode
|
||||
{
|
||||
Read,
|
||||
Write
|
||||
};
|
||||
|
||||
wxFileHandle(const wxString& filename, OpenMode mode)
|
||||
{
|
||||
m_hFile = ::CreateFile
|
||||
(
|
||||
filename, // name
|
||||
GENERIC_READ, // access mask
|
||||
0, // no sharing
|
||||
NULL, // no secutity attr
|
||||
OPEN_EXISTING, // creation disposition
|
||||
0, // no flags
|
||||
NULL // no template file
|
||||
filename, // name
|
||||
mode == Read ? GENERIC_READ // access mask
|
||||
: GENERIC_WRITE,
|
||||
0, // no sharing
|
||||
NULL, // no secutity attr
|
||||
OPEN_EXISTING, // creation disposition
|
||||
0, // no flags
|
||||
NULL // no template file
|
||||
);
|
||||
|
||||
if ( m_hFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
wxLogSysError(_("Failed to open '%s' for reading"),
|
||||
filename.c_str());
|
||||
wxLogSysError(_("Failed to open '%s' for %s"),
|
||||
filename.c_str(),
|
||||
mode == Read ? _("reading") : _("writing"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,32 +195,45 @@ private:
|
||||
// convert between wxDateTime and FILETIME which is a 64-bit value representing
|
||||
// the number of 100-nanosecond intervals since January 1, 1601.
|
||||
|
||||
// the number of milliseconds between the Unix Epoch (January 1, 1970) and the
|
||||
// FILETIME reference point (January 1, 1601)
|
||||
static const wxLongLong FILETIME_EPOCH_OFFSET = wxLongLong(0xa97, 0x30b66800);
|
||||
|
||||
static void ConvertFileTimeToWx(wxDateTime *dt, const FILETIME &ft)
|
||||
{
|
||||
wxLongLong ll(ft.dwHighDateTime, ft.dwLowDateTime);
|
||||
FILETIME ftLocal;
|
||||
if ( !::FileTimeToLocalFileTime(&ft, &ftLocal) )
|
||||
{
|
||||
wxLogLastError(_T("FileTimeToLocalFileTime"));
|
||||
}
|
||||
|
||||
// convert 100ns to ms
|
||||
ll /= 10000;
|
||||
SYSTEMTIME st;
|
||||
if ( !::FileTimeToSystemTime(&ftLocal, &st) )
|
||||
{
|
||||
wxLogLastError(_T("FileTimeToSystemTime"));
|
||||
}
|
||||
|
||||
// move it to our Epoch
|
||||
ll -= FILETIME_EPOCH_OFFSET;
|
||||
|
||||
*dt = wxDateTime(ll);
|
||||
dt->Set(st.wDay, wxDateTime::Month(st.wMonth - 1), st.wYear,
|
||||
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
}
|
||||
|
||||
static void ConvertWxToFileTime(FILETIME *ft, const wxDateTime& dt)
|
||||
{
|
||||
// do the reverse of ConvertFileTimeToWx()
|
||||
wxLongLong ll = dt.GetValue();
|
||||
ll += FILETIME_EPOCH_OFFSET;
|
||||
ll *= 10000;
|
||||
SYSTEMTIME st;
|
||||
st.wDay = dt.GetDay();
|
||||
st.wMonth = dt.GetMonth() + 1;
|
||||
st.wYear = dt.GetYear();
|
||||
st.wHour = dt.GetHour();
|
||||
st.wMinute = dt.GetMinute();
|
||||
st.wSecond = dt.GetSecond();
|
||||
st.wMilliseconds = dt.GetMillisecond();
|
||||
|
||||
ft->dwHighDateTime = ll.GetHi();
|
||||
ft->dwLowDateTime = ll.GetLo();
|
||||
FILETIME ftLocal;
|
||||
if ( !::SystemTimeToFileTime(&st, &ftLocal) )
|
||||
{
|
||||
wxLogLastError(_T("SystemTimeToFileTime"));
|
||||
}
|
||||
|
||||
if ( !::LocalFileTimeToFileTime(&ftLocal, ft) )
|
||||
{
|
||||
wxLogLastError(_T("LocalFileTimeToFileTime"));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __WIN32__
|
||||
@ -1561,9 +1582,9 @@ void wxFileName::SplitPath(const wxString& fullpath,
|
||||
// time functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxFileName::SetTimes(const wxDateTime *dtCreate,
|
||||
const wxDateTime *dtAccess,
|
||||
const wxDateTime *dtMod)
|
||||
bool wxFileName::SetTimes(const wxDateTime *dtAccess,
|
||||
const wxDateTime *dtMod,
|
||||
const wxDateTime *dtCreate)
|
||||
{
|
||||
#if defined(__UNIX_LIKE__) || (defined(__DOS__) && defined(__WATCOMC__))
|
||||
if ( !dtAccess && !dtMod )
|
||||
@ -1582,7 +1603,7 @@ bool wxFileName::SetTimes(const wxDateTime *dtCreate,
|
||||
return TRUE;
|
||||
}
|
||||
#elif defined(__WIN32__)
|
||||
wxFileHandle fh(GetFullPath());
|
||||
wxFileHandle fh(GetFullPath(), wxFileHandle::Write);
|
||||
if ( fh.IsOk() )
|
||||
{
|
||||
FILETIME ftAccess, ftCreate, ftWrite;
|
||||
@ -1626,13 +1647,13 @@ bool wxFileName::Touch()
|
||||
#else // other platform
|
||||
wxDateTime dtNow = wxDateTime::Now();
|
||||
|
||||
return SetTimes(NULL /* don't change create time */, &dtNow, &dtNow);
|
||||
return SetTimes(&dtNow, &dtNow, NULL /* don't change create time */);
|
||||
#endif // platforms
|
||||
}
|
||||
|
||||
bool wxFileName::GetTimes(wxDateTime *dtAccess,
|
||||
wxDateTime *dtMod,
|
||||
wxDateTime *dtChange) const
|
||||
wxDateTime *dtCreate) const
|
||||
{
|
||||
#if defined(__UNIX_LIKE__) || defined(__WXMAC__) || (defined(__DOS__) && defined(__WATCOMC__))
|
||||
wxStructStat stBuf;
|
||||
@ -1642,13 +1663,13 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess,
|
||||
dtAccess->Set(stBuf.st_atime);
|
||||
if ( dtMod )
|
||||
dtMod->Set(stBuf.st_mtime);
|
||||
if ( dtChange )
|
||||
dtChange->Set(stBuf.st_ctime);
|
||||
if ( dtCreate )
|
||||
dtCreate->Set(stBuf.st_ctime);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#elif defined(__WIN32__)
|
||||
wxFileHandle fh(GetFullPath());
|
||||
wxFileHandle fh(GetFullPath(), wxFileHandle::Read);
|
||||
if ( fh.IsOk() )
|
||||
{
|
||||
FILETIME ftAccess, ftCreate, ftWrite;
|
||||
@ -1656,14 +1677,14 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess,
|
||||
if ( ::GetFileTime(fh,
|
||||
dtMod ? &ftCreate : NULL,
|
||||
dtAccess ? &ftAccess : NULL,
|
||||
dtChange ? &ftWrite : NULL) )
|
||||
dtCreate ? &ftWrite : NULL) )
|
||||
{
|
||||
if ( dtMod )
|
||||
ConvertFileTimeToWx(dtMod, ftCreate);
|
||||
if ( dtAccess )
|
||||
ConvertFileTimeToWx(dtAccess, ftAccess);
|
||||
if ( dtChange )
|
||||
ConvertFileTimeToWx(dtChange, ftWrite);
|
||||
if ( dtCreate )
|
||||
ConvertFileTimeToWx(dtCreate, ftWrite);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user