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 1,828 other subscribers

Archive for the ‘Software Development’ Category

ISO 8601: Delphi way to convert XML date and time to TDateTime and back (via: Stack Overflow)

Posted by jpluimers on 2011/07/19

Recently I needed a way of concerting back and forth ISO 8601 DateTime values used in XML from Delphi.

Thoug the Delphi DateUtils unit has some ISO 8601 features for calculating week numbers, you actually need to the XSBuiltIns unit for converting back and forth to ISO 8601 text representation of a DateTime.

I remembered answering the related In Delphi is there a function to convert XML date and time to TDateTime question on StackOverflow a while ago (and forgot that this was back in 2009 <g>).

ISO 8601 dates can either include a time-zone, or be in UTC, which is not part of that answer. So lets elaborate on that answer a bit now:

UTC times in ISO 8601 format end in a Z time zone designator like this:

    <Created>2011-06-29T17:01:45.505Z</Created>

The Z UTC indicator is basically a shortcut for a timezone offset of +00:00 or -00:00, effectively being a zero (or zulu) timezone.

Nonzero timezones start with an optional + or -, followed by the hours and minutes offset from UTC, for instance +01:00 for the Central European Time zone.

    <Created>2011-06-29T17:01:45.505+01:00</Created>

When you want historical time zones, then you need the Delphi TZDB interface to the historical TZ database.

To do the timezone calculations, I used the TimeZoneBias function from Indy, which is either in the IdGlobal unit (Indy <= version 9) or the IdGlobalProtocols unit (Indy 10 and up).

Conversion is done by using the TXSDateTime (that like all the XS conversion classes descends from TRemotableXS in the InvokeRegistry unit).

Most of the classes descending from TRemotableXS contain two methods: NativeToXS and XSToNative doing the underlying conversions.

Since I didn’t need the historical reference in the TZDB, this is the code that I came up with:

unit Iso8601Unit;

interface

type
  TIso8601 = class(TObject)
  public
    class function DateTimeFromIso8601(const Value: string): TDateTime; static;
    class function UtcDateTimeToIso8601(const Value: TDateTime): string; static;
    class function DateTimeToIso8601(const Value: TDateTime): string; static;
    class function UtcNow: TDateTime; static;
    class function ToUtc(const Value: TDateTime): TDateTime; static;
    class function FromUtc(const Value: TDateTime): TDateTime; static;
  end;

implementation

uses
  IdGlobalProtocols, {IdGlobal for Index   SysUtils,
  XSBuiltIns;

class function TIso8601.DateTimeFromIso8601(const Value: string): TDateTime;
begin
  with TXSDateTime.Create() do
  try
    XSToNative(value); // convert from WideString
    Result := AsDateTime; // convert to TDateTime  finally
  finally
    Free();
  end;
end;

class function TIso8601.UtcDateTimeToIso8601(const Value: TDateTime): string;
begin
  with TXSDateTime.Create() do
  try
    AsUTCDateTime := Value;
    Result := NativeToXS; // convert to WideString
  finally
    Free();
  end;
end;

class function TIso8601.DateTimeToIso8601(const Value: TDateTime): string;
begin
  with TXSDateTime.Create() do
  try
    AsDateTime := Value; // convert from TDateTime
    Result := NativeToXS; // convert to WideString
  finally
    Free();
  end;
end;

class function TIso8601.UtcNow: TDateTime;
begin
  Result := ToUtc(Now);
end;

class function TIso8601.ToUtc(const Value: TDateTime): TDateTime;
var
  Bias: TDateTime;
begin
  Bias := TimeZoneBias;
  Result := Value + TimeZoneBias;
end;

class function TIso8601.FromUtc(const Value: TDateTime): TDateTime;
var
  Bias: TDateTime;
begin
  Bias := TimeZoneBias;
  Result := Value - TimeZoneBias;
end;

end.

–jeroen

via In Delphi is there a function to convert XML date and time to TDateTime – Stack Overflow.

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 7 Comments »

Delphi commandline oddity with double-quoted arguments

Posted by jpluimers on 2011/07/14

Boy, I was wrong. Somewhere in the back of my head I knew it.

ParamStr goes from zero (the name of the EXE) through ParamCount (the last parameter). Duh :)

 

I’ll keep this so you can have a good laugh:

 

