return a wxAnyStrPtr covnertible to either narrow or wide char pointer from wxDateTime::ParseXXX() methods to improve compatibility with wx 2.8 and also simplify the code (closes #9560)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59822 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -309,6 +309,7 @@ WXSCINTILLA_OBJECTS = \
|
|||||||
PLUGINS_INST_DIR = $(libdir)/wx/$(PLUGIN_VERSION0)
|
PLUGINS_INST_DIR = $(libdir)/wx/$(PLUGIN_VERSION0)
|
||||||
ALL_BASE_HEADERS = \
|
ALL_BASE_HEADERS = \
|
||||||
wx/afterstd.h \
|
wx/afterstd.h \
|
||||||
|
wx/anystr.h \
|
||||||
wx/app.h \
|
wx/app.h \
|
||||||
wx/apptrait.h \
|
wx/apptrait.h \
|
||||||
wx/archive.h \
|
wx/archive.h \
|
||||||
@@ -467,6 +468,7 @@ ALL_HEADERS = \
|
|||||||
$(ALL_GUI_HEADERS)
|
$(ALL_GUI_HEADERS)
|
||||||
ALL_PORTS_BASE_HEADERS = \
|
ALL_PORTS_BASE_HEADERS = \
|
||||||
wx/afterstd.h \
|
wx/afterstd.h \
|
||||||
|
wx/anystr.h \
|
||||||
wx/app.h \
|
wx/app.h \
|
||||||
wx/apptrait.h \
|
wx/apptrait.h \
|
||||||
wx/archive.h \
|
wx/archive.h \
|
||||||
|
@@ -390,6 +390,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
|
|||||||
</set>
|
</set>
|
||||||
<set var="BASE_CMN_HDR" hints="files">
|
<set var="BASE_CMN_HDR" hints="files">
|
||||||
wx/afterstd.h
|
wx/afterstd.h
|
||||||
|
wx/anystr.h
|
||||||
wx/app.h
|
wx/app.h
|
||||||
wx/apptrait.h
|
wx/apptrait.h
|
||||||
wx/archive.h
|
wx/archive.h
|
||||||
|
@@ -1035,6 +1035,10 @@ SOURCE=..\..\include\wx\afterstd.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\include\wx\anystr.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\include\wx\app.h
|
SOURCE=..\..\include\wx\app.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@@ -1194,6 +1194,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\wx\afterstd.h">
|
RelativePath="..\..\include\wx\afterstd.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\wx\anystr.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\wx\app.h">
|
RelativePath="..\..\include\wx\app.h">
|
||||||
</File>
|
</File>
|
||||||
|
@@ -1615,6 +1615,10 @@
|
|||||||
RelativePath="..\..\include\wx\afterstd.h"
|
RelativePath="..\..\include\wx\afterstd.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\wx\anystr.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\wx\app.h"
|
RelativePath="..\..\include\wx\app.h"
|
||||||
>
|
>
|
||||||
|
@@ -1611,6 +1611,10 @@
|
|||||||
RelativePath="..\..\include\wx\afterstd.h"
|
RelativePath="..\..\include\wx\afterstd.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\wx\anystr.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\wx\app.h"
|
RelativePath="..\..\include\wx\app.h"
|
||||||
>
|
>
|
||||||
|
136
include/wx/anystr.h
Normal file
136
include/wx/anystr.h
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/anystr.h
|
||||||
|
// Purpose: wxAnyStrPtr class declaration
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Created: 2009-03-23
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_ANYSTR_H_
|
||||||
|
#define _WX_ANYSTR_H_
|
||||||
|
|
||||||
|
#include "wx/string.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxAnyStrPtr
|
||||||
|
//
|
||||||
|
// Notice that this is an internal and intentionally not documented class. It
|
||||||
|
// is only used by wxWidgets itself to ensure compatibility with previous
|
||||||
|
// versions and shouldn't be used by user code. When you see a function
|
||||||
|
// returning it you should just know that you can treat it as a string pointer.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// This is a helper class convertible to either narrow or wide string pointer.
|
||||||
|
// It is similar to wxCStrData but, unlike it, can be NULL which is required to
|
||||||
|
// represent the return value of wxDateTime::ParseXXX() methods for example.
|
||||||
|
//
|
||||||
|
// NB: this class is fully inline and so doesn't need to be DLL-exported
|
||||||
|
class wxAnyStrPtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctors: this class must be created from the associated string or using
|
||||||
|
// its default ctor for an invalid NULL-like object; notice that it is
|
||||||
|
// immutable after creation.
|
||||||
|
|
||||||
|
// ctor for invalid pointer
|
||||||
|
wxAnyStrPtr()
|
||||||
|
: m_str(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ctor for valid pointer into the given string (whose lifetime must be
|
||||||
|
// greater than ours and which should remain constant while we're used)
|
||||||
|
wxAnyStrPtr(const wxString& str, const wxString::const_iterator& iter)
|
||||||
|
: m_str(&str),
|
||||||
|
m_iter(iter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// default copy ctor is ok and so is default dtor, in particular we do not
|
||||||
|
// free the string
|
||||||
|
|
||||||
|
|
||||||
|
// various operators meant to make this class look like a superposition of
|
||||||
|
// char* and wchar_t*
|
||||||
|
|
||||||
|
// this one is needed to allow boolean expressions involving these objects,
|
||||||
|
// e.g. "if ( FuncReturningAnyStrPtr() && ... )" (unfortunately using
|
||||||
|
// unspecified_bool_type here wouldn't help with ambiguity between all the
|
||||||
|
// different conversions to pointers)
|
||||||
|
operator bool() const { return m_str != NULL; }
|
||||||
|
|
||||||
|
|
||||||
|
// and these are the conversions operator which allow to assign the result
|
||||||
|
// of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*)
|
||||||
|
operator const char *() const
|
||||||
|
{
|
||||||
|
if ( !m_str )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// check if the string is convertible to char at all
|
||||||
|
//
|
||||||
|
// notice that this pointer points into wxString internal buffer
|
||||||
|
// containing its char* representation and so it can be kept for as
|
||||||
|
// long as wxString is not modified -- which is long enough for our
|
||||||
|
// needs
|
||||||
|
const char *p = m_str->c_str().AsChar();
|
||||||
|
if ( *p )
|
||||||
|
{
|
||||||
|
// find the offset of the character corresponding to this iterator
|
||||||
|
// position in bytes: we don't have any direct way to do it so we
|
||||||
|
// need to redo the conversion again for the part of the string
|
||||||
|
// before the iterator to find its length in bytes in current
|
||||||
|
// locale
|
||||||
|
//
|
||||||
|
// NB: conversion won't fail as it succeeded for the entire string
|
||||||
|
p += strlen(wxString(m_str->begin(), m_iter).mb_str());
|
||||||
|
}
|
||||||
|
//else: conversion failed, return "" as we can't do anything else
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const wchar_t *() const
|
||||||
|
{
|
||||||
|
if ( !m_str )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// no complications with wide strings (as long as we discount
|
||||||
|
// surrogates as we do for now)
|
||||||
|
//
|
||||||
|
// just remember that this works as long as wxString keeps an internal
|
||||||
|
// buffer with its wide wide char representation, just as with AsChar()
|
||||||
|
// above
|
||||||
|
return m_str->c_str().AsWChar() + (m_iter - m_str->begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because the objects of this class are only used as return type for
|
||||||
|
// functions which can return NULL we can skip providing dereferencing
|
||||||
|
// operators: the code using this class must test it for NULL first and if
|
||||||
|
// it does anything else with it it has to assign it to either char* or
|
||||||
|
// wchar_t* itself, before dereferencing.
|
||||||
|
//
|
||||||
|
// IOW this
|
||||||
|
//
|
||||||
|
// if ( *FuncReturningAnyStrPtr() )
|
||||||
|
//
|
||||||
|
// is invalid because it could crash. And this
|
||||||
|
//
|
||||||
|
// const char *p = FuncReturningAnyStrPtr();
|
||||||
|
// if ( p && *p )
|
||||||
|
//
|
||||||
|
// already works fine.
|
||||||
|
|
||||||
|
private:
|
||||||
|
// the original string and the offset in it we correspond to, if the string
|
||||||
|
// is NULL this object is NULL pointer-like
|
||||||
|
const wxString * const m_str;
|
||||||
|
const wxString::const_iterator m_iter;
|
||||||
|
|
||||||
|
wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _WX_ANYSTR_H_
|
||||||
|
|
@@ -26,6 +26,7 @@
|
|||||||
#include <limits.h> // for INT_MIN
|
#include <limits.h> // for INT_MIN
|
||||||
|
|
||||||
#include "wx/longlong.h"
|
#include "wx/longlong.h"
|
||||||
|
#include "wx/anystr.h"
|
||||||
|
|
||||||
class WXDLLIMPEXP_FWD_BASE wxDateTime;
|
class WXDLLIMPEXP_FWD_BASE wxDateTime;
|
||||||
class WXDLLIMPEXP_FWD_BASE wxTimeSpan;
|
class WXDLLIMPEXP_FWD_BASE wxTimeSpan;
|
||||||
@@ -1098,103 +1099,36 @@ public:
|
|||||||
inline wxTimeSpan Subtract(const wxDateTime& dt) const;
|
inline wxTimeSpan Subtract(const wxDateTime& dt) const;
|
||||||
inline wxTimeSpan operator-(const wxDateTime& dt2) const;
|
inline wxTimeSpan operator-(const wxDateTime& dt2) const;
|
||||||
|
|
||||||
// conversion to/from text: all conversions from text return the pointer to
|
// conversion to/from text: all conversions from text return an object
|
||||||
// the next character following the date specification (i.e. the one where
|
// representing the next character following the date specification (i.e.
|
||||||
// the scan had to stop) or NULL on failure; for the versions taking
|
// the one where the scan had to stop) or a special NULL-like object
|
||||||
// wxString or wxCStrData, we don't know if the user code needs char* or
|
// on failure -- this object is necessary to preserve compatibility with
|
||||||
// wchar_t* pointer and so we return char* one for compatibility with the
|
// the existing code assigning the return value of these functions to
|
||||||
// existing ANSI code and also return iterator in another output parameter
|
// either char* or wxChar* (new code should treat the return value as bool
|
||||||
// (it will be equal to end if the entire string was parsed)
|
// and use end parameter to retrieve the end of the scan)
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
// parse a string in RFC 822 format (found e.g. in mail headers and
|
// parse a string in RFC 822 format (found e.g. in mail headers and
|
||||||
// having the form "Wed, 10 Feb 1999 19:07:07 +0100")
|
// having the form "Wed, 10 Feb 1999 19:07:07 +0100")
|
||||||
const char *ParseRfc822Date(const wxString& date,
|
wxAnyStrPtr ParseRfc822Date(const wxString& date,
|
||||||
wxString::const_iterator *end = NULL);
|
wxString::const_iterator *end = NULL);
|
||||||
const char *ParseRfc822Date(const wxCStrData& date,
|
|
||||||
wxString::const_iterator *end = NULL)
|
|
||||||
{
|
|
||||||
return ParseRfc822Date(date.AsString(), end);
|
|
||||||
}
|
|
||||||
|
|
||||||
const wchar_t *ParseRfc822Date(const wchar_t* date)
|
|
||||||
{
|
|
||||||
return ReturnEndAsWidePtr(&wxDateTime::ParseRfc822Date, date);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ParseRfc822Date(const char* date)
|
|
||||||
{
|
|
||||||
return ParseRfc822Date(wxString(date));
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse a date/time in the given format (see strptime(3)), fill in
|
// parse a date/time in the given format (see strptime(3)), fill in
|
||||||
// the missing (in the string) fields with the values of dateDef (by
|
// the missing (in the string) fields with the values of dateDef (by
|
||||||
// default, they will not change if they had valid values or will
|
// default, they will not change if they had valid values or will
|
||||||
// default to Today() otherwise)
|
// default to Today() otherwise)
|
||||||
|
wxAnyStrPtr ParseFormat(const wxString& date,
|
||||||
// notice that we unfortunately need all those overloads because we use
|
|
||||||
// the type of the date string to select the return value of the
|
|
||||||
// function: it's wchar_t if a wide string is passed for compatibility
|
|
||||||
// with the code doing "const wxChar *p = dt.ParseFormat(_T("..."))",
|
|
||||||
// but char* in all other cases for compatibility with ANSI build which
|
|
||||||
// allowed code like "const char *p = dt.ParseFormat("...")"
|
|
||||||
//
|
|
||||||
// so we need wchar_t overload and now passing s.c_str() as first
|
|
||||||
// argument is ambiguous because it's convertible to both wxString and
|
|
||||||
// wchar_t* and now it's passing char* which becomes ambiguous as it is
|
|
||||||
// convertible to both wxString and wxCStrData hence we need char*
|
|
||||||
// overload too
|
|
||||||
//
|
|
||||||
// and to make our life more miserable we also pay for having the
|
|
||||||
// optional dateDef parameter: as it's almost never used, we want to
|
|
||||||
// allow people to omit it when specifying the end iterator output
|
|
||||||
// parameter but we still have to allow specifying dateDef too, so we
|
|
||||||
// need another overload for this
|
|
||||||
//
|
|
||||||
// FIXME: all this mess could be avoided by using some class similar to
|
|
||||||
// wxFormatString, i.e. remembering string [pointer] of any type
|
|
||||||
// and convertible to either char* or wchar_t* as wxCStrData and
|
|
||||||
// having only 1 (or 2, because of the last paragraph above)
|
|
||||||
// overload taking it, see #9560
|
|
||||||
const char *ParseFormat(const wxString& date,
|
|
||||||
const wxString& format = wxDefaultDateTimeFormat,
|
const wxString& format = wxDefaultDateTimeFormat,
|
||||||
const wxDateTime& dateDef = wxDefaultDateTime,
|
const wxDateTime& dateDef = wxDefaultDateTime,
|
||||||
wxString::const_iterator *end = NULL);
|
wxString::const_iterator *end = NULL);
|
||||||
|
|
||||||
const char *ParseFormat(const wxString& date,
|
wxAnyStrPtr ParseFormat(const wxString& date,
|
||||||
const wxString& format,
|
const wxString& format,
|
||||||
wxString::const_iterator *end)
|
wxString::const_iterator *end)
|
||||||
{
|
{
|
||||||
return ParseFormat(date, format, wxDefaultDateTime, end);
|
return ParseFormat(date, format, wxDefaultDateTime, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ParseFormat(const wxCStrData& date,
|
|
||||||
const wxString& format = wxDefaultDateTimeFormat,
|
|
||||||
const wxDateTime& dateDef = wxDefaultDateTime,
|
|
||||||
wxString::const_iterator *end = NULL)
|
|
||||||
{
|
|
||||||
return ParseFormat(date.AsString(), format, dateDef, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
const wchar_t *ParseFormat(const wchar_t *date,
|
|
||||||
const wxString& format = wxDefaultDateTimeFormat,
|
|
||||||
const wxDateTime& dateDef = wxDefaultDateTime)
|
|
||||||
{
|
|
||||||
const wxString datestr(date);
|
|
||||||
wxString::const_iterator end;
|
|
||||||
if ( !ParseFormat(datestr, format, dateDef, &end) )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return date + (end - datestr.begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ParseFormat(const char *date,
|
|
||||||
const wxString& format = "%c",
|
|
||||||
const wxDateTime& dateDef = wxDefaultDateTime)
|
|
||||||
{
|
|
||||||
return ParseFormat(wxString(date), format, dateDef);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// parse a string containing date, time or both in ISO 8601 format
|
// parse a string containing date, time or both in ISO 8601 format
|
||||||
//
|
//
|
||||||
@@ -1221,65 +1155,18 @@ public:
|
|||||||
|
|
||||||
// parse a string containing the date/time in "free" format, this
|
// parse a string containing the date/time in "free" format, this
|
||||||
// function will try to make an educated guess at the string contents
|
// function will try to make an educated guess at the string contents
|
||||||
const char *ParseDateTime(const wxString& datetime,
|
wxAnyStrPtr ParseDateTime(const wxString& datetime,
|
||||||
wxString::const_iterator *end = NULL);
|
wxString::const_iterator *end = NULL);
|
||||||
|
|
||||||
const char *ParseDateTime(const wxCStrData& datetime,
|
|
||||||
wxString::const_iterator *end = NULL)
|
|
||||||
{
|
|
||||||
return ParseDateTime(datetime.AsString(), end);
|
|
||||||
}
|
|
||||||
|
|
||||||
const wchar_t *ParseDateTime(const wchar_t *datetime)
|
|
||||||
{
|
|
||||||
return ReturnEndAsWidePtr(&wxDateTime::ParseDateTime, datetime);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ParseDateTime(const char *datetime)
|
|
||||||
{
|
|
||||||
return ParseDateTime(wxString(datetime));
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse a string containing the date only in "free" format (less
|
// parse a string containing the date only in "free" format (less
|
||||||
// flexible than ParseDateTime)
|
// flexible than ParseDateTime)
|
||||||
const char *ParseDate(const wxString& date,
|
wxAnyStrPtr ParseDate(const wxString& date,
|
||||||
wxString::const_iterator *end = NULL);
|
wxString::const_iterator *end = NULL);
|
||||||
|
|
||||||
const char *ParseDate(const wxCStrData& date,
|
|
||||||
wxString::const_iterator *end = NULL)
|
|
||||||
{
|
|
||||||
return ParseDate(date.AsString(), end);
|
|
||||||
}
|
|
||||||
|
|
||||||
const wchar_t *ParseDate(const wchar_t *date)
|
|
||||||
{
|
|
||||||
return ReturnEndAsWidePtr(&wxDateTime::ParseDate, date);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ParseDate(const char *date)
|
|
||||||
{
|
|
||||||
return ParseDate(wxString(date));
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse a string containing the time only in "free" format
|
// parse a string containing the time only in "free" format
|
||||||
const char *ParseTime(const wxString& time,
|
wxAnyStrPtr ParseTime(const wxString& time,
|
||||||
wxString::const_iterator *end = NULL);
|
wxString::const_iterator *end = NULL);
|
||||||
|
|
||||||
const char *ParseTime(const wxCStrData& time,
|
|
||||||
wxString::const_iterator *end = NULL)
|
|
||||||
{
|
|
||||||
return ParseTime(time.AsString(), end);
|
|
||||||
}
|
|
||||||
|
|
||||||
const wchar_t *ParseTime(const wchar_t *time)
|
|
||||||
{
|
|
||||||
return ReturnEndAsWidePtr(&wxDateTime::ParseTime, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ParseTime(const char *time)
|
|
||||||
{
|
|
||||||
return ParseTime(wxString(time));
|
|
||||||
}
|
|
||||||
|
|
||||||
// this function accepts strftime()-like format string (default
|
// this function accepts strftime()-like format string (default
|
||||||
// argument corresponds to the preferred date and time representation
|
// argument corresponds to the preferred date and time representation
|
||||||
@@ -1326,23 +1213,6 @@ public:
|
|||||||
static struct tm *GetTmNow(struct tm *tmstruct);
|
static struct tm *GetTmNow(struct tm *tmstruct);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// helper function for defining backward-compatible wrappers for code
|
|
||||||
// using wchar_t* pointer instead of wxString iterators
|
|
||||||
typedef
|
|
||||||
const char *(wxDateTime::*StringMethod)(const wxString& s,
|
|
||||||
wxString::const_iterator *end);
|
|
||||||
|
|
||||||
const wchar_t *ReturnEndAsWidePtr(StringMethod func, const wchar_t *p)
|
|
||||||
{
|
|
||||||
const wxString s(p);
|
|
||||||
wxString::const_iterator end;
|
|
||||||
if ( !(this->*func)(s, &end) )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return p + (end - s.begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// the current country - as it's the same for all program objects (unless
|
// the current country - as it's the same for all program objects (unless
|
||||||
// it runs on a _really_ big cluster system :-), this is a static member:
|
// it runs on a _really_ big cluster system :-), this is a static member:
|
||||||
// see SetCountry() and GetCountry()
|
// see SetCountry() and GetCountry()
|
||||||
|
@@ -802,50 +802,34 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
This function is like ParseDateTime(), but it only allows the date to
|
This function is like ParseDateTime(), but it only allows the date to
|
||||||
be specified. It is thus less flexible then ParseDateTime(), but also
|
be specified.
|
||||||
has less chances to misinterpret the user input.
|
|
||||||
|
|
||||||
@return @NULL if the conversion failed, otherwise return the pointer
|
It is thus less flexible then ParseDateTime(), but also has less
|
||||||
to the character which stopped the scan.
|
chances to misinterpret the user input.
|
||||||
|
|
||||||
|
See ParseFormat() for the description of function parameters and return
|
||||||
|
value.
|
||||||
|
|
||||||
@see Format()
|
@see Format()
|
||||||
*/
|
*/
|
||||||
const char* ParseDate(const wxString& date,
|
const char* ParseDate(const wxString& date,
|
||||||
wxString::const_iterator* end = NULL);
|
wxString::const_iterator* end = NULL);
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const char* ParseDate(const char* date);
|
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const wchar_t* ParseDate(const wchar_t* date);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Parses the string @a datetime containing the date and time in free
|
Parses the string @a datetime containing the date and time in free
|
||||||
format. This function tries as hard as it can to interpret the given
|
format.
|
||||||
string as date and time. Unlike ParseRfc822Date(), it will accept
|
|
||||||
anything that may be accepted and will only reject strings which can
|
|
||||||
not be parsed in any way at all.
|
|
||||||
|
|
||||||
@return @NULL if the conversion failed, otherwise return the pointer
|
This function tries as hard as it can to interpret the given string as
|
||||||
to the character which stopped the scan.
|
date and time. Unlike ParseRfc822Date(), it will accept anything that
|
||||||
|
may be accepted and will only reject strings which can not be parsed in
|
||||||
|
any way at all.
|
||||||
|
|
||||||
|
See ParseFormat() for the description of function parameters and return
|
||||||
|
value.
|
||||||
*/
|
*/
|
||||||
const char* ParseDateTime(const wxString& datetime,
|
const char* ParseDateTime(const wxString& datetime,
|
||||||
wxString::const_iterator* end = NULL);
|
wxString::const_iterator* end = NULL);
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const char* ParseDateTime(const char* datetime);
|
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const wchar_t* ParseDateTime(const wchar_t* datetime);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function parses the string @a date according to the given
|
This function parses the string @a date according to the given
|
||||||
@e format. The system @c strptime(3) function is used whenever
|
@e format. The system @c strptime(3) function is used whenever
|
||||||
@@ -865,8 +849,38 @@ public:
|
|||||||
@a dateDef. If it is not specified, Today() is used as the default
|
@a dateDef. If it is not specified, Today() is used as the default
|
||||||
date.
|
date.
|
||||||
|
|
||||||
@return @NULL if the conversion failed, otherwise return the pointer
|
Notice that the return value of this method is not actually a pointer
|
||||||
to the character which stopped the scan.
|
but rather an object of a special proxy class which is convertible to
|
||||||
|
either @c char* or @c wchar_t* pointer. This is needed for
|
||||||
|
compatibility with the existing code but the new code should use @a end
|
||||||
|
parameter instead and just test whether the return value is @NULL or
|
||||||
|
not, e.g.:
|
||||||
|
@code
|
||||||
|
wxDateTime dt;
|
||||||
|
wxString str = "...";
|
||||||
|
wxString::const_iterator end;
|
||||||
|
if ( !dt.ParseFormat(str, "%Y-%m-%d", &end) )
|
||||||
|
... parsing failed ...
|
||||||
|
else if ( end == str.end() )
|
||||||
|
... entire string parsed ...
|
||||||
|
else
|
||||||
|
... wxString(end, str.end()) left over ...
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@param date
|
||||||
|
The string to be parsed.
|
||||||
|
@param format
|
||||||
|
strptime()-like format string.
|
||||||
|
@param dateDef
|
||||||
|
Used to fill in the date components not specified in the @a date
|
||||||
|
string.
|
||||||
|
@param end
|
||||||
|
If non-@NULL, will be filled with the iterator pointing to the
|
||||||
|
location where the parsing stopped. If the entire string was
|
||||||
|
consumed, it is set to @c date.end().
|
||||||
|
@return
|
||||||
|
Pointer-like object indicating the location where the scan stopped
|
||||||
|
if parsing was successful or @NULL-like otherwise.
|
||||||
|
|
||||||
@see Format()
|
@see Format()
|
||||||
*/
|
*/
|
||||||
@@ -878,16 +892,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
@overload
|
@overload
|
||||||
*/
|
*/
|
||||||
const char* ParseFormat(const char* date,
|
const char* ParseFormat(const wxString& date,
|
||||||
const wxString& format = wxDefaultDateTimeFormat,
|
const wxString& format = wxDefaultDateTimeFormat,
|
||||||
const wxDateTime& dateDef = wxDefaultDateTime);
|
wxString::const_iterator* end = NULL);
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const wchar_t* ParseFormat(const wchar_t* date,
|
|
||||||
const wxString& format = wxDefaultDateTimeFormat,
|
|
||||||
const wxDateTime& dateDef = wxDefaultDateTime);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function parses the string containing the date and time in ISO
|
This function parses the string containing the date and time in ISO
|
||||||
@@ -933,39 +940,22 @@ public:
|
|||||||
string which is not RFC 822 compliant. If you need to parse date
|
string which is not RFC 822 compliant. If you need to parse date
|
||||||
formatted in more free ways, you should use ParseDateTime() or
|
formatted in more free ways, you should use ParseDateTime() or
|
||||||
ParseDate() instead.
|
ParseDate() instead.
|
||||||
|
|
||||||
|
See ParseFormat() for the description of function parameters and return
|
||||||
|
value.
|
||||||
*/
|
*/
|
||||||
const char* ParseRfc822Date(const wxString& date,
|
const char* ParseRfc822Date(const wxString& date,
|
||||||
wxString::const_iterator* end = NULL);
|
wxString::const_iterator* end = NULL);
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const char* ParseRfc822Date(const char* date);
|
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const wchar_t* ParseRfc822Date(const wchar_t* date);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This functions is like ParseDateTime(), but only allows the time to be
|
This functions is like ParseDateTime(), but only allows the time to be
|
||||||
specified in the input string.
|
specified in the input string.
|
||||||
|
|
||||||
@return @NULL if the conversion failed, otherwise return the pointer
|
See ParseFormat() for the description of function parameters and return
|
||||||
to the character which stopped the scan.
|
value.
|
||||||
*/
|
*/
|
||||||
const char* ParseTime(const wxString& time,
|
const char* ParseTime(const wxString& time,
|
||||||
wxString::const_iterator* end = NULL);
|
wxString::const_iterator* end = NULL);
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const char* ParseTime(const char* time);
|
|
||||||
|
|
||||||
/**
|
|
||||||
@overload
|
|
||||||
*/
|
|
||||||
const wchar_t* ParseTime(const wchar_t* time);
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
@@ -128,8 +128,20 @@ CallStrptime(const wxString& str,
|
|||||||
|
|
||||||
#endif // HAVE_STRPTIME
|
#endif // HAVE_STRPTIME
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DateLang_English = 1,
|
||||||
|
DateLang_Local = 2
|
||||||
|
};
|
||||||
|
|
||||||
// return the month if the string is a month name or Inv_Month otherwise
|
// return the month if the string is a month name or Inv_Month otherwise
|
||||||
wxDateTime::Month GetMonthFromName(const wxString& name, int flags)
|
//
|
||||||
|
// flags can contain wxDateTime::Name_Abbr/Name_Full or both of them and lang
|
||||||
|
// can be either DateLang_Local (default) to interpret string as a localized
|
||||||
|
// month name or DateLang_English to parse it as a standard English name or
|
||||||
|
// their combination to interpret it in any way
|
||||||
|
wxDateTime::Month
|
||||||
|
GetMonthFromName(const wxString& name, int flags, int lang)
|
||||||
{
|
{
|
||||||
wxDateTime::Month mon;
|
wxDateTime::Month mon;
|
||||||
for ( mon = wxDateTime::Jan; mon < wxDateTime::Inv_Month; wxNextMonth(mon) )
|
for ( mon = wxDateTime::Jan; mon < wxDateTime::Inv_Month; wxNextMonth(mon) )
|
||||||
@@ -138,19 +150,35 @@ wxDateTime::Month GetMonthFromName(const wxString& name, int flags)
|
|||||||
// and not versions
|
// and not versions
|
||||||
if ( flags & wxDateTime::Name_Full )
|
if ( flags & wxDateTime::Name_Full )
|
||||||
{
|
{
|
||||||
if ( name.CmpNoCase(wxDateTime::
|
if ( lang & DateLang_English )
|
||||||
GetMonthName(mon, wxDateTime::Name_Full)) == 0 )
|
|
||||||
{
|
{
|
||||||
break;
|
if ( name.CmpNoCase(wxDateTime::GetEnglishMonthName(mon,
|
||||||
|
wxDateTime::Name_Full)) == 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lang & DateLang_Local )
|
||||||
|
{
|
||||||
|
if ( name.CmpNoCase(wxDateTime::GetMonthName(mon,
|
||||||
|
wxDateTime::Name_Full)) == 0 )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags & wxDateTime::Name_Abbr )
|
if ( flags & wxDateTime::Name_Abbr )
|
||||||
{
|
{
|
||||||
if ( name.CmpNoCase(wxDateTime::
|
if ( lang & DateLang_English )
|
||||||
GetMonthName(mon, wxDateTime::Name_Abbr)) == 0 )
|
|
||||||
{
|
{
|
||||||
break;
|
if ( name.CmpNoCase(wxDateTime::GetEnglishMonthName(mon,
|
||||||
|
wxDateTime::Name_Abbr)) == 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lang & DateLang_Local )
|
||||||
|
{
|
||||||
|
if ( name.CmpNoCase(wxDateTime::GetMonthName(mon,
|
||||||
|
wxDateTime::Name_Abbr)) == 0 )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,28 +187,46 @@ wxDateTime::Month GetMonthFromName(const wxString& name, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return the weekday if the string is a weekday name or Inv_WeekDay otherwise
|
// return the weekday if the string is a weekday name or Inv_WeekDay otherwise
|
||||||
wxDateTime::WeekDay GetWeekDayFromName(const wxString& name, int flags)
|
//
|
||||||
|
// flags and lang parameters have the same meaning as for GetMonthFromName()
|
||||||
|
// above
|
||||||
|
wxDateTime::WeekDay
|
||||||
|
GetWeekDayFromName(const wxString& name, int flags, int lang)
|
||||||
{
|
{
|
||||||
wxDateTime::WeekDay wd;
|
wxDateTime::WeekDay wd;
|
||||||
for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
|
for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
|
||||||
{
|
{
|
||||||
// case-insensitive comparison either one of or with both abbreviated
|
|
||||||
// and not versions
|
|
||||||
if ( flags & wxDateTime::Name_Full )
|
if ( flags & wxDateTime::Name_Full )
|
||||||
{
|
{
|
||||||
if ( name.CmpNoCase(wxDateTime::
|
if ( lang & DateLang_English )
|
||||||
GetWeekDayName(wd, wxDateTime::Name_Full)) == 0 )
|
|
||||||
{
|
{
|
||||||
break;
|
if ( name.CmpNoCase(wxDateTime::GetEnglishWeekDayName(wd,
|
||||||
|
wxDateTime::Name_Full)) == 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lang & DateLang_Local )
|
||||||
|
{
|
||||||
|
if ( name.CmpNoCase(wxDateTime::GetWeekDayName(wd,
|
||||||
|
wxDateTime::Name_Full)) == 0 )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags & wxDateTime::Name_Abbr )
|
if ( flags & wxDateTime::Name_Abbr )
|
||||||
{
|
{
|
||||||
if ( name.CmpNoCase(wxDateTime::
|
if ( lang & DateLang_English )
|
||||||
GetWeekDayName(wd, wxDateTime::Name_Abbr)) == 0 )
|
|
||||||
{
|
{
|
||||||
break;
|
if ( name.CmpNoCase(wxDateTime::GetEnglishWeekDayName(wd,
|
||||||
|
wxDateTime::Name_Abbr)) == 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lang & DateLang_Local )
|
||||||
|
{
|
||||||
|
if ( name.CmpNoCase(wxDateTime::GetWeekDayName(wd,
|
||||||
|
wxDateTime::Name_Abbr)) == 0 )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -636,226 +682,156 @@ wxString wxDateTime::Format(const wxString& format, const TimeZone& tz) const
|
|||||||
//
|
//
|
||||||
// this function is "strict" by design - it must reject anything except true
|
// this function is "strict" by design - it must reject anything except true
|
||||||
// RFC822 time specs.
|
// RFC822 time specs.
|
||||||
//
|
wxAnyStrPtr
|
||||||
// TODO a great candidate for using reg exps
|
|
||||||
const char *
|
|
||||||
wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
|
wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
|
||||||
{
|
{
|
||||||
// TODO: rewrite using iterators instead of wxChar pointers
|
wxString::const_iterator p = date.begin();
|
||||||
const wxStringCharType *p = date.wx_str();
|
|
||||||
const wxStringCharType *comma = wxStrchr(p, wxS(','));
|
|
||||||
if ( comma )
|
|
||||||
{
|
|
||||||
// the part before comma is the weekday
|
|
||||||
|
|
||||||
// skip it for now - we don't use but might check that it really
|
// 1. week day
|
||||||
// corresponds to the specfied date
|
static const int WDAY_LEN = 3;
|
||||||
p = comma + 1;
|
const wxString::const_iterator endWday = p + WDAY_LEN;
|
||||||
|
const wxString wday(p, endWday);
|
||||||
|
if ( GetWeekDayFromName(wday, Name_Abbr, DateLang_English) == Inv_WeekDay )
|
||||||
|
return wxAnyStrPtr();
|
||||||
|
//else: ignore week day for now, we could also check that it really
|
||||||
|
// corresponds to the specified date
|
||||||
|
|
||||||
if ( *p != _T(' ') )
|
p = endWday;
|
||||||
{
|
|
||||||
wxLogDebug(_T("no space after weekday in RFC822 time spec"));
|
|
||||||
|
|
||||||
return NULL;
|
// 2. separating comma
|
||||||
}
|
if ( *p++ != ',' || *p++ != ' ' )
|
||||||
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
p++; // skip space
|
// 3. day number
|
||||||
}
|
|
||||||
|
|
||||||
// the following 1 or 2 digits are the day number
|
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
wxLogDebug(_T("day number expected in RFC822 time spec, none found"));
|
|
||||||
|
|
||||||
return NULL;
|
wxDateTime_t day = (wxDateTime_t)(*p++ - '0');
|
||||||
}
|
|
||||||
|
|
||||||
wxDateTime_t day = (wxDateTime_t)(*p++ - _T('0'));
|
|
||||||
if ( wxIsdigit(*p) )
|
if ( wxIsdigit(*p) )
|
||||||
{
|
{
|
||||||
day *= 10;
|
day *= 10;
|
||||||
day = (wxDateTime_t)(day + (*p++ - _T('0')));
|
day = (wxDateTime_t)(day + (*p++ - '0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( *p++ != _T(' ') )
|
if ( *p++ != ' ' )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the following 3 letters specify the month
|
// 4. month name
|
||||||
wxString monName(p, 3);
|
static const int MONTH_LEN = 3;
|
||||||
Month mon;
|
const wxString::const_iterator endMonth = p + MONTH_LEN;
|
||||||
if ( monName == _T("Jan") )
|
const wxString monName(p, endMonth);
|
||||||
mon = Jan;
|
Month mon = GetMonthFromName(monName, Name_Abbr, DateLang_English);
|
||||||
else if ( monName == _T("Feb") )
|
if ( mon == Inv_Month )
|
||||||
mon = Feb;
|
return wxAnyStrPtr();
|
||||||
else if ( monName == _T("Mar") )
|
|
||||||
mon = Mar;
|
|
||||||
else if ( monName == _T("Apr") )
|
|
||||||
mon = Apr;
|
|
||||||
else if ( monName == _T("May") )
|
|
||||||
mon = May;
|
|
||||||
else if ( monName == _T("Jun") )
|
|
||||||
mon = Jun;
|
|
||||||
else if ( monName == _T("Jul") )
|
|
||||||
mon = Jul;
|
|
||||||
else if ( monName == _T("Aug") )
|
|
||||||
mon = Aug;
|
|
||||||
else if ( monName == _T("Sep") )
|
|
||||||
mon = Sep;
|
|
||||||
else if ( monName == _T("Oct") )
|
|
||||||
mon = Oct;
|
|
||||||
else if ( monName == _T("Nov") )
|
|
||||||
mon = Nov;
|
|
||||||
else if ( monName == _T("Dec") )
|
|
||||||
mon = Dec;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxLogDebug(_T("Invalid RFC 822 month name '%s'"), monName.c_str());
|
|
||||||
|
|
||||||
return NULL;
|
p = endMonth;
|
||||||
}
|
|
||||||
|
|
||||||
p += 3;
|
if ( *p++ != ' ' )
|
||||||
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
if ( *p++ != _T(' ') )
|
// 5. year
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// next is the year
|
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
// no year?
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int year = *p++ - _T('0');
|
int year = *p++ - '0';
|
||||||
|
if ( !wxIsdigit(*p) ) // should have at least 2 digits in the year
|
||||||
if ( !wxIsdigit(*p) )
|
return wxAnyStrPtr();
|
||||||
{
|
|
||||||
// should have at least 2 digits in the year
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
year *= 10;
|
year *= 10;
|
||||||
year += *p++ - _T('0');
|
year += *p++ - '0';
|
||||||
|
|
||||||
// is it a 2 digit year (as per original RFC 822) or a 4 digit one?
|
// is it a 2 digit year (as per original RFC 822) or a 4 digit one?
|
||||||
if ( wxIsdigit(*p) )
|
if ( wxIsdigit(*p) )
|
||||||
{
|
{
|
||||||
year *= 10;
|
year *= 10;
|
||||||
year += *p++ - _T('0');
|
year += *p++ - '0';
|
||||||
|
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
{
|
||||||
// no 3 digit years please
|
// no 3 digit years please
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
year *= 10;
|
year *= 10;
|
||||||
year += *p++ - _T('0');
|
year += *p++ - '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( *p++ != _T(' ') )
|
if ( *p++ != ' ' )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// time is in the format hh:mm:ss and seconds are optional
|
// 6. time in hh:mm:ss format with seconds being optional
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxDateTime_t hour = (wxDateTime_t)(*p++ - _T('0'));
|
wxDateTime_t hour = (wxDateTime_t)(*p++ - '0');
|
||||||
|
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hour *= 10;
|
hour *= 10;
|
||||||
hour = (wxDateTime_t)(hour + (*p++ - _T('0')));
|
hour = (wxDateTime_t)(hour + (*p++ - '0'));
|
||||||
|
|
||||||
if ( *p++ != _T(':') )
|
if ( *p++ != ':' )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxDateTime_t min = (wxDateTime_t)(*p++ - _T('0'));
|
wxDateTime_t min = (wxDateTime_t)(*p++ - '0');
|
||||||
|
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
min *= 10;
|
min *= 10;
|
||||||
min = (wxDateTime_t)(min + *p++ - _T('0'));
|
min += (wxDateTime_t)(*p++ - '0');
|
||||||
|
|
||||||
wxDateTime_t sec = 0;
|
wxDateTime_t sec = 0;
|
||||||
if ( *p == _T(':') )
|
if ( *p == ':' )
|
||||||
{
|
{
|
||||||
p++;
|
p++;
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec = (wxDateTime_t)(*p++ - _T('0'));
|
sec = (wxDateTime_t)(*p++ - '0');
|
||||||
|
|
||||||
if ( !wxIsdigit(*p) )
|
if ( !wxIsdigit(*p) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec *= 10;
|
sec *= 10;
|
||||||
sec = (wxDateTime_t)(sec + *p++ - _T('0'));
|
sec += (wxDateTime_t)(*p++ - '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( *p++ != _T(' ') )
|
if ( *p++ != ' ' )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and now the interesting part: the timezone
|
// 7. now the interesting part: the timezone
|
||||||
int offset wxDUMMY_INITIALIZE(0);
|
int offset wxDUMMY_INITIALIZE(0);
|
||||||
if ( *p == _T('-') || *p == _T('+') )
|
if ( *p == '-' || *p == '+' )
|
||||||
{
|
{
|
||||||
// the explicit offset given: it has the form of hhmm
|
// the explicit offset given: it has the form of hhmm
|
||||||
bool plus = *p++ == _T('+');
|
bool plus = *p++ == '+';
|
||||||
|
|
||||||
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
|
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hours
|
// hours
|
||||||
offset = MIN_PER_HOUR*(10*(*p - _T('0')) + (*(p + 1) - _T('0')));
|
offset = MIN_PER_HOUR*(10*(*p - '0') + (*(p + 1) - '0'));
|
||||||
|
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
|
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// minutes
|
// minutes
|
||||||
offset += 10*(*p - _T('0')) + (*(p + 1) - _T('0'));
|
offset += 10*(*p - '0') + (*(p + 1) - '0');
|
||||||
|
|
||||||
if ( !plus )
|
if ( !plus )
|
||||||
{
|
|
||||||
offset = -offset;
|
offset = -offset;
|
||||||
}
|
|
||||||
|
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
else
|
else // not numeric
|
||||||
{
|
{
|
||||||
// the symbolic timezone given: may be either military timezone or one
|
// the symbolic timezone given: may be either military timezone or one
|
||||||
// of standard abbreviations
|
// of standard abbreviations
|
||||||
@@ -871,18 +847,14 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
|
|||||||
};
|
};
|
||||||
|
|
||||||
if ( *p < _T('A') || *p > _T('Z') || *p == _T('J') )
|
if ( *p < _T('A') || *p > _T('Z') || *p == _T('J') )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
wxLogDebug(_T("Invalid militaty timezone '%c'"), *p);
|
|
||||||
|
|
||||||
return NULL;
|
offset = offsets[*p++ - 'A'];
|
||||||
}
|
|
||||||
|
|
||||||
offset = offsets[*p++ - _T('A')];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// abbreviation
|
// abbreviation
|
||||||
wxString tz = p;
|
const wxString tz(p, date.end());
|
||||||
if ( tz == _T("UT") || tz == _T("UTC") || tz == _T("GMT") )
|
if ( tz == _T("UT") || tz == _T("UTC") || tz == _T("GMT") )
|
||||||
offset = 0;
|
offset = 0;
|
||||||
else if ( tz == _T("AST") )
|
else if ( tz == _T("AST") )
|
||||||
@@ -906,11 +878,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
|
|||||||
else if ( tz == _T("PDT") )
|
else if ( tz == _T("PDT") )
|
||||||
offset = PDT - GMT0;
|
offset = PDT - GMT0;
|
||||||
else
|
else
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
wxLogDebug(_T("Unknown RFC 822 timezone '%s'"), p);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p += tz.length();
|
p += tz.length();
|
||||||
}
|
}
|
||||||
@@ -919,15 +887,15 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
|
|||||||
offset *= MIN_PER_HOUR;
|
offset *= MIN_PER_HOUR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// the spec was correct, construct the date from the values we found
|
// the spec was correct, construct the date from the values we found
|
||||||
Set(day, mon, year, hour, min, sec);
|
Set(day, mon, year, hour, min, sec);
|
||||||
MakeFromTimezone(TimeZone::Make(offset*SEC_PER_MIN));
|
MakeFromTimezone(TimeZone::Make(offset*SEC_PER_MIN));
|
||||||
|
|
||||||
const size_t endpos = p - date.wx_str();
|
|
||||||
if ( end )
|
if ( end )
|
||||||
*end = date.begin() + endpos;
|
*end = p;
|
||||||
|
|
||||||
return date.c_str() + endpos;
|
return wxAnyStrPtr(date, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
@@ -1090,13 +1058,13 @@ static wxString GetLocaleDateFormat()
|
|||||||
|
|
||||||
#endif // __WINDOWS__
|
#endif // __WINDOWS__
|
||||||
|
|
||||||
const char *
|
wxAnyStrPtr
|
||||||
wxDateTime::ParseFormat(const wxString& date,
|
wxDateTime::ParseFormat(const wxString& date,
|
||||||
const wxString& format,
|
const wxString& format,
|
||||||
const wxDateTime& dateDef,
|
const wxDateTime& dateDef,
|
||||||
wxString::const_iterator *end)
|
wxString::const_iterator *end)
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( !format.empty(), NULL, "format can't be empty" );
|
wxCHECK_MSG( !format.empty(), wxAnyStrPtr(), "format can't be empty" );
|
||||||
|
|
||||||
wxString str;
|
wxString str;
|
||||||
unsigned long num;
|
unsigned long num;
|
||||||
@@ -1147,7 +1115,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( *input++ != *fmt )
|
if ( *input++ != *fmt )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1162,7 +1130,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
while ( wxIsdigit(*++fmt) )
|
while ( wxIsdigit(*++fmt) )
|
||||||
{
|
{
|
||||||
width *= 10;
|
width *= 10;
|
||||||
width += *fmt - _T('0');
|
width += *fmt - '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// the default widths for the various fields
|
// the default widths for the various fields
|
||||||
@@ -1195,12 +1163,16 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
case _T('a'): // a weekday name
|
case _T('a'): // a weekday name
|
||||||
case _T('A'):
|
case _T('A'):
|
||||||
{
|
{
|
||||||
int flag = *fmt == _T('a') ? Name_Abbr : Name_Full;
|
wday = GetWeekDayFromName
|
||||||
wday = GetWeekDayFromName(GetAlphaToken(input), flag);
|
(
|
||||||
|
GetAlphaToken(input),
|
||||||
|
*fmt == 'a' ? Name_Abbr : Name_Full,
|
||||||
|
DateLang_Local
|
||||||
|
);
|
||||||
if ( wday == Inv_WeekDay )
|
if ( wday == Inv_WeekDay )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
haveWDay = true;
|
haveWDay = true;
|
||||||
@@ -1209,12 +1181,16 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
case _T('b'): // a month name
|
case _T('b'): // a month name
|
||||||
case _T('B'):
|
case _T('B'):
|
||||||
{
|
{
|
||||||
int flag = *fmt == _T('b') ? Name_Abbr : Name_Full;
|
mon = GetMonthFromName
|
||||||
mon = GetMonthFromName(GetAlphaToken(input), flag);
|
(
|
||||||
|
GetAlphaToken(input),
|
||||||
|
*fmt == 'b' ? Name_Abbr : Name_Full,
|
||||||
|
DateLang_Local
|
||||||
|
);
|
||||||
if ( mon == Inv_Month )
|
if ( mon == Inv_Month )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
haveMon = true;
|
haveMon = true;
|
||||||
@@ -1253,7 +1229,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
wxS("%X %x")
|
wxS("%X %x")
|
||||||
);
|
);
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
Tm tm = dt.GetTm();
|
Tm tm = dt.GetTm();
|
||||||
|
|
||||||
@@ -1276,7 +1252,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
(num > 31) || (num < 1) )
|
(num > 31) || (num < 1) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can't check whether the day range is correct yet, will
|
// we can't check whether the day range is correct yet, will
|
||||||
@@ -1289,7 +1265,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || (num > 23) )
|
if ( !GetNumericToken(width, input, &num) || (num > 23) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveHour = true;
|
haveHour = true;
|
||||||
@@ -1300,7 +1276,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
|
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveHour = true;
|
haveHour = true;
|
||||||
@@ -1312,7 +1288,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || !num || (num > 366) )
|
if ( !GetNumericToken(width, input, &num) || !num || (num > 366) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveYDay = true;
|
haveYDay = true;
|
||||||
@@ -1321,7 +1297,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
|
|
||||||
case _T('l'): // milliseconds (0-999)
|
case _T('l'): // milliseconds (0-999)
|
||||||
if ( !GetNumericToken(width, input, &num) )
|
if ( !GetNumericToken(width, input, &num) )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
haveMsec = true;
|
haveMsec = true;
|
||||||
msec = (wxDateTime_t)num;
|
msec = (wxDateTime_t)num;
|
||||||
@@ -1331,7 +1307,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
|
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveMon = true;
|
haveMon = true;
|
||||||
@@ -1342,7 +1318,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || (num > 59) )
|
if ( !GetNumericToken(width, input, &num) || (num > 59) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveMin = true;
|
haveMin = true;
|
||||||
@@ -1362,7 +1338,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
|
|
||||||
GetAmPmStrings(&am, &pm);
|
GetAmPmStrings(&am, &pm);
|
||||||
if (am.empty() && pm.empty())
|
if (am.empty() && pm.empty())
|
||||||
return NULL; // no am/pm strings defined
|
return wxAnyStrPtr(); // no am/pm strings defined
|
||||||
if ( token.CmpNoCase(pm) == 0 )
|
if ( token.CmpNoCase(pm) == 0 )
|
||||||
{
|
{
|
||||||
isPM = true;
|
isPM = true;
|
||||||
@@ -1370,7 +1346,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
else if ( token.CmpNoCase(am) != 0 )
|
else if ( token.CmpNoCase(am) != 0 )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1380,7 +1356,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
wxDateTime dt;
|
wxDateTime dt;
|
||||||
if ( !dt.ParseFormat(wxString(input, date.end()),
|
if ( !dt.ParseFormat(wxString(input, date.end()),
|
||||||
wxS("%I:%M:%S %p"), &input) )
|
wxS("%I:%M:%S %p"), &input) )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
haveHour = haveMin = haveSec = true;
|
haveHour = haveMin = haveSec = true;
|
||||||
|
|
||||||
@@ -1396,7 +1372,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
const wxDateTime
|
const wxDateTime
|
||||||
dt = ParseFormatAt(input, date.end(), wxS("%H:%M"));
|
dt = ParseFormatAt(input, date.end(), wxS("%H:%M"));
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
haveHour =
|
haveHour =
|
||||||
haveMin = true;
|
haveMin = true;
|
||||||
@@ -1411,7 +1387,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || (num > 61) )
|
if ( !GetNumericToken(width, input, &num) || (num > 61) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveSec = true;
|
haveSec = true;
|
||||||
@@ -1423,7 +1399,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
const wxDateTime
|
const wxDateTime
|
||||||
dt = ParseFormatAt(input, date.end(), wxS("%H:%M:%S"));
|
dt = ParseFormatAt(input, date.end(), wxS("%H:%M:%S"));
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
haveHour =
|
haveHour =
|
||||||
haveMin =
|
haveMin =
|
||||||
@@ -1440,7 +1416,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || (wday > 6) )
|
if ( !GetNumericToken(width, input, &num) || (wday > 6) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveWDay = true;
|
haveWDay = true;
|
||||||
@@ -1496,7 +1472,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
dt = ParseFormatAt(input, date.end(),
|
dt = ParseFormatAt(input, date.end(),
|
||||||
fmtDate, fmtDateAlt);
|
fmtDate, fmtDateAlt);
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
Tm tm = dt.GetTm();
|
Tm tm = dt.GetTm();
|
||||||
|
|
||||||
@@ -1517,7 +1493,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
// use strptime() to do it for us (FIXME !Unicode friendly)
|
// use strptime() to do it for us (FIXME !Unicode friendly)
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
if ( !CallStrptime(date, input, "%X", &tm) )
|
if ( !CallStrptime(date, input, "%X", &tm) )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
haveHour = haveMin = haveSec = true;
|
haveHour = haveMin = haveSec = true;
|
||||||
|
|
||||||
@@ -1536,7 +1512,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
const wxDateTime
|
const wxDateTime
|
||||||
dt = ParseFormatAt(input, date.end(), "%T", "%r");
|
dt = ParseFormatAt(input, date.end(), "%T", "%r");
|
||||||
if ( !dt.IsValid() )
|
if ( !dt.IsValid() )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
haveHour =
|
haveHour =
|
||||||
haveMin =
|
haveMin =
|
||||||
@@ -1554,7 +1530,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) || (num > 99) )
|
if ( !GetNumericToken(width, input, &num) || (num > 99) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveYear = true;
|
haveYear = true;
|
||||||
@@ -1568,7 +1544,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( !GetNumericToken(width, input, &num) )
|
if ( !GetNumericToken(width, input, &num) )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
haveYear = true;
|
haveYear = true;
|
||||||
@@ -1583,7 +1559,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( *input++ != _T('%') )
|
if ( *input++ != _T('%') )
|
||||||
{
|
{
|
||||||
// no match
|
// no match
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1593,7 +1569,7 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
// fall through
|
// fall through
|
||||||
|
|
||||||
default: // not a known format spec
|
default: // not a known format spec
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1634,22 +1610,14 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
if ( haveDay )
|
if ( haveDay )
|
||||||
{
|
{
|
||||||
if ( mday > GetNumberOfDays(tm.mon, tm.year) )
|
if ( mday > GetNumberOfDays(tm.mon, tm.year) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
wxLogDebug(_T("bad month day in wxDateTime::ParseFormat"));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tm.mday = mday;
|
tm.mday = mday;
|
||||||
}
|
}
|
||||||
else if ( haveYDay )
|
else if ( haveYDay )
|
||||||
{
|
{
|
||||||
if ( yday > GetNumberOfDays(tm.year) )
|
if ( yday > GetNumberOfDays(tm.year) )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
wxLogDebug(_T("bad year day in wxDateTime::ParseFormat"));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tm tm2 = wxDateTime(1, Jan, tm.year).SetToYearDay(yday).GetTm();
|
Tm tm2 = wxDateTime(1, Jan, tm.year).SetToYearDay(yday).GetTm();
|
||||||
|
|
||||||
@@ -1688,19 +1656,15 @@ wxDateTime::ParseFormat(const wxString& date,
|
|||||||
|
|
||||||
// finally check that the week day is consistent -- if we had it
|
// finally check that the week day is consistent -- if we had it
|
||||||
if ( haveWDay && GetWeekDay() != wday )
|
if ( haveWDay && GetWeekDay() != wday )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
wxLogDebug(_T("inconsistsnet week day in wxDateTime::ParseFormat()"));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( end )
|
if ( end )
|
||||||
*end = input;
|
*end = input;
|
||||||
|
|
||||||
return date.c_str() + (input - date.begin());
|
return wxAnyStrPtr(date, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
wxAnyStrPtr
|
||||||
wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
|
wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
|
||||||
{
|
{
|
||||||
// Set to current day and hour, so strings like '14:00' becomes today at
|
// Set to current day and hour, so strings like '14:00' becomes today at
|
||||||
@@ -1723,7 +1687,7 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
|
|||||||
|
|
||||||
const wxString timestr(endDate, date.end());
|
const wxString timestr(endDate, date.end());
|
||||||
if ( !dtTime.ParseTime(timestr, &endTime) )
|
if ( !dtTime.ParseTime(timestr, &endTime) )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
endBoth = endDate + (endTime - timestr.begin());
|
endBoth = endDate + (endTime - timestr.begin());
|
||||||
}
|
}
|
||||||
@@ -1731,14 +1695,14 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
|
|||||||
{
|
{
|
||||||
// check if we have a time followed by a date
|
// check if we have a time followed by a date
|
||||||
if ( !dtTime.ParseTime(date, &endTime) )
|
if ( !dtTime.ParseTime(date, &endTime) )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
while ( endTime != date.end() && wxIsspace(*endTime) )
|
while ( endTime != date.end() && wxIsspace(*endTime) )
|
||||||
++endTime;
|
++endTime;
|
||||||
|
|
||||||
const wxString datestr(endTime, date.end());
|
const wxString datestr(endTime, date.end());
|
||||||
if ( !dtDate.ParseDate(datestr, &endDate) )
|
if ( !dtDate.ParseDate(datestr, &endDate) )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
endBoth = endTime + (endDate - datestr.begin());
|
endBoth = endTime + (endDate - datestr.begin());
|
||||||
}
|
}
|
||||||
@@ -1751,10 +1715,10 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
|
|||||||
if ( end )
|
if ( end )
|
||||||
*end = endBoth;
|
*end = endBoth;
|
||||||
|
|
||||||
return date.c_str() + (endBoth - date.begin());
|
return wxAnyStrPtr(date, endBoth);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
wxAnyStrPtr
|
||||||
wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
||||||
{
|
{
|
||||||
// this is a simplified version of ParseDateTime() which understands only
|
// this is a simplified version of ParseDateTime() which understands only
|
||||||
@@ -1801,8 +1765,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
if ( end )
|
if ( end )
|
||||||
*end = pEnd;
|
*end = pEnd;
|
||||||
|
|
||||||
return wxStringOperations::AddToIter(date.c_str().AsChar(),
|
return wxAnyStrPtr(date, pEnd);
|
||||||
pEnd - pBegin);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1906,7 +1869,12 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
else // not a number
|
else // not a number
|
||||||
{
|
{
|
||||||
// be careful not to overwrite the current mon value
|
// be careful not to overwrite the current mon value
|
||||||
Month mon2 = GetMonthFromName(token, Name_Full | Name_Abbr);
|
Month mon2 = GetMonthFromName
|
||||||
|
(
|
||||||
|
token,
|
||||||
|
Name_Full | Name_Abbr,
|
||||||
|
DateLang_Local | DateLang_English
|
||||||
|
);
|
||||||
if ( mon2 != Inv_Month )
|
if ( mon2 != Inv_Month )
|
||||||
{
|
{
|
||||||
// it's a month
|
// it's a month
|
||||||
@@ -1934,7 +1902,12 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
}
|
}
|
||||||
else // not a valid month name
|
else // not a valid month name
|
||||||
{
|
{
|
||||||
WeekDay wday2 = GetWeekDayFromName(token, Name_Full | Name_Abbr);
|
WeekDay wday2 = GetWeekDayFromName
|
||||||
|
(
|
||||||
|
token,
|
||||||
|
Name_Full | Name_Abbr,
|
||||||
|
DateLang_Local | DateLang_English
|
||||||
|
);
|
||||||
if ( wday2 != Inv_WeekDay )
|
if ( wday2 != Inv_WeekDay )
|
||||||
{
|
{
|
||||||
// a week day
|
// a week day
|
||||||
@@ -2013,11 +1986,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
// either no more tokens or the scan was stopped by something we couldn't
|
// either no more tokens or the scan was stopped by something we couldn't
|
||||||
// parse - in any case, see if we can construct a date from what we have
|
// parse - in any case, see if we can construct a date from what we have
|
||||||
if ( !haveDay && !haveWDay )
|
if ( !haveDay && !haveWDay )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
wxLogDebug(_T("ParseDate: no day, no weekday hence no date."));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( haveWDay && (haveMon || haveYear || haveDay) &&
|
if ( haveWDay && (haveMon || haveYear || haveDay) &&
|
||||||
!(haveDay && haveMon && haveYear) )
|
!(haveDay && haveMon && haveYear) )
|
||||||
@@ -2025,7 +1994,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
// without adjectives (which we don't support here) the week day only
|
// without adjectives (which we don't support here) the week day only
|
||||||
// makes sense completely separately or with the full date
|
// makes sense completely separately or with the full date
|
||||||
// specification (what would "Wed 1999" mean?)
|
// specification (what would "Wed 1999" mean?)
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !haveWDay && haveYear && !(haveDay && haveMon) )
|
if ( !haveWDay && haveYear && !(haveDay && haveMon) )
|
||||||
@@ -2051,12 +2020,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( !haveMon )
|
if ( !haveMon )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
// if we give the year, month and day must be given too
|
|
||||||
wxLogDebug(_T("ParseDate: day and month should be specified if year is."));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !haveMon )
|
if ( !haveMon )
|
||||||
@@ -2074,7 +2038,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
// normally we check the day above but the check is optimistic in case
|
// normally we check the day above but the check is optimistic in case
|
||||||
// we find the day before its month/year so we have to redo it now
|
// we find the day before its month/year so we have to redo it now
|
||||||
if ( day > GetNumberOfDays(mon, year) )
|
if ( day > GetNumberOfDays(mon, year) )
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
|
|
||||||
Set(day, mon, year);
|
Set(day, mon, year);
|
||||||
|
|
||||||
@@ -2082,12 +2046,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
{
|
{
|
||||||
// check that it is really the same
|
// check that it is really the same
|
||||||
if ( GetWeekDay() != wday )
|
if ( GetWeekDay() != wday )
|
||||||
{
|
return wxAnyStrPtr();
|
||||||
// inconsistency detected
|
|
||||||
wxLogDebug(_T("ParseDate: inconsistent day/weekday."));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // haveWDay
|
else // haveWDay
|
||||||
@@ -2109,17 +2068,17 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
|
|||||||
if ( end )
|
if ( end )
|
||||||
*end = p;
|
*end = p;
|
||||||
|
|
||||||
return wxStringOperations::AddToIter(date.c_str().AsChar(), p - pBegin);
|
return wxAnyStrPtr(date, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
wxAnyStrPtr
|
||||||
wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
|
wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
|
||||||
{
|
{
|
||||||
// first try some extra things
|
// first try some extra things
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
wxDateTime_t hour;
|
wxDateTime_t hour;
|
||||||
} stdTimes[] =
|
} stdTimes[] =
|
||||||
{
|
{
|
||||||
{ wxTRANSLATE("noon"), 12 },
|
{ wxTRANSLATE("noon"), 12 },
|
||||||
@@ -2129,17 +2088,17 @@ wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
|
|||||||
|
|
||||||
for ( size_t n = 0; n < WXSIZEOF(stdTimes); n++ )
|
for ( size_t n = 0; n < WXSIZEOF(stdTimes); n++ )
|
||||||
{
|
{
|
||||||
wxString timeString = wxGetTranslation(stdTimes[n].name);
|
const wxString timeString = wxGetTranslation(stdTimes[n].name);
|
||||||
size_t len = timeString.length();
|
const wxString::const_iterator p = time.begin() + timeString.length();
|
||||||
if ( timeString.CmpNoCase(wxString(time, len)) == 0 )
|
if ( timeString.CmpNoCase(wxString(time.begin(), p)) == 0 )
|
||||||
{
|
{
|
||||||
// casts required by DigitalMars
|
// casts required by DigitalMars
|
||||||
Set(stdTimes[n].hour, wxDateTime_t(0), wxDateTime_t(0));
|
Set(stdTimes[n].hour, wxDateTime_t(0), wxDateTime_t(0));
|
||||||
|
|
||||||
if ( end )
|
if ( end )
|
||||||
*end = time.begin() + len;
|
*end = p;
|
||||||
|
|
||||||
return time.c_str() + len;
|
return wxAnyStrPtr(time, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2159,12 +2118,12 @@ wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
|
|||||||
|
|
||||||
for ( size_t nFmt = 0; nFmt < WXSIZEOF(timeFormats); nFmt++ )
|
for ( size_t nFmt = 0; nFmt < WXSIZEOF(timeFormats); nFmt++ )
|
||||||
{
|
{
|
||||||
const char *result = ParseFormat(time, timeFormats[nFmt], end);
|
const wxAnyStrPtr result = ParseFormat(time, timeFormats[nFmt], end);
|
||||||
if ( result )
|
if ( result )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return wxAnyStrPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -206,6 +206,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
# --- wxBase headers list begins here ---
|
# --- wxBase headers list begins here ---
|
||||||
cat <<EOF >wxbase-headers.files
|
cat <<EOF >wxbase-headers.files
|
||||||
wx/afterstd.h
|
wx/afterstd.h
|
||||||
|
wx/anystr.h
|
||||||
wx/app.h
|
wx/app.h
|
||||||
wx/apptrait.h
|
wx/apptrait.h
|
||||||
wx/archive.h
|
wx/archive.h
|
||||||
|
@@ -111,6 +111,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
# --- wxBase headers list begins here ---
|
# --- wxBase headers list begins here ---
|
||||||
cat <<EOF >wxbase-headers.files
|
cat <<EOF >wxbase-headers.files
|
||||||
wx/afterstd.h
|
wx/afterstd.h
|
||||||
|
wx/anystr.h
|
||||||
wx/app.h
|
wx/app.h
|
||||||
wx/apptrait.h
|
wx/apptrait.h
|
||||||
wx/archive.h
|
wx/archive.h
|
||||||
|
@@ -135,6 +135,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
# --- wxBase headers list begins here ---
|
# --- wxBase headers list begins here ---
|
||||||
cat <<EOF >wxbase-headers.files
|
cat <<EOF >wxbase-headers.files
|
||||||
wx/afterstd.h
|
wx/afterstd.h
|
||||||
|
wx/anystr.h
|
||||||
wx/app.h
|
wx/app.h
|
||||||
wx/apptrait.h
|
wx/apptrait.h
|
||||||
wx/archive.h
|
wx/archive.h
|
||||||
|
Reference in New Issue
Block a user