Although they worked very well, inside me everything was screaming. I was working with objects all over the project, and now I needed to use procedural functions in my domain. Today I want to try to convert those functions to a real object, which makes it easy to convert from any date/time format to a specific one that is used in the whole company. Why? to show the power of objects ;)
The procedural interface
The unit that is used to convert a specific date and/or time format to another one, for example: 23122008 to 20081223 or 2008-12-23 to a TDateTime object. The code is made to handle conversion errors, so in the time this unit was created (years ago) it would have been very useful. Now (as far as I know) the standard Delphi library has some functionality to perform the conversions. There are around the 100 functions to choose from and some of these functions looks very similar. Similar code can lead us to code duplication and that can lead us to bugs in multiple places. But even these 100 functions don't give you all the possibilities you can have. Every function is working on its own and every result should be stored in memory. To be able to do some calculations or comparisons or multiple conversions we are in need for some other "magic". This magic are objects.The object oriented interface
Before I describe the interface of the new object, I will describe some requirements for this class.- It should be possible to parse a given date and or time to a TDateTime object.
- It should be possible to convert a TDateTime object to a specific date and or time format.
- It should be possible to add or remove time to the object.
type DateTime = class
begin
begin
public:
procedure ParseDateTime(value, format : string);
function ToString(format : string) : string;
function Compare(dt : DateTime) : integer;
function ToString(format : string) : string;
function Compare(dt : DateTime) : integer;
end;
The method ParseDateTime is used to convert a string to format that is used internally. The method ToString will convert the internal time value to a specific format. Compare will compare the two different values (by using the internal format).OK, now we have a basic interface how do we implement this and what is our internal value? The internal value should be (in my opinion) in a format that the computer understands the best. In Delphi we can use the TDateTime type (if I remember correct) which is just a alias for a Long type which can be found in most programming languages.
The parsing of the Date and Time values can be done by using functions that are included in Delphi. We can make sure that errors are caught and we can throw an exception (for example IncorrectFormat exception, or something like that). The same we can do for the ToString function. (I won't show a real implementation, because I don't want to show an example with errors.)
To compare two DateTime objects we simply compare the internal values. If I recall correctly Delphi can access private fields of a class instance (an object) from another class instance of the same type, so this shouldn't be a problem. For convenience and to follow standards we return some kind of value depending on the comparison (0 means self equals dt, negative means self is smaller (earlier) than dt and positive means self is greater (later) than dt). There might be a function for this in Delphi as well, but I am not sure.
Time zones
OK, but what about different time zones you might say. How can a datetime from Europe (GMT +1 and GMT +2) be compared with America (GMT -7)? There are a few solutions for this I think:- We don't mind, so we don't implement
- Convert date and time to UTC (GMT 0)
- Use region information
*Disclaimer* What I write here is pure theoretical, I couldn't test it, but by providing this information, the reader can try it out in his/her preferred programming language.
For converting a date and time format we need to know in which time zone the given time is. There we could use for example the TTimeZoneInformation type form Delphi (_TIME_ZONE_INFORMATION structure in Win32 API). To get the UTC time first convert the datetime-value to a long (as before) and then add the TTimeZoneInformation.Bias value. I am not sure if it is possible to get the TTimeZoneInformation type for other time zones, but it is worth trying.
When you choose to include the timezone info into the DateTime class, you can use this information for comparison as well.
No comments:
Post a Comment
Note: only a member of this blog may post a comment.