Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 9 of 9 total
Thread ISO 8601 Date Time Support?
Mon, Jul 27 2015 12:12 PMPermanent Link

Doug B

Are there any functions to convert between an ISO 8601 date/time value and the native DateTime value in EWB?  The REST API I'm calling expects this format.

Thanks,
Doug
Mon, Jul 27 2015 4:38 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Doug,

<< Are there any functions to convert between an ISO 8601 date/time value and the native DateTime value in EWB?  The REST API I'm calling expects this format. >>

No, but it's not hard to handle with these functions:

http://www.elevatesoft.com/manual?action=viewtopic&id=ewb2&topic=EncodeDateTime

http://www.elevatesoft.com/manual?action=viewtopic&id=ewb2&topic=YearOf
http://www.elevatesoft.com/manual?action=viewtopic&id=ewb2&topic=MonthOf

etc.

http://www.elevatesoft.com/manual?action=topics&id=ewb2&section=function_and_procedure_reference

Tim Young
Elevate Software
www.elevatesoft.com
Mon, Jul 27 2015 9:50 PMPermanent Link

Doug B

Thanks Tim.

After some more research, I noticed that the JavaScript Data object supports a toISOString() method.  I assume that EWB is using the native JS type for DateTime?  If so, is there an easy way to enable this functionality for the DateTime type in EWB other than writing my own conversion routines?

Doug
Tue, Jul 28 2015 7:36 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Doug,

<< After some more research, I noticed that the JavaScript Data object supports a toISOString() method.  I assume that EWB is using the native JS type for DateTime?  If so, is there an easy way to enable this functionality for the DateTime type in EWB other than writing my own conversion routines? >>

Good catch - I didn't know that method existed, or forgot at some point. Smile

I'll see if I can add a wrapper function, but for now you can use something like this:

interface

type

  external TDate emit Date = class
     public
        constructor Create(value: DateTime);
        function toISOString: String;
     end;

implementation

procedure ShowNow;
var
  TempDateTime: DateTime;
begin
  TempDateTime:=Now;
  ShowMessage(TDate.Create(TempDateTime).toISOString);
end;

Tim Young
Elevate Software
www.elevatesoft.com
Tue, Jul 28 2015 2:37 PMPermanent Link

Doug B

Awesome, thanks Tim.

How can I support the Date.parse method?  I tried this, but when calling parse I get an "Object doesn't support property or method parse" error:

external TDate emit Date = class
    public
       constructor Create(value: DateTime);
       function toISOString: String;
       function parse(value: String): Integer;  <===============
    end;

procedure ShowDate;
var
 d: TDate;
 DateMs: Integer;
 dt: DateTime;
begin
 d := TDate.Create(DateTime(0));
 DateMs := d.parse('July 28, 2015'); <=============== ERROR
 dt := DateTime(DateMs);
 ShowMessage(DateToStr(dt));  
end;

In addition, the JavaScript Data object has multiple constructors, including an empty one.  How to I add those constructors in EWB?

Thanks,
Doug
Wed, Jul 29 2015 6:54 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Doug,

<< How can I support the Date.parse method?  I tried this, but when calling parse I get an "Object doesn't support property or method parse" error: >>

Now you're moving the goalposts.... Wink

This is where JS falls down in terms of documentation.  Date.parse() is actually a static *class* method, not an class *instance* method, so you declare it like this:

  external TDate emit Date = class
     public
        constructor Create(value: DateTime);
        function toISOString: String;
        class function parse(const value: String): DateTime;
     end;

And use it like this:

var
  TempDateTime: DateTime;
begin
  TempDateTime:=TDate.parse('July 28, 2015');
  ShowMessage(DateToStr(TempDateTime));
end;

<< In addition, the JavaScript Data object has multiple constructors, including an empty one.  How to I add those constructors in EWB? >>

Just add them as additional constructors (Create methods) with the proper parameters.

Tim Young
Elevate Software
www.elevatesoft.com
Mon, Aug 10 2015 3:56 PMPermanent Link

Doug B

<< Now you're moving the goalposts.... Wink>>

There was a method to the madness. Smile

I've created a custom TJsonPersistent descendant, which can be used as the ancestor for any class that needs to easily serialize itself to/from JSON with support for the ISO 8601 date format.

Here's an example:

procedure TestSerialization;
var
 c: TCustomer;
 json: String;
begin
 c := TCustomer.Create;
 try
   c.CustomerId := 1234;
   c.FirstName := 'Joe';
   c.LastName := 'Smith';
   c.SignupDate := StrToDate('8/10/2015');
   json := c.ToJson();
   Window.Alert(json);
   c.FromJson(json);
   Window.Alert(Format('First: %s; Last: %s; Signup Date: %s', [c.FirstName, c.LastName, DateToStr(c.SignupDate)]));
 finally
   c.Free;
 end;
end;

The code above with serialize and de-serialize the TCustomer instance with datetime values encoded in ISO 8601 format.

Note that any class that inherits from TJsonPersistent will also automatically inherit the ability to serialize itself via the ToJson() and FromJson() methods.

I've attached the code so you can see exactly what I've done.  I think I had to make one or both of the TPersistent LoadProperty and SaveProperty methods virtual, so at a minimum it would be nice to do this in the production code that ships with EWB.

Also, it would be nice to have built-in support for this via a TReader/TWriter option that would allow you to specify whether you want datetime values stored as integers or ISO 8601 strings. This would allow the developer to simply select which format to use.

Doug



Attachments: ISO8601 Serialization Demo.zip
Tue, Aug 11 2015 12:09 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Doug,

<< I've created a custom TJsonPersistent descendant, which can be used as the ancestor for any class that needs to easily serialize itself to/from JSON with support for the ISO 8601 date format. >>

Nicely done. Smile

<< I've attached the code so you can see exactly what I've done.  I think I had to make one or both of the TPersistent LoadProperty and SaveProperty methods virtual, so at a minimum it would be nice to do this in the production code that ships with EWB. >>

It was SaveProperty - I changed this in the WebCore unit that we distribute.

<< Also, it would be nice to have built-in support for this via a TReader/TWriter option that would allow you to specify whether you want datetime values stored as integers or ISO 8601 strings. This would allow the developer to simply select which format to use. >>

No problem.  I'll pop it on the list for 2.02.

Thanks,

Tim Young
Elevate Software
www.elevatesoft.com
Thu, Aug 13 2015 5:46 PMPermanent Link

Doug B

Awesome, thanks Tim.

FYI, I had to make a minor change to prevent an error if the JSON value of a DateTime field is empty:

function ISO8601StringToDate(const AValue: string): DateTime;
var
 d: TDate;
begin
 if (AValue = '') then
   Result := DateTime(0)
 else
   Result := TDate.Parse(AValue);
end;

Doug
Image