|Perl: the Markov chain saw|
Getting started with DateTimeby monsterzero (Monk)
|on Jan 16, 2004 at 16:59 UTC||Need Help??|
The DateTime suite of modules was created to address a very fundimential problem with dates in perl. There are several different packages on CPAN with overlapping functionality, but it was difficult to take dates in one package and convert them to another which you would often have to do to get a function from a different package.The primary goal of DateTime is to solve this problem. The DateTime project also has the Olson Time Zone database support built in. This database contains code and data that represent the history of local time for many locations around the globe. It is updated to reflect changes made by political bodies to UTC offsets and daylight-saving rules. This database is used by several implementations, including the GNU C Library used in GNU/Linux.
Currently the project can be divided into several categories.
Core functionality - This contains the core datetime object along with time zone handling. In addition there are modules that handle various types of datetime sets, and preforming set math operations on them.
Parsing and formatting - This set contains the modules that help getting dates into and out of datetime.
Events and sets - This contains various modules that are based on generating an event or set of events. Events can be any event like easter sunrise/sunset.
Non-Gregorian calenders - This contains the modules for converting dates to/from other calenders like Julian, Mayan and others.
Let's take a look at how we can use DateTime to create a date in perl. Having downloaded it from CPAN and installed it in the normal manner using it is as simple as:
Or since you most often want the current date and/or time you can simply do
The difference between the to is that DateTime->now not only has the date but also the time. whereas DateTime->today is truncated to the day. Both of these will take the time zone offset. On some operating systems (windows) setting the time_zone param to local will not work unless the TZ environment variable is set.
Now that I have something in DateTime how can I get it out? DateTime provides some basic output routines. Some examples are
The outputs are self explanatory except for the DateTime() method. The output is like 2003-08-20T00:00:00. I mainly use this for debugging and testing purposes.
Converting between timezones is what makes DateTime shine.
What time is it in Helsinki, when it is 9pm in Chicago?
One of the big problems with handling dates is daylight savings time. Since DateTime used the Olson database, DateTime can do it all for you.
This will print 1998-04-05T08:00:00. Notice that the time is 8:00 not 7:00 this is because on April 5 1998 at 2:00 am is when daylight savings time takes effect here in Los Angeles. DateTime is smart enough to know the DST rules and makes the correction.
But what if I have a date that is outside of my program (external source) well there are currently 14 formatting/parsing modules available to datetime. Chances are one of them will parse the date for you. Here is an example.
In this example I have chosen to use the DateTime::Format::HTTP module created by Iain Truskett. Basicly, I have a date (in HTTP format) and I use the parse_datetime method to convert the string to a datetime object. Then I output the date in GMT ASCII time format. One thing to notice is that the formatting modules all have a parse_datetime (for getting strings into) and format_datetime (for outputting DT objects) methods. This makes it easy to use all of the formatting modules since they all have a some what standard interface.
This is all fine and good but what happens when you do not know the format of the date. Well the other day someone came to comp.lang.perl.misc and asked a very similer question. He asked:
Hello, I just came from cpan, after doing some searches and before I get a module, wanted to ask if any one out there knows of a module that takes an array of dates and sort them regardless of the date format.
Good question!! lets see if Datetime can help with this. I checked the DateTime FAQ and came up with something like this.
Now the OP did not specify what format his dates were in so I just had to make some up. In the above example the real workhorse is in the package DateTime::Format::Mytest, what I have done is chain together three different DateTime format modules in order to parse the dates. Once I parsed the dates (and placed them in the new_dates array) I just sorted the new array using the standard sort function.
Ok, now that I can create a date let's look at how to compare 2 different dates. In DateTime we can use the compare method for this.
Here is an example:
This will set the $cmp variable to either -1,0 or 1. If $dt is less than $dt2 the value of $cmp will be -1. If $dt is equal to $dt2 the value will be 0 and if $dt is greater than $dt2 the value will be 1. As you can see this is using the built in function compare. You can also use the standard perl function to accomplish the same thing.
All of these work as expected!
Date math is very easy with DateTime.Here is an example.
This will produce a date one week earler. I can use days, months, years and all work as expected.
The DateTime project is still being developed. However, I have found it to be extreamly useful. It has made dealing with date and times in perl much simpler.
For more information about the datetime project please see the DateTime.perl.org website There is also a mailing list. You can subscribe by sending a message to email@example.com.
Major thanks goes to Dave Rolsky for writing the DateTime module and to the rest of the developers at the datetime project.