Print This Post

5-Minute-Snack: Dealing with dates and time in Delphi. Hints about System.DateUtils.

Thinking back to Delphi 7, I clearly remember that the first thing I did was to import some sort of unit that provided more operations for string and date handling. Looking at Delphi Berlin – things have changed.

Especially when it comes to calculations that deal with time and dates – lots of improvements that might have gone unnoticed. Installing 3rd party units is no longer necessary as the RTL has been extended. Of course, this did not happen recently – still, a lot of Delphi developers are not aware of these extensions.

Thus, let’s look at the unit that offers lots of comfy stuff to calculations with date and time and query calendars: System.DateUtils.pas 

Embarcadero gives this util the following comment as a title:

Spending a lot of time in the .NET world myself, I always wondered why Delphi needed that long to provide these utilities as part of the RTL. Granted, .NET was created much later, but the Jedi Code Library was an essential part for these sort of things.

Let’s clear up some things about the terminology used in this unit:

Both functions return a date of type TDateTime that points to the start of the week or a week. Subtle difference in speech, big difference for the developer:

  • Whenever the undefined article (“a”) is used in the function or procedure name, you do not have to specify any point in time as a TDateTime  but as another numerical datatype, mostly Word .
  • If the definied article (“the”) is used, you will have to provide the point in time as a TDateTime . 

What does this mean?

Looking at an example: If you want to know the date week 9 starts in 2017 and you do not have any TDateTime  datatype, you may use StartOfAWeek . If you already have a variable of type TDateTime  and you want to determine the start of the week of that date, simply use StartOfTheWeek . Spending time both in the US and Germany during the year, I always become away of a slight difference between both countries with regard to weeks. In the US the week starts on a Sunday, in Germany on a Monday. Does the unit use some sort of calendar? Unlike Apple’s iOS the date operations of this unit cannot be bound to a certain calendar that determines these things. I also heard statements like “It depends on the region settings of the system the code is executed on.” That is actually horribly wrong. If that  were the case we would have to write any date calculation with the region settings in mind. Thus, note the subtle references to ISO 8601 :

And in case you did not know which norm was used:

What I want to say is this: Embarcadero put these comments there for a reason and they did their best to make sure it would be rather striking. However, even in the documentation they point out what ISO 8601 describes with regard to the function. 

Coming back to our little example: The norm specifies that a week starts on a Monday and ends on a Sunday.

Apart from doing calculations, the unit also offers an easy way to encode and decode date and time values, check for certain things like is the time in the am or pm, etc.

Finally, one more advise before using this unit:

Read the documentation and do not make assumptions about return values!

Why? Simple. I used the following function a couple of days ago:

So the return value will be negative if ANow is before AThen, as the logic from the parameters is reversed. Wrong! The return value will always be positive! Thus, you cannot use a condition like > 0  to determine if some date is older than another date! Reading the documentation clears this up right away:

DaysBetween  always returns a positive result and therefore the parameter values are interchangeable.

If you upgraded rather recently, spend some time exploring the RTL. You will be surprised what has been added in recent years.

Tags: , , ,