The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,262 other subscribers

Archive for November 11th, 2020

How to quickly add hours/minutes/second to date and time in Excel?

Posted by jpluimers on 2020/11/11

Excel date times are almost identical to OLE/COM automation date times (that used in many Windows applications).

Which means that dates are 1 unit apart, and:

  • Weeks = 7
  • Days = 1
  • Hours = 1/24
  • Minutes = 1/(24*60) or 1/1440
  • Seconds = 1/(24*60*60) or 1/86400

That way you can easily add one hour to a date/time value by adding 1/24.

Source: How to quickly add hours/minutes/second to date and time in Excel?

Related:

–jeroen

Posted in Development, Excel, LifeHacker, Office, Power User, Software Development | Leave a Comment »

Editors (including visual studio code – VSCode): insert tab character manually – Stack Overflow

Posted by jpluimers on 2020/11/11

Sometimes you are in search of a real TAB character, as most editors (except a few like the ones for Golang) I bump into are space-based. A great answer at [WayBack] visual studio code – VSCode insert tab character manually – Stack Overflow:

Quick-and-dirty solution: Find a tab somewhere else, then copy-paste.

Chances are that you already have a tab character in the file you are editing, but if not you can generate one in another application or text editor.

You can also generate a tab programmatically in a bash shell with the following command (the brackets are optional):

echo -e [\\t]

For your more immediate needs, I have inserted a tab character below…

    There is a tab character between these brackets: [ ]

–jeroen

Posted in Development, Software Development, Visual Studio and tools, vscode Visual Studio Code | Leave a Comment »

Be careful changing the DataContext of a TRemotable

Posted by jpluimers on 2020/11/11

Still not sure why the RTL code is like this:

procedure TRemotable.SetDataContext(Value: TDataContext);
begin
  if (RemotableDataContext <> nil) and (RemotableDataContext = Self.DataContext) then
  begin
    TDataContext(RemotableDataContext).RemoveObjectToDestroy(Self);
  end;
  FDataContext := Value;
end;

It means that if you ever have to change the DataContext property from the default global RemotableDataContext, it will be removed, but not added to the new DataContext.

When you assign it nil (so you can dump it to JSON, which often is easier to read than XML), and back to the old value, this results in a memory leak:

function TNotificationKeyPortTypeImplementation.prematchChanged(const prematchChangedRequest: prematchChangedRequest): prematchChangedResponse;
var
  DataContext: TDataContext;
begin
  // ...
  DataContext := prematchChangedRequest.DataContext;
  try
    prematchChangedRequest.DataContext := nil; // otherwise the JSON serializer will stackoverflow because DataContext points back to the TRemotable instance.
    Result := Format('prematchChanged: prematchChangedRequest=%s', [TJson.ObjectToJsonString(prematchChangedRequest)]);
  finally
    // `prematchChangedRequest.DataContext := nil` removed `prematchChangedRequest` from `DataContext.FObjsToDestroy`
    DataContext.AddObjectToDestroy(prematchChangedRequest);
    prematchChangedRequest.DataContext := DataContext; // does not add `prematchChangedRequest` to `DataContext.FObjsToDestroy`
  end;
end;

or when you are outside an incoming SOAP call where DataContext might not be assigned at all:

function ToJSON(const Value: TRemotable): string;
var
  DataContext: TDataContext;
  RemotableDataContext: Pointer;
begin
  if Assigned(Value) then
  begin
    DataContext := Value.DataContext;
    try
      Value.DataContext := nil; // otherwise the JSON serializer will stackoverflow because DataContext points back to the TRemotable instance.
      Result := TJson.ObjectToJsonString(Value);
      Result := TRegExSanitiser.ReplaceSecretInText(Result, [rttJSON]);
    finally
      // `Value.DataContext := nil` removed `Value` from `DataContext.FObjsToDestroy`
      if Assigned(DataContext) then
      begin
        RemotableDataContext := GetRemotableDataContext();
        if Assigned(RemotableDataContext) and (RemotableDataContext = DataContext) then
          DataContext.AddObjectToDestroy(Value);
        Value.DataContext := DataContext; // does not add `Value` to `DataContext.FObjsToDestroy`
      end;
    end;
  end
  else
    Result := '';
end;

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »