Date Adapter Utility

15 views
Skip to first unread message

Sean Devlin

unread,
Jun 11, 2009, 9:24:09 PM6/11/09
to Clojure
Hey everyone,
I'm looking for feedback on a date utility library I'm writing. It's
still early in it's design, and I want to see if other people see
anything. It's designed to create various forms of date objects.

It's available on github here:

http://github.com/francoisdevlin/devlinsf-clojure-utils/tree/master

Here is an except from docs/date-utils.markdown:

namespace: lib.devlinsf.date-utils

This library is designed to add a standard way to construct & wrap
date objects in Clojure. It is intended to be a very broad purpose
adapter.

It depends on clojure.contrib.str-utils

(defn date[& params] ...)

This function is designed to create a java.util.Date object.

;This code was executed on June 11, 2009, near 7PM
user=> (date)
#<Date Thu Jun 11 19:07:28 EDT 2009>

The date method can also take a list of keywords followed by values

user=> (date :year 1982)
#<Date Fri Jun 11 19:10:06 EDT 1982>

Notice that the "unset" values default to the current time and date.

user=> (date :year 1982 :month 2 :day 4)
#<Date Thu Mar 04 19:11:35 EST 1982>

Passing a map works just a easily:

user=> (date {:year 1982 :month :2 :day 4})
#<Date Thu Mar 04 19:31:30 EST 1982>

* Setting the Month *
In the example above, notice that month 2 corresponds to March, not
February. This is done to match the Java api. However, that's a PITA.
The month field can also take a keyword.

user=> (date :year 1982 :month :march :day 4)
#<Date Thu Mar 04 19:31:30 EST 1982>

Or, use the three letter shorthand:

user=> (date :year 1982 :month :mar :day 4)
#<Date Thu Mar 04 19:31:30 EST 1982>
Much better! The complete list of month keywords:

*Date Parsing*
(Note: This parser currently only works for dates, not times.)

How about creating a date from a string?

user=> (date "3/4/1982")
#<Date Thu Mar 04 19:32:39 EST 1982>

user=> (date "3-4-1982")
#<Date Thu Mar 04 19:33:03 EST 1982>

Hmmm, this is good for Americans, but the rest of the world might
prefer something else. No problem.

(date "4/3/1982" :order [:day :month :year])
=> <Date Thu Mar 04 19:34:33 EST 1982>

Perfect!

*nil behavior*

This function returns nil if passed nil

user=> (date nil)
nil

* Wrapping other time formats *

This function can also accept other time formats and return them as
java.util.Date objects. This method can take:

*java.lang.Long
user=> (date (. (date :year 1970) getTime))
#<Date Thu Jun 11 20:36:51 EDT 1970>

*java.util.Calendar
user=> (date (java.util.GregorianCalendar. ))
#<Date Thu Jun 11 20:38:00 EDT 2009>

*java.sql.Timestamp
user=> (date
(java.sql.Timestamp.
(. (java.util.Date. ) getTime)))
#<Date Thu Jun 11 20:38:48 EDT 2009>

*java.util.Date
user=> (date (java.util.Date. ))
#<Date Thu Jun 11 20:39:59 EDT 2009>

Each of the above functions "drills down" to the Long value, and
builds a new Date object. This way changing the original object won't
affect the new date record.

*** The Awesome Part ***

There are also four other methods in this library

long-time (returns java.lang.Long)
greg-cal (returns java.util.GregorianCalendar)
sql-ts (returns java.sql.Timestamp)
time-map (returns clojure.lang.PersistentHashMap)

Each of these has the exact same signature as date. Every use of date
shown above will work with these methods. For example, each of the
following is valid:

user=> (long-time)
1244764606423

user=> (greg-cal (date))
#<GregorianCalendar java.util.GregorianCalendar[...]>

user=> (sql-ts :year 1982 :month :march :day 4)
#<Timestamp 1982-03-04 19:57:23.309>

user=> (time-map "3/4/1982")
{:minute 57, :hour-of-day 19, :day-of-week 5, :year 1982, :month
2, :day 4, :second 44, :ms 375}

Each of these methods also drills down to the Long, so that there is
no object linking. This also makes each of the methods a very
versatile adapters.

AndrewC.

unread,
Jun 12, 2009, 10:19:38 AM6/12/09
to Clojure


On Jun 12, 2:24 am, Sean Devlin <francoisdev...@gmail.com> wrote:
> Hey everyone,
> I'm looking for feedback on a date utility library I'm writing.

Without wanting to seem down on your obvious care and hard work, the
last time this came up the general consensus was that "Date libraries
are much harder then you think. Use Joda!"

http://groups.google.com/group/clojure/browse_thread/thread/659503e698ede0b5/9dda25f36f102799?lnk=gst&q=joda#9dda25f36f102799

http://joda-time.sourceforge.net/

Sean Devlin

unread,
Jun 12, 2009, 11:09:29 AM6/12/09
to Clojure
Thanks for raising this thread. You're right, time manipulation is a
very difficult problem. I should have been more clear about the
intent of my library.

My problem is that time handling is not unified in Java. There are at
least 4 internal ways Java handles time:

java.util.Date
java.util.Calendar
java.sql.Timestamp
java.lang.Long

There isn't a good interface unifying the concept of time. The best
you can do usually is figure out how to eventually convert each of
these to a java.util.Date. This is what motivated the first method,
date.

(date *some-object*) => java.util.Date

It's supposed to be the swiss army knife of date creation. A super-
duper factory, if you will. Then once I have a Date (insert zingger
here), I know how to construct lots of other time objects.
Internally, each function:

long-time
greg-cal
time-map
sql-ts

calls the date fn. The date adapter fn now sorta behaves like an
abstract super type.

You raised an excellent point about using Joda. Perhaps there could
be something gained by combining Joda's manipulation with a versatile
adapter. I think I'll look into trying Joda data types into my
adapter fn.

Thanks for bringing up this point.

On Jun 12, 10:19 am, "AndrewC." <mr.bl...@gmail.com> wrote:
> On Jun 12, 2:24 am, Sean Devlin <francoisdev...@gmail.com> wrote:
>
> > Hey everyone,
> > I'm looking for feedback on a date utility library I'm writing.
>
> Without wanting to seem down on your obvious care and hard work, the
> last time this came up the general consensus was that "Date libraries
> are much harder then you think. Use Joda!"
>
> http://groups.google.com/group/clojure/browse_thread/thread/659503e69...
>
> http://joda-time.sourceforge.net/
Reply all
Reply to author
Forward
0 new messages