|
A date is a unit that measures the number of years,
months, or days elapsed in a series of alternate sunrises and sunsets. To
represent the dates, computers, applications, and compilers are configured
with specific techniques. The C++Builder compiler counts dates from
12/30/1899 at midnight. With this compiler, dates and related operations are
dealt with using a class called TDateTime. Since this class is not a
control, you can use it with any control that displays text.
|
The dates used in your applications will mostly be
based on the TDateTime class. To perform most operations in your programs,
you will need to know when, how, and where to use this class. As an
object, you will need to declare it.
To declare a date value, use one of the TDateTime
constructors:
System::TDateTime * __fastcall TDateTime(void);
System::TDateTime * __fastcall TDateTime(int src);
System::TDateTime * __fastcall TDateTime(double src);
System::TDateTime * __fastcall TDateTime(const System::TDateTime & src);
System::TDateTime * __fastcall TDateTime(const System::TDateTimeBase & src);
System::TDateTime * __fastcall TDateTime(const System::UnicodeString & src,
System::TDateTime::TDateTimeFlag flag);
System::TDateTime * __fastcall TDateTime(unsigned short year,
unsigned short month,
unsigned short day);
System::TDateTime * __fastcall TDateTime(unsigned short hour,
unsigned short min,
unsigned short sec,
unsigned short msec);
System::TDateTime * __fastcall TDateTime(unsigned short year,
unsigned short month,
unsigned short day,
unsigned short hour,
unsigned short min,
unsigned short sec,
unsigned short msec);
The simplest way is to use the default constructor and
provide a valid C++ name. Here is an example:
TDateTime dt;
If not assigned a value, this variable is initialized
to 12/30/1899 at midnight. If you know the exact date that you want to
initialize, you have two alternatives. You can initialize the variable
using a string. Here is an example:
TDateTime dt(L"12/05/1990");
This could also be written as:
UnicodeString S = L"05/04/1988";
TDateTime Mine = S;
You can also provide the integer values of the year,
the month, and the day respectively. Here is an example:
TDateTime dt(1990, 11, 26);
To initialize a date, you can also provide an integer
that represents the number of days passed since 1899 to the specified
date. Here is an example:
TDateTime dt = 33895;
The simplest way to get the date in your application
consists of calling the Date() function. For example, you
can use it to display the current date:
- In an Edit control: edtToday->Text = Date();
- On a label: Label1->Caption = Date();
- In a form’s title bar: Form1->Caption = Date();
Date, String, and Numeric Conversions
|
|
Converting a String to Date
|
|
Unless you are using a special control that recognizes
date values, most of the controls will receive and display text. For this
reason, as far as the compiler is concerned, the user or the client of a
control would be supplying text derived from a UnicodeString
class. Therefore, before performing any operation on such a text, you will
have to convert the content of the control to a valid date. In the same
way, if you want the compiler to consider a date value as a "normal"
string, you would convert the date value into a string.
If the user types a valid date into an edit box, such
as 10/4/1988, this is still considered a string and you would not be able
to use it in an operation. To convert a string to a date, you can use the
StrToDate() function. Its syntax is:
System::TDateTime __fastcall StrToDate(System::UnicodeString S);
This function takes an argument as the string that
needs to be converted. The string must be provided in a recognizable
format, following the Regional Settings of the Windows Control Panel. For
example, in the United States, the components of a date are separated with
a forward slash "/”. The typical formats of a date are:
If the string contains an invalid date, the conversion
would fail and the program would throw an error. If the conversion is
successful, the function would return a valid date. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm2::btnConvertClick(TObject *Sender)
{
TDateTime Value = StrToDate(edtSource->Text);
edtTarget->Text = Value;
}
//---------------------------------------------------------------------------
Converting a Date to a String
|
|
The TDateTime and the
UnicodeString classes are configured to work in harmony and allow
great flexibility. This allows a TDateTime date value to
be easily recognized by, and converted to, a UnicodeString
string. Unless you are performing detailed formatting, a date value can be
transparently identified as a string. For this reason, you can display a
date value as a string without any conversion. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime AFewMonthsAgo(L"04/28/1998");
Edit1->Text = AFewMonthsAgo;
}
//---------------------------------------------------------------------------
A UnicodeString string is able to
recognize a TDateTime value because the
UnicodeString operator is defined in the TDateTime
class. Its syntax is:
System::UnicodeString __fastcall operator ()(void);
The UnicodeString() operator function allows
any valid TDateTime value to be automatically converted to a string when
needed. You can also explicitly use the function if necessary. Here is an
example:TDateTime value to be automatically converted to
a string when needed. You can also explicitly use the function if
necessary. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TfrmExercise::btnConvertClick(TObject *Sender)
{
TDateTime AFewMonthsAgo(L"06/28/2010");
UnicodeString Converted = AFewMonthsAgo.operator UnicodeString();
edtResult->Text = Converted;
}
//---------------------------------------------------------------------------
If you have a date value that needs to be converted to
a string, you can use the DateToStr() function. Its syntax is:
System::UnicodeString __fastcall DateToStr(System::TDateTime DateTime);
This function takes one argument, which is the date
value that needs to be converted. If the argument is not a valid date, the
conversion would fail and the program would throw an error (in simple but
practical terms, the program would crash). If the conversion is
successful, the function returns a string. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnConvertClick(TObject *Sender)
{
UnicodeString Current = DateToStr(Date());
edtResult->Text = Current;
}
//---------------------------------------------------------------------------
Alternatively, you can use the
TDateTime::DateString() function to convert a valid date to a string.
The syntax of the DateString() method is:
System::UnicodeString __fastcall DateString(void);
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime Today = Date();
UnicodeString Value = Today.DateString();
Edit1->Text = Value;
}
//---------------------------------------------------------------------------
Converting a Date to a Double-Precision Number
|
|
A TDateTime value can be configured
to display as a decimal number. The syntax used is:
__fastcall operator double() const;
The double data type was overloaded
in the TDateTime class to allow converting a
TDateTime value to a fractional equivalent. The number can be
made of two parts. If the number is round, that is, without a decimal
value, it represents the number of days elapsed since 12/30/1899. If the
number has a decimal part, the decimal portion represents a fraction of
the day over a 24-hour period.
The operator double() function can be
used to get the number of days and the amount of time elapsed since
12/30/1899 at midnight and the time of the current date. In the following
example, the difference between the current date and time and 12/30/1899
at midnight is displayed as a double-precision number in an edit control
of a form when the form comes up:
//---------------------------------------------------------------------------
void __fastcall TForm2::FormCreate(TObject *Sender)
{
TDateTime RightNow = Now();
double Qty = RightNow.operator double();
Edit1->Text = Qty;
}
//---------------------------------------------------------------------------
To convert a TDateTime value to double using
the double overloaded operator, declare a double variable and
assign the TDateTime variable to it by calling the operator double()
function. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDifferenceClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
TDateTime Diff = End - Start;
double d = Diff.operator double();
edtDifference->Text = d;
}
//---------------------------------------------------------------------------
Converting a Date Value to an Integer
|
|
Like the double data type, the int data
type was overloaded in the TDateTime class to convert a TDateTime value to
an integer. The syntax of the function is:
__fastcall operator int() const;
To get the equivalent number of days of a TDateTime
value, declare an integer and assign it the desired TDateTime value by
calling the operator int() function. If the operator is applied on a
variable that holds a particular and valid date, the operator int()
function would produce the number of days elapsed since 12/30/1899. In the
following example, the number of days since 12/30/1899 to the current date
is displayed in an Edit control when the user clicks the button:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnShowDaysClick(TObject *Sender)
{
TDateTime Today = Date();
int Days = Today.operator int();
edtDifference->Text = Days;
}
//---------------------------------------------------------------------------
The Computer’s System of Displaying Dates
|
|
Your computer and your customer’s use a set of
attributes to display date values. These are provided or configured in the
Region and Language section of the Control Panel. The formats are
available in the Formats tab, in the Date And Time Formats section:
The computer uses two main categories of date display.
These categories are based on the language used by the user's computer.
For example, most users computers that reside in the United States use a
standard known as US English. This commands how the date displays in the
continental US. Each category uses specific characters to represent its
value. The m or M is used for a month, the d or D is used for a day, and
the y or Y is used for the year.
The Short Date Format is a special string that all
applications of a user's computer refer to in order to display a date
using the numeric version of a date.
The months hold the values 1 (for January), 2 (for
February), 3 (for March), 4 (for April), 5 (for May), 6 (for June), 7 (for
July), 8 (for August), 9 (for September), 10 (for October), 11 (for
November), and 12 (for December). Instead of numbers, a month is
represented with the letter m; the computer has the responsibility of
finding the right month.
The computer refers to the following characters and it
depends on how these characters are retrieved:
Character |
Meaning |
Why use it? |
m or
M |
The month displays
as a single digit if the numeric month is less than 10 |
Can be used to
display May as 5 instead of 05 |
mm or
MM |
The month displays a
leading 0 if the numeric month is less than 10 |
Can be used to
display May as 05 instead of 5 |
d or
D |
The day displays as
a single digit if the day of the month is less than 10 |
Can be used to
display the 8th of the month as 8 and not 08 |
dd or
DD |
The day displays a
leading 0 if the day of the month is less than 10 |
Can be used to
display 8th day of the month as 08 and not 8 |
y,
yy, Y, or YY |
The year displays
with two digits like 88 for 1988 |
Used when two digits
suffice to display the year |
yyy,
YYY, yyyy, YYYY |
The year displays
with 4 digits such as 1988 and not 88 |
Used to display all
digits for a year |
To display a date value, use the syntax:
ShortDateFormat = L"Format";
To create a format, assign an appropriate string to
the ShortDateFormat variable. After creating such a format, you can
display a date value in the desired control. Before displaying the date,
the compiler would scan the event or function and find out what format to
apply. Here are examples of displaying individual portions of a date
value:
//---------------------------------------------------------------------------
void __fastcall TfrmExercise::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
ShortDateFormat = L"d";
edtD->Text = DateValue;
ShortDateFormat = L"dd";
edtDD->Text = DateValue;
ShortDateFormat = L"M";
edtM->Text = DateValue;
ShortDateFormat = L"MM";
edtMM->Text = DateValue;
ShortDateFormat = L"y";
edtY->Text = DateValue;
ShortDateFormat = L"yy";
edtYY->Text = DateValue;
ShortDateFormat = L"yyy";
edtYYY->Text = DateValue;
ShortDateFormat = L"yyyy";
edtYYYY->Text = DateValue;
}
//---------------------------------------------------------------------------
Besides using any of these characters to display their
corresponding portion of a date, you can also combine these characters to
display a semi or complete date. To do this, you will need a symbol or
character that separates the portions of a date. In the US English, the
most common character used to separate the portions of a date is the
forward slash "/”. Another character used is the dash "-".
Using a combination of the above characters, the
operating system proposes a list of possible formats for date display.
The combinations are in the Short Date combo box:
Here are examples of displaying the formats specified
by the operating system:
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
ShortDateFormat = L"M/d/yyyy";
edtMdyyyy->Text = DateValue;
ShortDateFormat = L"M/d/yy";
edtMdyy->Text = DateValue;
ShortDateFormat = L"MM/dd/yy";
edtMMddyy->Text = DateValue;
ShortDateFormat = L"MM/dd/yyyy";
edtMMddyyyy->Text = DateValue;
ShortDateFormat = L"yy/MM/dd";
edtyyMMdd->Text = DateValue;
ShortDateFormat = L"yyyy-MM-dd";
edtyyyyMMdd->Text = DateValue;
ShortDateFormat = L"dd-MMM-yy";
edtddMMMyy->Text = DateValue;
}
//---------------------------------------------------------------------------
In the same way, you can create your own formats.
The operating system provides a more explicit system
of displaying date values. This is called the Long Date Format and
it uses a global variable called LongDateFormat. This variable is
defined in the Regional Options of the Control Panel. When using the
LongDateFormat, there are various types of combinations applied to the
characters, depending on what you are trying to display.
To display the date using the Long Date Format
formats, the computer uses the following combinations:
Format |
Description |
d |
The single d is
used to display the numeric day of a month. Each month starts
at 1, then 2, and so on. The month of February can have 28 or
29 days depending on whether the year is a leap year. The
other months have 30 or 31 days. If the day occurs before the
10th, the number would display without the leading 0 |
dd |
The double d as
dd displays the numeric day of the month, from 1 tom 31
depending on the month and whether it is a leap year for
February. If the month occurs before October, it would display
with the leading 0 |
M |
The single M is
used to display the numeric position of the month. January is
1, February is 2 and December is 12. If the month occurs
before October, it would display without the leading 0 |
MM |
The double M as
MM displays the numeric position of a month from 1 to 12. If
the number is less than 10, it would display with the leading
0 |
MMM |
The triple M as
MMM displays the name of the month using three letters. It
uses a global variable called ShortMonthNames. This
variable is defined by the operating system. By default, the
names of the month are Jan, Feb, Mar, Apr, May, Jun, Jul, Aug,
Sep, Oct, Nov, and Dec |
MMMM |
The quadruple M
as MMMM displays the complete name of a month as defined as
the operating system. The variable used is called
LongMonthNames. The names of the months are January,
February, March, April, May, June, July, August, September,
October, November, and December |
Y or YY |
The single y or
double yy is used to display the numeric year with the last
two digits |
YYY or YYYY |
The triple y as
yyy or the quadruple one as yyyy is used to display all four
digits of a year |
Any control that uses a UnicodeString can display a
date. From the declarations we have seen, if you create an initialized
date, you can use the DateToStr() function to display it. If you
use a date variable declared with the default construction, the control
would display the first date the compiler can recognize:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime Mine;
Edit1->Text = DateToStr(Mine);
}
//---------------------------------------------------------------------------
If the date is initialized with a valid date value,
you can omit the conversion function:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime Mine(L"12/05/1990");
Edit1->Text = Mine;
}
//---------------------------------------------------------------------------
If you supply the integer values of the variable, the
compiler would take care of displaying the equivalent date:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime Mine(1990, 11, 26);
Edit1->Text = Mine;
}
//---------------------------------------------------------------------------
In the same way, if you initialize the variable with a
number of days as an integer, the compiler would calculate and display the
corresponding date:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime Mine = 33895;
Edit1->Text = Mine;
}
//---------------------------------------------------------------------------
A date variable declared from the TDateTime class is
made of a year, a month, and a day values. Decoding a date consists of
isolating or retrieving these components of a date value. To perform such
an operation, the TDateTime class is equipped with the DecodeDate()
method. Its syntax is:
void __fastcall DecodeDate(unsigned short* year,
unsigned short* month,
unsigned short* day) const;
Each component is retrieved using a pointer to an
unsigned short. The presence of pointers allows you to pass "empty”
variables whose value would be altered by the function and returned with
new values.
In the following example, the current date is stored
in a TDateTime variable. Then the year, month, and day of the variable are
extracted before constructing a sentence to display on a label:
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TDateTime Today = Date();
unsigned short Year, Month, Day;
Today.DecodeDate(&Year, &Month, &Day);
Label1->Caption = L"Today is the " + String(Day) +
L" of month " + Month +
L" of the year " + Year + L".";
}
//---------------------------------------------------------------------------
If you want to display a better English version of the
sentence above, you can format the date components to your liking. Here is
an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TDateTime Today = Date();
UnicodeString Dayth, Monthth;
unsigned short Year, Month, Day;
Today.DecodeDate(&Year, &Month, &Day);
if( Day == 1 )
Dayth = L"st";
else if( Day == 2 )
Dayth = L"nd";
else if( Day == 3 )
Dayth = L"rd";
else
Dayth = L"th";
if( Month == 1 )
Monthth = L"st";
else if( Month == 2 )
Monthth = L"nd";
else if( Month == 3 )
Monthth = L"rd";
else
Monthth = L"th";
Label1->Caption = L"Today is the " + String(Day) + Dayth +
L" of the " + Month + Monthth +
L" month of the year " + Year + L".";
}
//---------------------------------------------------------------------------
The DecodeDate() function comes in two
versions. Besides the TDateTime’s, the VCL provides another version whose
syntax is:
void __fastcall DecodeDate(System::TDateTime Date,
Word &Year,
Word &Month,
Word &Day);
Since this version is class-independent, the first
argument you must supply is a TDateTime value or
variable. This time, the year, the month, and the day values are passed by
reference, which also allows the function to return them altered.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDecodeClick(TObject *Sender)
{
TDateTime Typed = StrToDate(edtDate->Text);
Word Year, Month, Day;
DecodeDate(Typed, Year, Month, Day);
edtDay->Text = Day;
edtMonth->Text = Month;
edtYear->Text = Year;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnCloseClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
If you want to get or display the English name of the
decoded month, you can write a conditional switch whose cases
would represent the months by their integral position. You can also
declare a UnicodeString variable to hold the names of months and retrieve
the necessary one when needed. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDecodeClick(TObject *Sender)
{
TDateTime Typed = StrToDate(edtDate->Text);
Word Year, Month, Day;
UnicodeString Months[] = { L"",
L"January", L"February", L"March", L"April",
L"May", L"June", L"July", L"August",
L"September", L"October", L"November", L"December"
};
DecodeDate(Typed, Year, Month, Day);
edtDay->Text = Day;
edtMonth->Text = Months[Month];
edtYear->Text = Year;
}
//---------------------------------------------------------------------------
Encoding a date consists of supplying the necessary
components of a TDateTime object to the compiler to
create a valid TDateTime value. The function used to
perform this operation is:
TDateTime __fastcall EncodeDate(Word Year, Word Month, Word Day);
This function takes three positive integers (unsigned
short) that represent:
- The year: valid values range from 0 to 9999;
- The month: valid values range from 1 to 12; January is 1, February
is 2, etc;
- The day: this could be 28, 29, 30, or 31 depending on the month
and whether the year is a leap year, which controls the number of days
for the month of February.
The following form is equipped with four Edit controls
named edtDay, edtMonth, edtYear and edtDate. When the user clicks the
Encode button named btnEncode, the OnClick event retrieves the values of
the day, the month, and the year from their respective edit boxes. Then
the compiler creates a date from those and displays it in the Date edit
box:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnEncodeClick(TObject *Sender)
{
Word Day, Month, Year;
Day = edtDay->Text.ToInt();
Month = edtMonth->Text.ToInt();
Year = edtYear->Text.ToInt();
TDateTime Value = EncodeDate(Year, Month, Day);
edtDate->Text = Value;
}
//---------------------------------------------------------------------------
One of the arduous operations performed on date values
is to find out whether the year value of a date is a leap year. Luckily,
the IsLeapYear() function can perform it. The syntax of this
function is:
bool __fastcall IsLeapYear(Word Year);
This function takes an unsigned short integer
argument variable and examines it. If the argument, which must be a valid
year number, is a leap year, the function returns true; otherwise,
it would return false. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TfrmExercise::btnCheckClick(TObject *Sender)
{
if( IsLeapYear(edtYear->Text.ToInt()) )
edtLeapYear->Text = L"Yes";
else
edtLeapYear->Text = L"No";
}
//---------------------------------------------------------------------------
The following example starts by requesting a date
value from the user using an InputBox() function. Then the date is
decoded to retrieve the year value. The year is examined to find out
whether it is a leap year, using the IsLeapYear() function. The
function displays a message box to show its findings:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnLeapYearClick(TObject *Sender)
{
unsigned short Year, Month, Day;
UnicodeString Value = InputBox(L"Date and Time", "Enter a date: ",
L"01/01/1900");
TDateTime Examiner = StrToDate(Value);
Examiner.DecodeDate(&Year, &Month, &Day);
UnicodeString LeapYear = IsLeapYear(Year) ?
L" is a leap year" :
L" is not a leap year";
ShowMessage(L"The date you typed was " + Value + L"\n" +
UnicodeString(Year) + LeapYear);
}
//---------------------------------------------------------------------------
The VCL is equipped with a special function that can
be used to retrieve the day of the week for a given date. The function
used is the DayOfWeek() and its syntax is:
int __fastcall DayOfWeek(System::TDateTime Date);
To use this function, pass a TDateTime value or
variable to the DayOfWeek() function. The TDateTime object passed
as argument must hold a valid date value. After execution, the function
returns an integer between 1 (included) and 7 (included) that represents
the position of the day. Sunday is referred to as the first day of the
week and has a value of 1; Monday is 2, etc.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnGetItClick(TObject *Sender)
{
TDateTime Value = StrToDate(edtDate->Text);
int Day = DayOfWeek(Value);
edtDayOfWeek->Text = Day;
}
//---------------------------------------------------------------------------
Of course, sometimes you will want to get or display
the English name of the day. To do this, you can write a switch
conditional statement that would display a name accordingly. Here is an
example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnGetItClick(TObject *Sender)
{
TDateTime Value = StrToDate(edtDate->Text);
int Day = DayOfWeek(Value);
UnicodeString DayName;
switch(Day)
{
case 1:
DayName = L"Sunday";
break;
case 2:
DayName = L"Monday";
break;
case 3:
DayName = L"Tuesday";
break;
case 4:
DayName = L"Wednesday";
break;
case 5:
DayName = L"Thursday";
break;
case 6:
DayName = L"Friday";
break;
case 7:
DayName = L"Saturday";
}
edtDay->Text = DayName;
}
//---------------------------------------------------------------------------
An alternative would be to declare an array of
UnicodeString strings to hold the names of the week days, then retrieve
the necessary one using its corresponding position. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnGetItClick(TObject *Sender)
{
TDateTime Value = StrToDate(edtDate->Text);
int Day = DayOfWeek(Value);
UnicodeString DayName[] = { L"",
L"Sunday", L"Monday", L"Tuesday", L"Wednesday",
L"Thursday", L"Friday", L"Saturday"
};
edtDay->Text = DayName[Day];
}
//---------------------------------------------------------------------------
The DayOfWeek() function comes in two versions.
Besides the VCL’s, the TDateTime class also is equipped
with this method. Its syntax is:
int __fastcall DayOfWeek() const;
This version does not take an argument. Instead, it is
called by a TDateTime variable that needs it. This function returns an
integer that represents the weekly position of the day if the execution is
successful. The equivalent version of the above program would be:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnGetItClick(TObject *Sender)
{
TDateTime Value = StrToDate(edtDate->Text);
int Day = Value.DayOfWeek();
edtDay->Text = Day;
}
//---------------------------------------------------------------------------
Increasing Months on a Date
|
|
The addition operator of the TDateTime class is used
to add a number of days to a date value. If you want to add months to a
date value, you can use the IncMonth() function. Its syntax is:
TDateTime __fastcall IncMonth(const TDateTime Source, int Months);
This function takes two arguments. The first is the
date value or variable that serves as the source or reference to work on.
This argument must hold a valid TDateTime date value; otherwise the
execution would fail. The second argument, Months is an integer that
represents the number of months to be added to the first argument. If the
addition is successful, the IncMonth() function returns a new
TDateTime value.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::edtMonthsExit(TObject *Sender)
{
TDateTime StartDate = edtStartDate->Text;
int Months = edtMonths->Text.ToInt();
TDateTime NextPeriod = IncMonth(StartDate, Months);
edtNextPeriod->Text = NextPeriod;
}
//---------------------------------------------------------------------------
The IncMonth() is used to both add and subtract
months from a date. To subtract months, pass the Months argument with a
negative value. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TfrmExercise::edtMonthsChange(TObject *Sender)
{
TDateTime StartDate = edtStartDate->Text;
int Months = edtMonths->Text.ToInt();
TDateTime NextPeriod = IncMonth(StartDate, -Months);
edtNextPeriod->Text = NextPeriod;
}
//---------------------------------------------------------------------------
The ReplaceDate() function allows replacing one
date with another.
void __fastcall ReplaceDate(TDateTime &Target, const TDateTime Source);
On the function, the Target argument is the new date
whose value needs to be replaced by that of the Source argument. Since the
starting point of the TDateTime class is on 12/30/1899, if the Source
argument occurs before that the date, the ReplaceDate() function
takes care of reconciling the negative date. Here is an example of using
the function:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnReplaceClick(TObject *Sender)
{
TDateTime Original = StrToDate(edtOriginal->Text);
TDateTime Replacement;
ReplaceDate(Replacement, Original);
edtReplacement->Text = DateToStr(Replacement);
}
//---------------------------------------------------------------------------
Comparison Operations on Dates
|
|
The TDateTime class was configured
with many arithmetic and comparison operators. These are used on date
values allowing you to use TDateTime variables as if they were regular
variables.
The Comparison for Equality
|
|
To find out whether two data values are the same,
simply apply the equality operator on their values. Once you have two
TDateTime values or variables, the compiler is configured
to perform this comparison.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if(Start == End)
pnlComparison->Caption = L"Both dates are the same";
else
pnlComparison->Caption = L"Those are different dates!";
}
//---------------------------------------------------------------------------
This comparison is possible because the equality
operator "==" was overloaded in the TDateTime class. Its
syntax is:
bool __fastcall operator ==(const TDateTime& Target) const;
To compare two dates using the overloaded equality
operator, call the operator==() on the desired date and supply the
argument date value that is being compared against the Target. The above
could have been written:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start.operator ==(End) )
pnlComparison->Caption = L"Both dates are the same";
else
pnlComparison->Caption = L"Those are different dates!";
}
//---------------------------------------------------------------------------
The Comparison for Inequality
|
|
To find out whether two date values are not the same,
simply apply the inequality operator on their values. Once you have two
TDateTime values or variables, the compiler is configured to perform this
comparison.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start != End )
pnlComparison->Caption = L"Those are different dates!";
else
pnlComparison->Caption = L"Both dates are the same";
}
//---------------------------------------------------------------------------
This comparison is possible because the inequality
operator "!=" is overloaded in the TDateTime class. Its
syntax is:
bool __fastcall operator !=(const TDateTime& Target) const;
To compare two dates using the overloaded inequality
operator, call the operator==() on the desired date and
supply the argument date value that is being compared against the target.
The above could have been written:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start.operator !=(End) )
pnlComparison->Caption = L"Those are different dates!";
else
pnlComparison->Caption = L"Both dates are the same";
}
//---------------------------------------------------------------------------
The Comparison for Inferiority
|
|
To find out whether a date occurs prior to another
date, apply the "less than" comparison operator. To do this, use the
operator as if both date values were normal integral or floating-point
values. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start < End )
pnlComparison->Caption = DateToStr(Start) + L" occurs prior to " +
DateToStr(End);
else
pnlComparison->Caption = L"I can't make up my mind";
}
//---------------------------------------------------------------------------
Alternatively, you can use the overloaded "less than"
operator to find out when one date is less than another. The syntax used
is:
bool __fastcall operator <(const TDateTime& Target) const;
To perform the above "less than” comparison, you could
implement the event as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start.operator<(End) )
pnlComparison->Caption = DateToStr(Start) + L" occurs prior to " +
DateToStr(End);
else
pnlComparison->Caption = L"I can't make up my mind";
}
//---------------------------------------------------------------------------
The Comparison for Inferiority or Equality
|
|
Two TDateTime values can be compared to find out
whether they are the same or if a source date occurs prior to a target
date. To perform this comparison, apply the "less than or equal” operator
as if the values were regular integer or floating-point numbers. Here is
an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start <= End )
pnlComparison->Caption = L"Your film will be ready after 5 O'Clock";
else
pnlComparison->Caption = L"Wrong date sequence";
}
//---------------------------------------------------------------------------
This comparison operator is useful because the "less
than or equal to" operator "<=" was overloaded in the TDateTime
class. Its syntax is:
bool __fastcall operator <=(const TDateTime& Target) const;
Using the <= overloaded operator, The comparison in
the above event could have been written as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start.operator <=(End) )
pnlComparison->Caption = L"Your film will be ready after 5 O'Clock";
else
pnlComparison->Caption = L"Wrong date sequence";
}
//---------------------------------------------------------------------------
The Comparison for Superiority
|
|
To find out if a source date occurs after a target
date, apply the "greater than" comparison operator. This operator is used
the same way you would for a regular integer or a floating-point values.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start > End )
pnlComparison->Caption = DateToStr(Start) + L" occurs after " +
DateToStr(End);
else
pnlComparison->Caption = L"I can't make up my mind";
}
//---------------------------------------------------------------------------
This "greater than” comparison between two date values
is possible because its operator was overloaded in the TDateTime class.
Its syntax is:
bool __fastcall operator >(const TDateTime& Target) const;
Using the overloaded operator, the previous event
could have been implemented as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start.operator >(End) )
pnlComparison->Caption = DateToStr(Start) + L" occurs after " +
DateToStr(End);
else
pnlComparison->Caption = L"I can't make up my mind";
}
//---------------------------------------------------------------------------
The Comparison for Superiority or Equality
|
|
Two TDateTime values can be compared to find out
whether they are the same or if a source date occurs after a target date.
To perform this comparison, apply the "greater than or equal” operator as
if the values were regular integer or floating-points. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start >= End )
pnlComparison->Caption = L"Testing for ""\"Greater Than Or Equal To""\"";
else
pnlComparison->Caption = L"I can't make up my mind";
}
//---------------------------------------------------------------------------
Using this comparison, you can validate an
intermediary operation. Even after finding out whether the first date is
greater than or equal to the second, you can further refine your
comparison inside of the comparison. In the following example, a message
box displays if the "greater than or equal to” comparison returns false:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start >= End )
{
pnlComparison->Caption = L"Testing for ""\"Greater Than Or Equal To""\"";
if( Start > End )
ShowMessage(DateToStr(Start) + L" occurs after " + DateToStr(End));
else if( Start == End )
ShowMessage(L"Both dates occur at the same time");
}
else
pnlComparison->Caption = L"I can't make up my mind";
}
//---------------------------------------------------------------------------
This comparison operator is accessible because the
"greater than or equal to" operator "<=" was overloaded in the
TDateTime class. Its syntax is:
bool __fastcall operator >=(const TDateTime& Target) const;
To perform the comparison in the above event using the
<= overloaded operator, call the operator>=() method on
the source date value and include the compared date as the Target
argument. The above event could be written as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::pnlComparisonClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
if( Start.operator >=(End) )
{
pnlComparison->Caption = L"Testing for ""\"Greater Than Or Equal To""\"";
if( Start > End )
ShowMessage(DateToStr(Start) + L" occurs after " + DateToStr(End));
else if( Start == End )
ShowMessage(L"Both dates occur at the same time");
}
else
pnlComparison->Caption = L"I can't make up my mind";
}
//---------------------------------------------------------------------------
The TDateTime and other VCL functions allow you to
perform various types of operations on a date value. Almost all types of
operations and all types of comparisons are possible. All arithmetic and
all logic comparison operators were overloaded to permit as much
flexibility as possible. Some of the operations are possible directly on
date values. When not possible or difficult, the decoder and encoder
functions can be used to let the compiler work behind the scenes.
Assigning One Date to Another
|
|
To assign one date to another, simply use the
assignment operator "=" as if the variables were regular values. In the
following example, the user enters a starting date in an Edit control and
finds out the number of days a customer of a car rental wants to keep the
car. The clerk enters this value in the # of Days edit box. When the clerk
clicks somewhere else, that is, when the edit box loses focus, the content
of the edit box is checked. If the number of days is 1 or less, which
means the customer wants the car for only one day, the first date is
assigned to a second TDateTime variable and displays in
the End Date edit box:
//---------------------------------------------------------------------------
void __fastcall TForm1::edtNbrOfDaysExit(TObject *Sender)
{
TDateTime Start, End;
int NbrOfDays;
Start = StrToDate(edtStartDate->Text);
NbrOfDays = StrToInt(edtNbrOfDays->Text);
if(NbrOfDays <= 1)
{
End = Start;
edtEndDate->Text = End;
}
else
{
edtEndDate->Text = L"";
edtEndDate->SetFocus();
}
}
//---------------------------------------------------------------------------
Alternatively, the TDateTime has the
assignment operator overloaded to allow assigning a date variable to
another. The syntaxes of the function are:
TDateTime& __fastcall operator =(const TDateTimeBase& rhs);
TDateTime& __fastcall operator =(const TDateTime& rhs);
TDateTime& __fastcall operator =(const double rhs);
TDateTime& __fastcall operator =(const int rhs);
To assign one date to another using the
operator =() function, use a valid TDateTime value or declare a
TDateTime variable and call the operator=()
overloaded function by supplying the intended target TDateTime
variable. The above event could be rewritten as;
//---------------------------------------------------------------------------
void __fastcall TForm1::edtNbrOfDaysExit(TObject *Sender)
{
TDateTime Start, End;
int NbrOfDays;
Start = StrToDate(edtStartDate->Text);
NbrOfDays = StrToInt(edtNbrOfDays->Text);
if(NbrOfDays <= 1)
{
End.operator =(Start);
edtEndDate->Text = End;
}
else
{
edtEndDate->Text = L"";
edtEndDate->SetFocus();
}
}
//---------------------------------------------------------------------------
To add a number of days to a TDateTime
value, simply add an integer to the intended date value. Here is an
example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnAdditionClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime Addition = Start + 5;
edtAddition->Text = Addition;
}
//---------------------------------------------------------------------------
You can also get the number of days from the user by
using another control on the application. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TfrmExercise::edtNumberOfDaysExit(TObject *Sender)
{
TDateTime StartDate = edtStartDate->Text;
int Days = edtNumberOfDays->Text.ToInt();
TDateTime EndDate = StartDate + Days;
edtEndDate->Text = EndDate;
}
//---------------------------------------------------------------------------
The addition operation is possible on a date value
because its operator is overloaded in the TDateTime class. The TDateTime
class provides a mechanism of adding a number of days to a date value. The
syntaxes of the overloaded operator are:
TDateTime __fastcall operator +(const TDateTimeBase& rhs) const;
TDateTime __fastcall operator +(const TDateTime& rhs) const;
TDateTime __fastcall operator +(const double rhs) const;
TDateTime __fastcall operator +(const int rhs) const;
When applied to a TDateTime value, the addition
operator "+" adds a number of days to a date. If the number added exceeds
the end of year, the class will calculate and encode a date that
corresponds to the date of the subsequent year:
To add a number of months to a date value, decode the
date to retrieve its year, month, and day values. Add the intended number
of months to your date and re-encode the date. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnAdditionClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtDate->Text);
int Months = StrToInt(edtValue->Text);
unsigned short Year, Month, Day;
Start.DecodeDate(&Year, &Month, &Day);
TDateTime End(Year, Month+Months, Day);
edtResult->Text = DateToStr(End);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnExitClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
To add a number of years to a date value, decode it to
extract the year, month, and day values. Add the integral number of years
to the source year. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnAdditionClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtDate->Text);
int Years = StrToInt(edtValue->Text);
unsigned short Year, Month, Day;
Start.DecodeDate(&Year, &Month, &Day);
TDateTime End(Year+Years, Month, Day);
edtResult->Text = DateToStr(End);
}
//---------------------------------------------------------------------------
You can add a value to a date variable and assign the
new value to the original date. This is the same as using the += operator.
The syntaxes used for this operator are:
TDateTime& __fastcall operator +=(const TDateTimeBase& rhs);
TDateTime& __fastcall operator +=(const TDateTime& rhs);
TDateTime& __fastcall operator +=(const double rhs);
TDateTime& __fastcall operator +=(const int rhs);
To add a number of days to an existing date value, you
can use the += operator as follows:
//---------------------------------------------------------------------------
void __fastcall TfrmExercise::btnIncreaseClick(TObject *Sender)
{
static TDateTime StartDate = StrToDate(edtDate->Text);
StartDate += 1;
edtResult->Text = DateToStr(StartDate);
}
//---------------------------------------------------------------------------
To get the number of days between two dates, perform
the subtraction operation on their values. To do this, you can declare a
double precision number or an integer that would store the subtracted
number from the later date to the earlier. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDifferenceClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
int Diff = End - Start;
edtDifference->Text = Diff;
}
//---------------------------------------------------------------------------
To get the difference of years between two dates,
apply the subtraction operator on their values to get the integral number
of days. Then divide this number by 365. This difference produces the
number of years in ranges of 365 days. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDifferenceClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
int Years = End - Start;
edtYears->Text = (Years / 365);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnCloseClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
As an alternative, you can decode both dates and
subtract their year values; this would produce the difference of years
with regards to the years, not the real dates. For example, the difference
between 12/31/2001 and 01/01/2002 would produce a year. Here is an
example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDifferenceClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
unsigned short StartYear, StartMonth, StartDay, EndYear, EndMonth, EndDay;
Start.DecodeDate(&StartYear, &StartMonth, &StartDay);
End.DecodeDate(&EndYear, &EndMonth, &EndDay);
int Years = EndYear - StartYear;
edtYears->Text = Years;
}
//---------------------------------------------------------------------------
To get the difference of months between two dates,
perform the subtraction operator on their values to get the number of days
elapsed and divide the result by 30. This would produce a number of
months. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDifferenceClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
int Months = End - Start;
edtYears->Text = Months / 30;
}
//---------------------------------------------------------------------------
The subtraction operation is possible on TDateTime
values because the subtraction operator "-" is overloaded in the TDateTime
class as follows:
TDateTime __fastcall operator -(const TDateTimeBase& rhs) const;
TDateTime __fastcall operator -(const TDateTime& rhs) const;
TDateTime __fastcall operator -(const double rhs) const;
TDateTime __fastcall operator -(const int rhs) const;
The subtraction operator "-" is overloaded in the
TDateTime class to allow getting the difference of days, that is, the
elapsed number of days between two dates. The subtraction is performed as
Date2 – Date1. In this case, if Date2 occurs after Date1, the result would
be a positive number; otherwise a negative value would indicate that Date2
occurs before Date1.
You can also use the operator int() overloaded
function to get the difference of days between two dates. To do this,
declare an integer that stores the subtracted number between two TDateTime
dates. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDifferenceClick(TObject *Sender)
{
TDateTime Start = StrToDate(edtStart->Text);
TDateTime End = StrToDate(edtEnd->Text);
TDateTime Diff = End - Start;
int Days = Diff.operator int();
edtDifference->Text = Days;
}
//---------------------------------------------------------------------------
Assigning a Subtracted Date
|
|
The -= operator is used to subtract a number of days
from a date and assign the new value to the date (whose value has been
subtracted). This operation is performed using the overloaded -= operator
that uses the following syntaxes:
TDateTime& __fastcall operator -=(const TDateTimeBase& rhs);
TDateTime& __fastcall operator -=(const TDateTime& rhs);
TDateTime& __fastcall operator -=(const double rhs);
TDateTime& __fastcall operator -=(const int rhs);
To subtract a number of days from a date, you can use
the subtraction operator. To assign the subtracted value to the original
date, use the -= operator. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDisplayClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
int IntValue = StrToInt(edtSubtract->Text);
DateValue -= IntValue;
edtResult->Text = DateToStr(DateValue);
}
//---------------------------------------------------------------------------
To decrement a date value, declare a TDateTime
variable and apply the – operator on its value. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
static TDateTime Start = StrToDate(edtStartDate->Text);
edtStartDate->Text = Start--;
}
//---------------------------------------------------------------------------
The TDateTime class allows subtracting one day from a
TDateTime value. This is done using the overloaded decrement operator
whose syntaxes are:
TDateTime& operator --();
TDateTime operator --(int);
To decrement a date value using the -- overloaded
operator, you have two options. To use the pre-decrement operator, as if
you were using "--Value”, call the operator--() function. This would apply
the operator before recalling the variable. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
static TDateTime Start = StrToDate(edtStartDate->Text);
edtStartDate->Text = Start.operator--();
}
//---------------------------------------------------------------------------
To use the post-increment operator, which is the same
as "Value--", in which case the statement is called before being
incremented, use the operator--(int) method. The int argument is not
specific but you must supply it. Therefore, type any integer number
between the parentheses. Remember that the argument supplied is not the
decrementing value; it is only a "witness” but it is necessary. Here is an
example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
static TDateTime Start = StrToDate(edtStartDate->Text);
edtStartDate->Text = Start.operator--(2);
}
//---------------------------------------------------------------------------
To increment a date value, declare a TDateTime
variable and use the ++ operator on its value. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnIncrementClick(TObject *Sender)
{
static TDateTime Original = StrToDate(edtDate->Text);
edtIncremented->Text = Original++;
}
//---------------------------------------------------------------------------
The TDateTime class allows you to add one day to a
TDateTime value. This is done using the overloaded increment operator with
the following syntaxes:
TDateTime& operator++();
TDateTime operator++(int);
To apply the pre-increment operator, as if you were
using "++Value”, call the operator++() function. This would apply the
operator before recalling the variable. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnIncrementClick(TObject *Sender)
{
static TDateTime Original = StrToDate(edtDate->Text);
edtIncremented->Text = Original.operator++();
}
//---------------------------------------------------------------------------
To use the post-increment operator, which is the same
as "Value++", in which case the statement is called before being
incremented, use the operator++(int). The int argument is not
specific but you must supply it. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnIncrementClick(TObject *Sender)
{
static TDateTime Original = StrToDate(edtDate->Text);
edtIncremented->Text = Original.operator++(12);
}
//---------------------------------------------------------------------------
This was the opening dialog box: This was performed
after the first click:
Formatting and Controlling the Display of
Dates
|
|
The TDateTime class and the VCL
provide special functions that can be used to control how the date values
display in your application. Calling one of these functions, a date can
use almost any format you see fit or any that makes your application
user-friendly.
To control how a date value displays, the TDateTime
class uses the FormatString() method. Its syntax is:
UnicodeString __fastcall FormatString(const UnicodeString& format);
The TDateTime::FormatString() method
takes a string argument that specifies what format to apply. After
formatting the date value, the method returns a UnicodeString string.
Alternatively, the VCL has its own function that
performs the same operation. Its syntax is:
UnicodeString __fastcall FormatDateTime(const UnicodeString Format,
System::TDateTime DateValue);
The FormatDateTime() function takes two arguments. The
Format argument is a string that specifies how the date should be
formatted. Since this function is not part of the TDateTime class, it
needs a valid TDateTime date value to work on; that is the role of the
DateValue argument.
The default format used by both the TDateTime::FormatString() and the
FormatDateTime() functions conforms to the ShortDateFormat of the Windows
Control Panel. For these functions, that format is represented by the "c”
string. You can still use it explicitly. For the TDateTime::FormatString()
method, an example would be:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime DateValue(L"10/22/2001");
Edit1->Text = DateValue.FormatString(L"c");
}
//---------------------------------------------------------------------------
A similar example applied on the FormatDateTime() function would be:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime DateValue(L"10/22/2001");
Edit1->Text = FormatDateTime(L"c", DateValue);
}
//---------------------------------------------------------------------------
Displaying the Numeric Day
|
|
The days of months are numbered from 1 to 31,
depending on the month. The formatting functions represent each of these
days with the "d” format. Here is an example used for the
TDateTime::FormatString() method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatStringClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"d");
}
//---------------------------------------------------------------------------
This would produce:
The implementation of this format using the
FormatDateTime() function is:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatDateTimeClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatDateTime->Text = FormatDateTime(L"d", DateValue);
}
//---------------------------------------------------------------------------
When the day has a numeric value that is less than 10,
the default "c” and the "d” formats display its value without the leading
0. To display the leading 0 as in 02 or 08, use the "dd” format. Here is
an example implemented using the TDateTime::FormatString() method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"dd");
}
//---------------------------------------------------------------------------
Using the FormatDateTime() function, you could
have written the same event as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = FormatDateTime(L"dd", DateValue);
}
//---------------------------------------------------------------------------
The names of the week use two formats: 3 letters or
full name. To display a name with 3 letters, use the "ddd” format. The
names will be Sun, Mon, Tue, Wed, Thu, Fri, or Sat. Here is an example
using the TDateTime::FormatString() method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"ddd");
}
//---------------------------------------------------------------------------
The same event using the FormatDateTime()
function would be written as:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = FormatDateTime(L"ddd", DateValue);
}
//---------------------------------------------------------------------------
To display the weekday and the numeric day of the
month, you can create a format that combines both strings. When creating
this string, the format must be separated inside the string so the
compiler would know which format to apply and where. To separate the
formats, you can use (almost) any character but you should conform to
those used in your regional settings. One of the most regularly used
separators on dates is the comma but the simplest separator is an empty
space. Here is an example (using the TDateTime::FormatString()
method):
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"ddd dd");
}
//---------------------------------------------------------------------------
To display the complete name of a weekday, use the
"dddd” format string. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"dddd");
}
//---------------------------------------------------------------------------
You can also display the weekday followed by the
numeric day of the month. Here is an example that uses the
FormatDateTime() function:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = FormatDateTime(L"dddd dd", DateValue);
}
//---------------------------------------------------------------------------
Displaying Numeric Months
|
|
Months are displayed using two categories: a number or
a name.
To display the numeric range of a month, use the "m”
format. The months are numbered as follows: 1=January, 2=February,
3=March, 4=April, 5=May, 6=June, 7=July, 8=August, 9=September,
10=October, 11=November, and 12=December. Here is an example that displays
the numeric month of a date, using the TDateTime::FormatString()
method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"m");
}
//---------------------------------------------------------------------------
Following the rules we applied to display a
combination of a weekday and a month’s numeric day, you can display a
month and the month’s numeric value. This time, instead of an empty space,
you should use a character that would indicate that the date is displaying
a combination of month and day (or day and month). The best character to
use is the one that conforms to the regional settings of your computer. In
the United States’ English, this would be the forward slash "/”. Here is
an example that uses the FormatDateTime() function:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = FormatDateTime(L"m/dd", DateValue);
}
//---------------------------------------------------------------------------
In the same way you can combine a weekday short name
followed by the combination of day/month (or month/day) as you see fit.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = FormatDateTime(L"ddd m/dd", DateValue);
}
//---------------------------------------------------------------------------
When using the "m” format, if the number of the month
is less than 10, the compiler would display it as 1, 2, 3, 4, 5, 6, 7, 8
or 9, without the leading 0. If you want to display the leading zero for a
month between 1 and 9, as 01 or 07, use the "mm” format. Here is an
example with the TDateTime::FormatString() method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"mm");
}
//---------------------------------------------------------------------------
You can also use this format when constructing a
combined date:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"dddd, mm/dd");
}
//---------------------------------------------------------------------------
Displaying the Name of a Month
|
|
You can display a month by its name using one of two
formats: short or long name. The short names of months are: Jan, Feb, Mar,
Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, and Dec. To display a month with
one of these names, use the "mmm” format. The following example uses the
TDateTime::FormatString() method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"mmm");
}
//---------------------------------------------------------------------------
This time, the name of the month would become more
explicit in a combined format. To create such a combined date, apply the
rules we have reviewed so far. The following TDateTime::FormatString()
implementation displays a date as short weekday-day-short month name
combination:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"ddd dd mmm");
}
//---------------------------------------------------------------------------
You can also use a comma and space to separate the
name of the weekday from the other components. The following event uses
the FormatDateTime() function:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = FormatDateTime(L"dddd, dd mmm", DateValue);
}
//---------------------------------------------------------------------------
To display a complete name of a month, use the "mmmm”
format. The name would display as one of the following: January, February,
March, April, May, June, July, August, September, October, November, and
December; confirming to the Regional Settings of your computer. Here is an
example that uses the TDateTime::FormatString() method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
UnicodeString Formatter = L"ddd, d mmmm";
edtFormatString->Text = DateValue.FormatString(Formatter);
}
//---------------------------------------------------------------------------
Another implementation that uses the
FormatDateTime() function can display the weekday-day-month
combination with an empty space as the separator:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
UnicodeString Formatter = L"dddd, dd mmmm";
edtFormatString->Text = FormatDateTime(Formatter, DateValue);
}
//---------------------------------------------------------------------------
A year value can be displayed using 2 or 4 digits. To
display a year value as a number between 00 and 99, use the "y” or the
"yy” formats as follows (this event uses the TDateTime::FormatString()
method):
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"y");
}
//---------------------------------------------------------------------------
To make the displays we have used so far a little more
explicit, you can include the year value in a combined date string, as
follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"ddd dd mmm yy");
}
//---------------------------------------------------------------------------
Therefore, you can apply any combination of the
formats we have used so far to display a date, as illustrated in the
following FormatDateTime() function call:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
UnicodeString Formatter = L"dddd dd mmmm yy";
edtFormatString->Text = FormatDateTime(Formatter, DateValue);
}
//---------------------------------------------------------------------------
A year value represented with two digits is hardly
explicit, unless you have a good reason for using it. The alternative is
to use all four digits to display a year. This format is created with the
"yyy” or the "yyyy” strings. Here is an example with the
TDateTime::FormatString() method:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
edtFormatString->Text = DateValue.FormatString(L"yyy");
}
//---------------------------------------------------------------------------
Since this format would be the only one with four
digits in a combined string, it makes a date easier to read. Once again,
you can apply the rules we have used so far, to create and display a
combined date. The default format used by Microsoft Windows for the
English language is as Sunday, January 27, 2002. You can use the
TDateTime::FormatString() method to create such a format as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
UnicodeString Formatter = L"dddd, mmmm dd, yyyy";
edtFormatString->Text = DateValue.FormatString(Formatter);
}
//---------------------------------------------------------------------------
Using these rules, you can display a date as you wish.
The following FormatDateTime() function displays a date differently
than the event above:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnFormatClick(TObject *Sender)
{
TDateTime DateValue = StrToDate(edtDate->Text);
UnicodeString Formatter = L"dddd d mmmm yyyy";
edtFormatString->Text = FormatDateTime(Formatter, DateValue);
}
//---------------------------------------------------------------------------
The time is a unit that measures the number of
sequences from a fixed starting point between two days to the equivalent
fixed point between the following two days. The starting point called
Midnight and is positioned at night. A day is made of 24 non-spatial
divisions; each one of these divisions is called an hour. An hour is made
of 60 fractions and each one these fractions is called a minute. A minute
is divided in 60; each one of those parts is called a second.
As done with dates, most of the operations performed
on time values are centered around the TDateTime class. This class is
based on a double-precision number initialized at 0.00. The constant 0.00
corresponds to 12/30/1899 at midnight. A double-precision number is made
of two sections: an integer part and a decimal side. The integral part is
a natural number with no decimal value, such as 8, 1450, or 32. For the
TDateTime class, the integral section represents the number of days that
have elapsed since 12/30/1899.
On a double-precision number, such as 204.58, the
decimal part starts with a period ".” and is made of all digits on the
right side of the period. For the TDateTime class, the decimal part
represents the number of seconds that have elapsed since midnight on the
day considered.
By default, the compiler refers to the Regional
Settings of your computer to display the time, separating it in hour,
minute, second, and AM/PM. The default symbol to separate the hour and the
minute, or the minute and the second is ":”. To separate the seconds and
the AM/PM, the compiler leaves a one-character empty space between them.
The time portion of a TDateTime object can be declared
and manipulated as a value. To declare time variables, you will use one of
the constructors of the TDateTime class. If you declare a variable using
the default constructor, as TDateTime TimeValue, the time will be
initialized to midnight or 12:00:00 AM.
The time in regular value is a floating number that
ranges from 0 included to 1 excluded. More precisely, the time is a value
defined as follows:
0 >= Time >= 0.99999
The 0 constant represents midnight while the 0.99999
double-precision number represents 12:59:59 PM. In between, 0.50
represents 12:00:00 PM (noon time), 0.325 represents 7:48:00 AM, and 0.738
represents 5:42:43 PM.
To declare a time variable, use the TDateTime class
and specify the name for the variable. Here is an example:
TDateTime Mine;
If not assigned a value, this variable is initialized
at midnight or 12:00:00 AM. You can display its value in an Edit control
as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeValue;
Edit1->Text = TimeValue;
}
//---------------------------------------------------------------------------
You can initialize a time value with a
double-precision number between 0.00000 and 0.99999. Here is an example:
TDateTime Value = 0.2185;
Such an initialization is the same as:
TDateTime Value(0.2185);
You can also get the value from an intermediary action
or request it from the user. This allows you, if necessary, to convert any
floating-point number to a time value, as follows:
You can also use an independent floating-point number
to initialize a time variable. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnTimeClick(TObject *Sender)
{
double Number = edtNumber->Text.ToDouble();
TDateTime TimeValue = Number;
edtTime->Text = TimeValue;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnCloseClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
Still using the default constructor, if you know the
time you want to initialize a variable with, you can provide it. To do
that, declare an instance of the TDateTime constructor and type the time
value between the double-quotes of the parentheses. If the time is known
only for the hour(s) and the minute(s), you can initialize it as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeValue(L"08:22");
Label3->Caption = TimeValue;
}
//---------------------------------------------------------------------------
When using this formula, the hour value must be
between 0 and 23. Any other value outside of this range will cause an
error. The minute value must range from 0 to 59; otherwise, an error would
be thrown. If the hour portion has a value between 0 and 11:59, the time
is set in the morning with the AM in the AM/PM section. If the hour
portion is between 12 and 23, the time is set in the afternoon. When
displaying it, the compiler, by default, calculates and displays the 0 to
12 portion and then displays PM in the AM/PM section.
You can also initialize a time value using the
Hour:Minute:Second formula as a string. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeValue(L"20:22:52");
Label3->Caption = TimeValue;
}
//---------------------------------------------------------------------------
Once again, in the absence of an AM/PM section, the
compiler would consider the hour portion to evaluate whether the time
occurs in the morning or in the afternoon. The value of the seconds must
be between 0 and 59; otherwise, an error will be thrown.
You can also initialize a time value by specifying the
AM/PM portion as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeValue(L"10:22:52 AM");
Label3->Caption = TimeValue;
}
//---------------------------------------------------------------------------
The AM and the PM can be in uppercase or lowercase. In
otherwords the AM/PM portion can be represented as AM, Am, aM, am, PM, Pm,
pM, or pm. Only the characters A and P (uppercase or lowercase) are
accepted as the first character. Only the M or m characters are accepted
as the second character. Any other combination or other character will
cause an error.
If you know the values of the hour, the minute, the
second, and the millisecond, you can use them to initialize a time
variable. To do this, you must supply the arguments in order following the
constructor:
__fastcall TDateTime(unsigned short Hour, unsigned short Minute,
unsigned short Second, unsigned short Millisecond);
The hour value must be between 0 and 23. The minutes
must be between 0 and 59. The Second argument must have a value between 0
and 59. Whenever the seconds are not important to represent the time,
provide their value as 0. The milliseconds must range from 0 to 999. If
you do not know the millisecond value, provide it as 0. Here is an
example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeValue(8, 20, 42, 605);
ShowMessage(L"The time considered is " + TimeValue);
}
//---------------------------------------------------------------------------
Since a double-precision number has a decimal section
that represents the time of the day, you can assign such a value to a
TDateTime variable to initialize a time value. If the integral part of the
value is greater than 0, it would represent the number of days. If it is
0, only the time would be recognized as a fraction of the day.
To get or display the time on your application, you
can use the Time() function. You can display it on:
- An edit box: edtTime->Text = Time();
- A label: lblCurrent->Caption = "Now is the time: " + Time();
- A panel: pnlTime->Caption = "At this time, we have " + Time();
Converting a String to Time
|
|
To convert a string to a time value, use the
StrToTime() function whose syntax is:
TDateTime __fastcall StrToTime(const UnicodeString S);
This function takes a string as argument. The string
must be in a in a valid time format, following the Regional Settings of
the Control Panel. For example, in the United States, the components of a
time are separated with a colon ":”. The typical formats of a time are:
If the string contains an invalid date, the conversion
would fail and the program would throw an error. If the conversion is
successful, the function returns a valid time. Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm2::btnConvertClick(TObject *Sender)
{
TDateTime Value = StrToTime(edtSource->Text);
edtTarget->Text = Value;
}
//---------------------------------------------------------------------------
Converting a Time Value to a String
|
|
A time value is, default, recognized and treated as a
string whenever necessary. This flexibility allows you to perform
transparent conversions from a time to a string values. Therefore, it is
perfectly legitimate to write the following assignment:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeValue(L"22:32:58");
UnicodeString Right = TimeValue;
Edit1->Text = Right;
}
//---------------------------------------------------------------------------
This conversion is possible because the UnicodeString
constructor is overloaded in the TDateTime class. Its syntax is:
__fastcall operator UnicodeString() const;
Therefore, to convert a time value to a string, you
can simply assign the time to a string variable. You can also explicitly
call the overloaded UnicodeString() function as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime StartTime(L"9:05:00 AM");
UnicodeString ToDisplay = StartTime.operator UnicodeString();
Edit1->Text = ToDisplay;
}
//---------------------------------------------------------------------------
The TDateTime class is also equipped with a method
that can be used to convert a time value to a string when necessary. The
syntax used is:
UnicodeString __fastcall TimeString() const;
To convert a time value to a string, declare a
TDateTime variable and call the TimeString() method. Here is an
example:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeValue(L"22:32:58");
UnicodeString ToDisplay = TimeValue.TimeString();
Edit1->Text = ToDisplay;
}
//---------------------------------------------------------------------------
Alternatively, to convert a time value to a string,
you can use the TimeToStr() function. Its syntax is:
UnicodeString __fastcall TimeToStr(System::TDateTime Date);
This function takes one argument, which is the time
value that needs to be converted. If the argument is not a valid time
value, the conversion would fail and the program would throw an error. If
the conversion is successful, the function returns a UnicodeString value.
Here is an example:
//---------------------------------------------------------------------------
void __fastcall TForm1::btnConvertClick(TObject *Sender)
{
UnicodeString Current = TimeToStr(Time());
edtTarget->Text = Current;
}
//---------------------------------------------------------------------------
Converting a Time Value to a Double-Precision
Number
|
|
A TDateTime time value is a number that represents a
fraction of the day on a 24-hour basis. This is quite helpful in algebraic
operations.
To convert a time value to a double-precision number,
simply cast the time value to a double. In the following example,
the current time is converted to double and displayed in an edit
box when the user clicks a button on a form:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeX = Time();
double Value = double(TimeX);
Edit1->Text = Value;
}
//---------------------------------------------------------------------------
The conversion of a time value to a double-precision
number is possible because the double data type was overloaded in the
TDateTime to allow this conversion. The syntax of the function used is:
__fastcall operator double() const;
You can use this function transparently as done in the
previous example. You can also call it explicitly call it as follows:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime TimeX(L"09:42:18 AM");
double Value = TimeX.operator double();
Edit1->Text = Value;
}
//---------------------------------------------------------------------------