Extracting Utime on Fast Report 2.5 - delphi

I wanted to extract Utime 2 types. One for AM ouput second for PM output.I learned how to create my own object but I couldn't extract from the [Utime] object.Could I use FRAC() here?To get the AM part.
here is my current ouput.
My current fast report code.
How could I extract from this object?

Yes, you may use Frac function. Delphi's TDateTime type is double, so Frac function will return time part of TDateTime as double value
begin
if frac([Utime]) < 0.5 then AmTime := [Utime] else PmTime := [Utime];
end

Related

How do I extract just the time from a datetimepicker component in Delphi?

I have a datetimepicker component in a Delphi form and I would like to just get the Time. When i look at the date in debug mode I see 42544.621701, and I would like just to get 0.621701 without the date value.
You can use the Frac() function:
var
Time: TTime;
...
Time := Frac(DateTimePicker1.DateTime);
Or, you can use the System.DateUtils.TimeOf() function, which is merely an inlined wrapper around Frac() with a more descriptive name:
uses
..., DateUtils;
var
Time: TTime;
...
Time := TimeOf(DateTimePicker1.DateTime);
The question is not actually about a date time picker. The control returns you a date time value. You are looking for a way to extract just the time portion. Do that with the TimeOf function from the System.DateUtils unit.
MyTime := TimeOf(MyDateTime);
EditHoo.Text:=timetostr(DateTimePicker2.Time);

StrToDateDef not working

I want to convert the system date time to a specific format. My system format is dd/mm/yy which i wanted to convert to mm/dd/yyyy and so i am using StrToDateDef. I need to use StrToDateDef only because the date comes as string and if there is a string other than date i will use default date. My code is below
str := '30/01/14';
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FmtStngs);
FmtStngs.DateSeparator := '/';
FmtStngs.ShortDateFormat := 'mm/dd/yyyy';
FmtStngs.TimeSeparator := ':';
FmtStngs.LongTimeFormat := 'hh:nn';
date := StrToDateDef(str,01/28/2013,FmtStngs);
I am expecting the date to be of '01/30/2014' but it is coming as '30/01/14'. What is that i am doing wrong?
There are several bugs in this code:
First the TFormatSettings you are passing to the StrToDateDef routine are the format settings for the string you are passing (and not for the datetime variable that comes out, more on that later).
As you are passing '30/01/14' your ShortDateFormat should be 'dd/mm/yyyy' and not 'mm/dd/yyyy'
Then the default value you are passing equals to like 1ms after midnight of 30.12.1899 (because you actually are passing 1 divided by 28 divided by 2014). Use EncodeDate(2013, 1, 28) from DateUtils.pas.
Then you are saying
I am expecting the date to be of '01/30/2014' but it is coming as '30/01/14'.
Well you are looking at a TDateTime variable and it will be formatted according to your local settings of your windows system by the debugger. Nothing more. You don't have a string but a float value (which is what TDateTime is) that is presented as string to you to make it readable.
Also I think the result should be the passed default date because the passed ShortDateFormat does not match the value of the string you are passing (trying to put 30 into the month part).

Delphi: How to determine and empty TDatetime value