When you add double quoted arguments to the commandline of your Delphi app, strange things can happen: the first parameter seems to be gone, while it is there.

It appears that the ParamCount/ParamStr logic fails here, and cannot be repaired because of backward compatibility.

Lets look at this commandline:

“..\bin\DumpCommandLine.exe” “C:\Program Files\test.xml” “C:\Program Files\meMySelfAndI.xml”

The demo code below will output something like this:

ParamCount:     2
ParamStr():
0       C:\develop\DumpCommandLine\bin\DumpCommandLine.exe
1       C:\Program Files\test.xml
CommandLine:
"..\bin\DumpCommandLine.exe" "C:\Program Files\test.xml" "C:\Program Files\meMySelfAndI.xml"
CommandLineStrings.Count:       3
CommandLineStrings[]:
0       ..\bin\DumpCommandLine.exe
1       C:\Program Files\test.xml
2       C:\Program Files\meMySelfAndI.xml

You see that regular ParamCount/ParamStr calls will mis the “C:\Program Files\test.xml” parameter.
But getting it through CommandLineStrings will correctly get it.

This is the dump code:

unit CommandlineDemoUnit;

interface

procedure DumpCommandLineToConsole;

implementation

uses
  Classes, CommandlineUnit;

procedure DumpCommandLineToConsole;
var
  CommandLineStrings: TStrings;
  I: Integer;
