TDateTimePicker and Date - delphi

It's a simple question for a weird thing of DatetTimePicker from Delphi XE7.
I have this code...
procedure TForm1.Button1Click(Sender: TObject);
begin
DateTimePicker1.Date:= Date;
memo1.Lines.Add(FloatToStr(Date) + ' vs ' + FloatToStr(DateTimePicker1.Date));
end;
Today, 18 of March 2015, after I press the button the results I get is:
42081 vs 42081.846316956
If I press again after 5 minutes I get the same result.
Why the values are not the same?

The Date() function truncates the decimal portion of the return value (sets the time portion to 0). So it returns the current date/time with only the date filled in.
The TDateTimePicker.Date property setter only updates the date portion of the internal stored TDateTime, leaving the existing time intact. The TDateTimePicker.Date property getter returns the entire internal stored date/time, not the date by itself, as one would expect. So you are seeing the updated date + the original time as initialized by TDateTimePicker.

The TDateTimePicker.Date and TDateTimePicker.Time property getters return both a full date/time value, despite their names. The property setters, on the other hand, update only the date and time portions, respectively, as expected.
The Date() function returns a TDateTime that just contains a date portion, no time portion.
To retrieve just the date portion by itself, you can use the DateOf() function from the DateUtils unit to strip off the time portion of the value returned by the TDateTimePicker.Date or TDateTimePicker.DateTime properties:
DateOf(DateTimePicker1.Date)

Set Datepicker1.Time to 0 and you'll get the same results.
It's the fraction of the daytime passed you see in the decimals.

Related

how compare datetime from firebird db to current date in Delphi

In firebird 3.0 db in Timestamp type field saved data. How compare this data to current date?
if (Query1data1.AsDateTime <>date()) then ...
If you want to ignore the time of day, may use CompareDate.
Indicates the relationship between the date portions of two TDateTime values.
Call CompareDate to compare the two TDateTime values specified by A
and B. CompareDate returns:
LessThanValue if A occurs on a day prior to the day specified by B.
EqualsValue if A occurs on the same day as B, ignoring the time of
day. GreaterThanValue if A occurs on a day that follows the day
specified by B.
For example :
case CompareDate(Query1data1.FieldByName('TIMESTAMP_FIELD').AsDateTime,Date()) of
-1 : ShowMessage('is less');
0 : ShowMessage('equals');
1 : ShowMessage('is greater')
end;
Also you may use: DateOf
Strips the time portion from a TDateTime value.
Call DateOf to convert a TDateTime value to a TDateTime value that
includes only the date information (sets the time portion to 0, which
means midnight).
if DateOf(Query1data1.FieldByName('FTIMESTAMP').AsDateTime) = Date() then
....

ECommonCalendarError: Failed to set calendar date or time

I started a new Delphi application, I dropped a TDateTimePicker on the main form, and I added this code:
procedure TForm1.FormShow(Sender: TObject);
begin
DateTimePicker1.MaxDate:= Now - 9;
DateTimePicker1.Date:= Now - 10;
end;
When I run the program and trying to change the date using UP ARROW from the keyboard, I get this error message. But if I change the date with the MOUSE to the last possible date, I don't receive the error message. And after that I can change the date with the arrow key too.
I do not understand what is wrong and how to correct this problem.
Update:
I found another situation when that error occurs: When I drop down the list and close it again, without selecting anything, but with these settings:
procedure TForm1.FormShow(Sender: TObject);
var D:TDate;
begin
D:= Date;
DateTimePicker1.Date:= D;
DateTimePicker1.MaxDate:= D;
end;
There is a bug in Delphi 2009 VCL. The problem is that setter for the MaxDate property did not add time portion of 23:59:59 to the maximum range limit. Then, when one left the Time property on time different from 00:00:00 and set only the Date property the DateTime_SetSystemTime macro failed because of a date time overflow of the date time range (which led to that exception).
To avoid this you can reset the Time property to 00:00:00, or assign date only (keeping time portion zeroed) to the DateTime property.

TDateTimePicker MaxDate - does not allow setting control to current date

I have set standard VCL TDateTimePicker - MaxDate property to Date - e.g.
DTPicker.MaxDate := Date;
However, there is a problem. If I now set the date to be the current one:
DTPicker.Date := Date;
It will not accept it. The control simply stays at the date which is set at the design time. I can solve it by setting MaxDate to be Date + 1 and then setting the Date property works fine and shows today's date, but then user is able to select tomorrow's date. I also tried to set MaxDate to Date + 0.99999999 but that also is of no help.
I use Delphi 2010 and C++Builder 2010 (if this is a bug in either of them).
Any ideas how to prevent selecting any date beyond today and set the control date to today's date?
Changing the date results in - "Failed to set calendar date or time."
Update:
I managed to make it work as following:
open drop-down in TDateTimePicker (during runtime) and intentionally select Today's date (click on already selected Today's date)
after that select any past date
click button which has the code to reset the date and then it works.
My solution will likely be to use range-check before closing the form, as it seems that MaxDate is useless, at least with this version of Delphi.
It appears it's the time portion of Date that's causing the problem. This works fine on D2007, XE, XE8, and Delphi 10 Seattle:
DateTimePicker1.MaxDate := Trunc(Date) + 0.99999999999;
DateTimePicker1.Date := Date;
Tested using a brand new VCL forms application. Drop a TDateTimePicker and a TButton on the form, and generate an event for the FormCreate for the form:
procedure TForm1.FormCreate(Sender: TObject);
begin
DateTimePicker1.MaxDate := Trunc(Date) + 0.99999999999;
end;
and the button:
procedure TForm1.Button1Click(Sender: TObject);
begin
DateTimePicker1.Date := Date;
end;
Run the app, click the DateTimePicker combobox to display the calendar, and pick any date that's available. The DateTimePicker displays the selected date. Click the button, and the DateTimePicker updates to show today's date. Dropping down the calendar again shows the correct dates available.
Of course, as Remy Lebeau pointed out in a comment: in an actual application, you wouldn't want to hard-code the time portion. A better solution would be to use DateUtils.EndOfDay(Date) or Trunc(Date) + EncodeTime(23, 59, 59, 999).
There is no big difference between adding 1 and 0.99999, as 1 you would increment one day to the date, and 0.999999 it would be almost one day (something like 23:59:59:xxx).
Try the following (you have to include DateUtils in the uses list):
DTPicker.MaxDate := IncSecond(Date);

ISO 8601 string date picker (Delphi, DevExpress)

Our Delphi application uses database-bound TcxGridDBColumns to let the user manipulate a ISO 8601-formatted date (YYYY-MM-DD) as a string. I would like to offer the end user a calender-based date picker.
TcxDateEditProperties can't be used (directly) since the underlying database uses a string field. So to my understanding I'm left with the options to
Create an additional date column (TDateTime DB field) in all tables and convert the date to the ISO 8601 string column on the BeforePost event of TDataSet
Create a custom Tcx***Properties class. This would likely involve inheriting from TcxPopupEditProperties.
Since there are many tables affected, I would much rather use #2. Can you point to help documents helping me with that? Or is there a #3?
if what you mean by documents is about writing custom component, then you can see here Creating Custom Delphi Components, as well as the document 'Component Writer's Guide' pdf that comes with Delphi (it has example about customizing DBGrid and navigating months, year and days too). This can be used for starting point for option no.2
There is a #3: No extra column needed, DateEdit understands strings in both current system format (in which a user change is written back) and ISO format. In the BeforePost I convert the system format back to the ISO which I need in the database. As an extra luxury, the following event changes the existing ISO dates to what the user's default date format:
procedure T_RVVorbereitung.cxGridAnalysisDateGetDataText(
Sender: TcxCustomGridTableItem; ARecordIndex: Integer; var AText: string);
var
ADate : TDateTime;
begin
try
try
ADate := TIso8601.DateTimeFromIso8601(AText); // YYYY-MM-DD
except
ADate := StrToDate(AText);
end;
AText := DateToStr(ADate);
except
// neither system nor ISO date: show as it is
end;
end;

Parsing to a total DateTime object in Rails

I'm currently given three values in a table
A date value in the format of %dd-%mname-%yy (i.e 06-may-05), and am parsing that using Date.parse(input,true) to fix the issue with the leading values.
I'm then given a time value in the form of %hh:%mm:%ss.%ms (the ms of which I can take or leave) and a third value of a GMT offset.
I can't really see anyway to convert these three values into a single DateTime object that would allow me to manipulate it using the range of ruby tools without first parsing the second value to time, somehow changing the offset ((given as a + or - n value) as in +2 or -6)to a signed int and then applying it and then parsing this all to a super dateTime object.
There's got to be a better way. Is there?
Chronic may be able to parse this (if you concatenate everything in one string, maybe with some modifications) but I haven't checked.
Okay in order to create a dateTime value with the time and the date given and to take into account an offset you need the following code
d = DateTime.parse(dateVal+" "+TimeVal)
offset = Rational(offset_val,24)
d = d.new_offset(offset)
So take your date, given to you as say 05 May 2010 and a timeval in the form hh:mm:ss
With an offset of +- any value, for this instance say -8
Then this code will generate you a new date object, offset to the amount you require

Resources