The new kbmMW Features blog post serie will talk about various smaller, but useful, features within kbmMW.

This blog will be about the TkbmMWDateTime structure, which is a TDateTime on stereoids.

A plain TDateTime is essentially nothing but a double sized floating point value. It stores the number of days (and a fraction of a day) since 12/30/1899 12:00 AM.

It seems easy to work with, but unfortunately its ease of use is deceptive.

Why you may ask? Because it usually ends up with the developer storing local date/time values in databases and elsewhere.

It is simply lacking the concept of timezones.

TkbmMWDateTime always operates with full knowledge about timezones. Hence you can easily ask for a TkbmMWDateTime expressed in any currently available timezone on earth. which essentially means that TkbmMWDateTime is universal. In fact timezones by themselfs are not enough, since we often operate with daylightsaving in some countries in the world.

TkbmMWDateTime also handles that. Further TkbmMWDateTime makes it easy to express dates and times in various standard and non standard formats, easing conversion between string representations and numerical representations, on which one can do date and time manipulation.

So how to work with TkbmMWDateTime?

Its easy.

var
  dt:TkbmMWDateTime;
begin
  dt:=TkbmMWDateTime.Now;
end;

This instantiate a TkbmMWDateTime to the current date/time. If you want to figure out what that is in UTC time (or in other words in the GMT timezone), type:

'The time is '+DateTimeToString(dt.UTC)

And to get the current timezone registered with the time:

'Current timezone is :'+dt.GetTimeZone;

It will return something similar to +2:00. As you may notice, despite TkbmMWDateTime has full knowledge of the worlds timezone names, it will not return the timezone name. The reason is that there are many timezone names that can match a single timezone offset. Instead presenting a timezone as an offset value is a generally accepted way.

And to return the date/time as the local time:

'The local time is '+DateTimeToString(dt.Local)

kbmMW can convert to and from ISO8601, RFC-1123 and NSCA formatted date/time strings along with handling Unix like epoch based values.

To return an ISO8601 formatted string based:

s:=dt.ISO8601String

Which will put something like ’01-10-2001T12:00:00.000+01:00′ in the variable s (The actual value obviously depends on what value dt has been assigned).

Similarly assigning a new ISO8601 formatted string value to dt is done like this:

dt.ISO8601String:='01-10-2001T12:00:00.000+01:00'

The ISO8601 format is the defacto standard in most data exchange protocols like XML, JSON etc.

The RFC-1123 format is often used in HTML headers and other internet protocols.

The NSCA format is often used in WWW and FTP server log files.

The TkbmMWDateTime is also able to understand and produce ISO8601 formatted duration values, like 5 weeks, 2 days and 1 hour.

Just a few other formats it understands are fixed format, temporenc, since epoch in ns or ms, and custom formatted strings.

You can also make calculations using TkbmMWDateTime, adding or subtracting seconds, minutes, hours, days, months and years, add or subtract durations even expressed in fractional weeks and so forth.

The upcoming release of kbmMW now also supports advanced custom formatting features.

var
   dt1:TkbmMWDateTime;
   s:string;
begin
     dt1.UTCAsFormat['%Y-%D-%M']:='2018-17-12'; // Set according to format
     s:=dt1.UTCAsFormat['%Y/%D/%M'];            // Get according to format 

     dt1.UTCAsFormat['%Y-%M-%D %H:%N:%S']:='2018-12-17 23:15:22';

     dt1.UTCAsFormat['%Y-%M-%D %H:%N:%S.%Z']:='2018-12-17 23:15:22.123';

     dt1.UTCAsFormat['%Y-%M-%D %H:%N:%S %P']:='2018-12-17 11:15:22 AM';

     dt1.UTCAsFormat['%Y-%M1-%D %H:%N:%S %P']:='2018-Feb-17 11:15:22 PM';

     dt1.UTCAsFormat['%Y-%M-%D%i%i%i%H:%N:%S %P']:='2018-12-17abc11:15:22 PM';

     dt1.UTCAsFormat['%Y-%M-%D%I, %H:%N:%S %P']:='2018-12-17 Monday, 11:15:22 PM';

Just to show some of the setting and getter options.

%Y = 4 digit year
%Y1 = 2 digit year 19xx
%Y2 = 2 digit year 20xx
%Y3 = 2 digit year >=50=19xx, <50=20xx
%M = 1 or 2 digit month
%M1 = 3+ char US month name
%M2 = 3+ char locale month name
%D = 1 or 2 digit day
%H = 1 or 2 digit hour
%N = 1 or 2 digit minute
%S = 1 or 2 digit second
%Z = 1,2 or 3 digit millisecond
%T = Timezone
%P = A/P/AM/PM
%i = Ignore one character .
%Ix = Ignore all characters until x
%% = %

Eg.
 %Y-%M-%D %H:%M:%S
 %D.%M.%Y %H:%M:%S

The following two example format strings shows it is possible to make advanced filtering using regular expressions to extract the values and interpret them as required. Just follow the format as given above with an equal sign and a regular expression extracting data to populate those bits and pieces.

The first one:  %D.%M.%Y=(\d{2}).(\d{2}).(\d{4})  is interpreted as 2 digits that is a day of month, 2 digits that is a month of year and 4 digits that is the year.

The second one: Dato\=%D.%M.%Y=’Dato='(\d{2}).(\d{2}).(\d{4}) outputs “Dato=27.05.2018” when converting to a string, and is able to parse the strings of same format.

This is just a taste of the nice features in TkbmMWDateTime. In addition it supports having a null value, tracks value changes, can have a default value and more.

Finally the same unit now also includes a TkbmMWGregorianCalendar class which for now can calculate easter start/end for any year, in both the socalled western (gregorian) style and in eastern (orthodox or julian) style.

 

Loading

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.