begin
  Writeln('ParamCount:', #9, ParamCount);
  Writeln('ParamStr():');
  for I := 0 to ParamCount - 1 do
    Writeln(I, #9, ParamStr(I));
  Writeln('CommandLine:');
  Writeln(CommandLine);
  CommandLineStrings := CreateCommandLineStrings();
  Writeln('CommandLineStrings.Count:', #9, CommandLineStrings.Count);
  Writeln('CommandLineStrings[]:');
  try
    for I := 0 to CommandLineStrings.Count - 1 do
      Writeln(I, #9, CommandLineStrings[I]);
  finally
    CommandLineStrings.Free;
  end;
end;

end.

And this the code to get the CommandLine and CommandLineStrings, which will fill a TStrings result using the CommaText property (it uses a default QuoteChar of of double quote #34 and Delimiter of space #32, this will work nicely):

unit CommandlineUnit;

interface

uses
  Classes;

function CommandLine: string;
function CreateCommandLineStrings: TStrings;

implementation

uses
  Windows;

function CommandLine: string;
begin
  Result := GetCommandLine();
end;

function CreateCommandLineStrings: TStrings;
begin
  Result := TStringList.Create();
  Result.CommaText := CommandLine;
end;

end.

Note that you need to manually free the TStrings object to avoid memory leaks.

–jeroen

Posted in Delphi, Development, Software Development | 13 Comments »

Extracting MSI files

Posted by jpluimers on 2011/07/13

Extracting MSI files can be a pain.

Some compression programs (like 7zip) can unpack them, but leave the unpacked filenames as gibberish.

Many people recommend using msiexec (link to technet docs) on the commandline using the /a parameter (which does an administrative install effectively unpacking it), but others prefer integration in Windows Explorer.

msiexec /a PathToMSIFile /qb TARGETDIR=DirectoryToExtractTo

There are many tools allowing to unpack, and the best seems to be LessMSIerables by Scott Willeke which used to be on the (now defunct) pingpoet blogs, but got resurrected as lessmsi at oogle code.

Note that LessMSI doesn’t always work when msiexec /a works; for instance, I once got this error message:

Error: System.Runtime.InteropServices.COMException (0x00000003): Failed to close cab extract object, error: 3

Note that when you want to view MST files in addition to MSI files, then you need MSTVIEW from ORK XP or ORK 2003 (which you can get through the Office 2003 resource kit downloads page).

–jeroen

Posted in .NET, Development, Power User, Software Development | 2 Comments »

Mac OS X Lion Supports Running 2 Additional OS X Instances Within a Virtual Machine

Posted by jpluimers on 2011/07/12

Good news for developers and IT engineers:

The new Mac OS X Lion EULA contains a phrase basically indicating you are a allowed to run 2 additional copies or instances of OS X Lion on each Mac already running OSX Lion.

This is a big change for OS X users.

For the beta, there were already steps on how to setup such a VM on a Mac or PC (including faking it to be the OS X Server), hopefully those steps have become a lot simpler now.
Probably these steps on how to make a OS X Bootable Installer from a USB Flash Drive helps too.

The OS X Lion release is already available to developers, and should be available to the general public really soon now.

–jeroen

via: Mac OS X Lion Supports Running Additional OS X Instances Within a Virtual Machine.

Posted in Apple, Development, Power User, Software Development, xCode/Mac/iPad/iPhone/iOS/cocoa | Leave a Comment »

Code Quality: the rate of WTFs

Posted by jpluimers on 2011/07/06

OSnews has an interesting view on code quality: the number of WTFs/minute.

I know it is from 2008, but it is so true, so I’m glad I re-found it.

–jeroen

via: wtfm.jpg (500×471).

Posted in .NET, Agile, Delphi, Development, Opinions, Software Development | Leave a Comment »

winapi – Best way to do non-flickering, segmented graphics updates in Delphi? – Stack Overflow

Posted by jpluimers on 2011/07/05

Recently, Jon Lennart Aasenden (of Surface Library fame) asked a nice winapi – Best way to do non-flickering, segmented graphics updates in Delphi question on StackOverflow.

Though the question is marked Delphi, the boundaries and solution very generic, and apply to any graphics library or GUI you develop: Windows, Mac, iOS, et cetera:

  • Avoid double buffering when using GUI connections
  • Draw only what you need
  • Avoid redrawing whenever possible (for instance by letting the OS perform scrolling for you)
–jeroen

Posted in .NET, Delphi, Development, Software Development, xCode/Mac/iPad/iPhone/iOS/cocoa | 2 Comments »

The importance of static links on the web: many (really) old links still work

Posted by jpluimers on 2011/06/30

Doing a re-haul of a Delphi project from almost 15 years ago, and some modifications a few year later, I came across a list of favourites I used back then.

It also reminded me when beginning that project, there was no Google Search; you had Yahoo SearchHotBot and later on Northern Light, but AltaVista was the best.
Finding your way around was much harder, but luckily later on Google Search was there :)

So here is a sample of how static the web is:

Few suffer from link rot: I was pretty amazed that most of the links still work!

–jeroen

Posted in Delphi, Development, Power User, Software Development | 4 Comments »

Weaving: Source code, IL, ByteCode, Native

Posted by jpluimers on 2011/06/28

Weaving extends your program adding new functionality.

It can be at different levels for difference purposes (AOP, Debugging, Automated Testing, etc).

This .net – What is IL Weaving? question on StackOverflow contains a few pointers to interesting reading material.

–jeroen

Posted in .NET, Debugging, Delphi, Development, Software Development | Leave a Comment »

StackOverflow C# question: Slight confusion over reference types and value types in the C# spec

Posted by jpluimers on 2011/06/23

Recently there was a nice Slight confusion over reference types and value types in the C# spec on StackOverflow.

Summary:

When structs are value types, but interfaces are reference types, how can a struct implement an interface and still be a value type?

The answer is boxing: when a reference to a struct is needed, a reference object is automatically created, and the value of the struct is box-wrapped into it.

This automatic boxing is really nice, but be aware that when frequently doing this, it can have a huge performance impact.

Thanks Abhina Basu for blogging about boxing structs having interfaces, and the many volunteers on StackOverflow explaining about boxing.

–jeroen

Posted in .NET, C#, Development | Leave a Comment »

.NET WPF Databinding to Collection Properties » Danny Thorpe

Posted by jpluimers on 2011/06/22

Danny Thorpe recently wrote a very nice post on via Databinding Collection Properties in WPF that sometimes fail without warning.

The short summary is that this fails without warning when binding to properties that do not explicitly implement the IList interface, for instance when binding to a collection that supports only IEnumerable (because of yield return) or IList<T> (for instance when binding to a Dictionary<TKey, TValue>.Values, which implements IList<T>, but not IList).

Thanks Danny for blogging about this (he explains it way better than I can), and putting a warning that the workaround Dictionary<TKey, TValue>.Values.ToList() potentially can have a big impact on memory consumption.

Life would be so much easier if WPF could bind to IEnumerable or IList<T> :)

–jeroen

via: Databinding Collection Properties » Danny Thorpe.

Posted in .NET, Development, Software Development, WPF | 2 Comments »