Seems there is no way to assign NULL (either an "unassigned value" to TDateTime variables.
The only way I've imagined is using something like this:
function isNull(aDate : TDateTime) : boolean;
const NullDate = 0.0;
var aNullDate : TDatetime;
ms : Int64;
begin
aNullDate := NullDate;
ms := MilliSecondsBetween(aDate,aNullDate);
result := (ms = Int64(0));
end;
Is there anybody out who knows better solution what not overlaps 0 date value?
Are negative TDateTime values dangerous? (As an able resource for previous purpose)
As Andreas already wrote, the TDateTime type is actually double and thus not "nullable". I use
const
c_UnassignedDate = -693594;
for a empty date value as this represents an impossible date of 00/00/0000. But for example DevExpress uses
NullDate = -700000;
InvalidDate = NullDate + 1;
So there seems to be no agreed upon standard vale, you should pick one which suits your need.
First you need to define what you mean by 'an empty TDateTime value'.
A TDateTime value is a double with the date encoded in the integer part and the time encoded in the fractional part. So, the closest thing to a 'null date' you can get is probably 0.
Hence, simply test ADate <> 0 to test if the date is 'null'.
But beware: if you declare a TDateTime local variable then it will not necessarily be =0 before you give it a value. It can be anything. Of course, the same thing applies to variables of type integer, double, boolean, ...
Also, I believe that a TDateTime with value 0 encodes the date 1899-12-30.
Finally, negative TDateTime values are perfectly normal. For instance, -5000 corresponds to 1886-04-22.
I don't quite get the point of your code. If you want to use 0 as the 'unassigned' value (which is bad if you are interested in dates close to 1899-12-30), why not do simply
function IsUnassigned(ADate: TDateTime): boolean;
begin
result := ADate = 0;
end;
or, possibly (but not equivalently!),
function IsUnassigned(ADate: TDateTime): boolean;
begin
result := IsZero(Date);
end;
In his answer, ain gave a couple of more reasonable choices for the 'unassigned date' value.
At unit Spring.Persistence.Core.Session.pas of library Spring Framework for Delphi (http://www.spring4d.org) in method TSession.ExecuteScalar<T> in case of NULL for result used value Default(T);
I think, Your function can look like
function IsNull(ADate: TDateTime): Boolean;
begin
Result := ADate = Default(TDateTime);
end;
tDateTime is undefined for the values between 0 and -1 which means that a tDateTime of -0.5 is an undefined value and useful for a null date as an alternative to NaN. DateTimeToString will display -0.5 the same as +0.5;
Use PDateTime instead TDateTime, and send as nil value. If no pointer to value, result no value.
To check value use Assigned ptr :
MyDatePointer := nil;
if ( Assigned(MyDatePointer)) then ...

Crash in Delphi function - StrToDateTime

Who can to advice in my problem.
I set date format as 'JUL/12 - 12 15:35', but when using StrToDateTime then give EConvertError.
What can I do with this format which contains 2 - date separator ?
Use next code
function LocaleFormatStrToDateTime(const S: string): TDateTime;
var
LFormatSettings: TFormatSettings;
begin
LFormatSettings := GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT);
LFormatSettings.ShortTimeFormat := FormatSettings.ShortTimeFormat;
LFormatSettings.TimeSeparator := FormatSettings.TimeSeparator;
Result := StrToDateTime(S, LFormatSettings);
end;
----------
**
the best solution is use jvDateUtil.StrToDate*
**
Your format is completely non-standard (and almost incomprehensible), so can't be handled by the built-in Date/Time formatters.
You've designed your own format, so you need to write your own code to convert to and from it.
This is nature's way of telling you not to use wacky date and time formats!
Probably the string you're trying to convert is not compatible with the default system format. Taking a look at the method signature and description reveals that you can override it to suit your needs, see an example here.
It would be helpful if you posted a piece of the code you have so far, maybe you overlooked something.
EDIT
I've missed the fact that your're using a complex format, including multiple separators for the date, which I'm not sure that are supported in delphi.
I guess that in this case you could split your string into pieces and then encode them into a TDateTime. To convert your month name to a month number you can iterate through the LFormatSettings.ShortMonthNames array, something like:
String longMonth:= copy(S, 0, 3);
for i := Low(LFormatSettings.ShortMonthNames) to High(LFormatSettings.ShortMonthNames) do
if SameText(longMonth, LFormatSettings.ShortMonthNames[i]) then begin
shortMonth:=FormatFloat('00', i);
Break;
end;

Avoiding Locale Conflicts when storing TDateTime's in Floats?

I got the TDateTime thing fixed by using Floating vars to store them in a file. However, now I face a new problem: Invalid Floating Point - Most likely because of the Comma Separator.
How can I set the default separator in my program? Or is there any other way around?
You can use a TFormatSettings record to specify the decimal separator when you call StrToFloat and FloatToStr. You have to decide what to use and stick to that. Here is sample code with a .
var
d: TDateTime;
s: string;
fs: TFormatSettings;
begin
d := Now();
fs.DecimalSeparator := '.';
s := FloatToStr(d, fs);
end;
Another option would be to use the XML standard date time format. Delphi has some functions in XSBuiltIns to do the conversion from TDateTime to string and back. You will have a time zone offset in the value so if you move your persisted TDateTime from one time zone to another you may have some unwanted behavior. It depends on the usage of the value.
var
d: TDateTime;
s: string;
begin
d := Now();
s := DateTimeToXMLTime(d);
d := XMLTimeToDateTime(s);
end;
As Mikael suggested, there are a many ways to do this. To re-cap you wish to store a TDateTime to a file in textual format and be able to restore this value successfully irrespective of the locale on which the restoration happens.
Option 1
When storing, call FloatToStr, say, but force a '.' for the decimal separator through the TFormatSettings parameter. On restore, use StrToFloat with the same TFormatSettings.
Option 2
Encode the 8 byte TDateTime value using base 64. This has the downside that it renders the value unreadable.
Option 3
Similar to option 1, but encode the TDateTime by calling DateTimeToStr and explicitly passing a TFormatSettings that does not rely on anything in the locale – so do not rely on the locale's date or time separators, instead force your own. To reverse call StrToDateTime with an identical TFormatSettings record.

Resources