Re: Date-Only NSTimestamps
Re: Date-Only NSTimestamps
- Subject: Re: Date-Only NSTimestamps
- From: "Pierce T. Wetter III" <email@hidden>
- Date: Wed, 2 Jan 2008 14:25:12 -0700
On Jan 2, 2008, at 1:01 PM, David Avendasora wrote:
Hi all,
I am working on some date-related calculations for a report. On the
report the user specifies a date, and I want to match to a
NSTimestamp-typed attribute in my Entity. The problem is that, of
course, the attribute also contains time information which for this
report is meaningless.
I've come up with a couple ways to achieve what I'm trying to do,
and they seem to work, but they feel _very_ clunky and overly
difficult, which brings me back to the old WO axiom: if it's hard,
you're probably not doing it the WO-way.
So, what are the best practices for working with an NSTimestamp
field, when all you really want is the date, not the time?
There's not really a good solution, in my experience. I'm A bit of a
date/time wonk, so this may be an overly long and opinionated answer,
but I feel like venting.
First off, setting the time to 00:00:00 sucks. It sucks because at
midnight, there is no different between Monday and Tuesday. Monday is
23:59.999999999999999999999999 (repeat ad infinitum).
Why does this matter? Because you can easily ass-raped by time
zones. Tuesday midnight can very easily turn into Monday midnight-
almost. Monday not-quite-midnight can very easily turn into Tuesday
midnight. I'll just skip over daylight savings time woes.
A typical hack is to normalize everything to noon in a particular
time zone instead. So anytime you get a date, you immediately move it
to noon. In Objective-C, you could do this via a category, which could
return a subclass of NSCalendarDate which knew it was normalized and
would do the right thing, and it would override things so the math
would work correctly (DST can screw up date calculations). So then you
could go crazy calling "normalize" every time you got a date, and be
safe, because the subclass knew that normalize was a no-op.
Of course, we're in Java, so we're screwed. You'll have to add a
completely separate class to do the normalization, which then just
gives you a normal NSTimestamp back, so you can find that your app
will spend an inordinate amount of time normalizing the dates.
For as long as I've been using WebObjects, I've been submitting
feature requests to be able to map the basic number types to custom
alternative classes. That would have solved the problem directly,
because then WO could pull an integer out of the database, which could
then be mapped to a date class and back again.
It might be possible now using the new enum support in 5.4, but only
as a hack, and I haven't looked at it.
Anyways, on to your problem, because none of that really affects you
except the midnight issue.
In your case, you're doing a report, so you have 2 date ranges. So
this then becomes a UI question. Let's say someone wants to do a query
for 2007. In most reporting software, that becomes:
WHERE date >= TIMESTAMP '2007-01-01 00:00:00' and date < TIMESTAMP
'2008-01-01 00:00:00'
that is, to get all of 2007, you really have to put the end date in
as midnight of the first second of 2008. Which is weird UI, because
the dates themselves are:
2007-01-01 to 2007-12-31
without the times...
Similarly, putting in:
2007-01-01 to 2007-01-01 gets you _zero_ days, because that's
midnight to midnight of the same day.
So.... What you can do is basically tweak the inputs. The low date
is rounded _down_ to midnight, the high date is converted to the
_next_ day then rounded down.
where date >= input_low.beginningOfDay() and date <
input_high.nextDay().beginningOfDay()
Note that this conflicts with the previous responses which tell you to
do:
WHERE date >= input_low.beginningOfDay and date <=
input_high.endOfDay()
David LeBer and Chuck Hill actually have a subtle bug, because they
probably have endOfDay() coded as 23:59:59.0000, but that means
there's a whole second they won't be including, the time between
23:59:59.00000000000000000000000000001 and the next day... There's a
whole second there that shows up in limbo. Which would really bum you
out if say, the bank was adding up transactions for the day, and
missed your paycheck if it was deposited right then...
Having both <= and >= in a where clause dealing with dates is always
a tip off for me. It should always be >= and <.
You can make the "endOfDay()" limbo arbitrarily small, by encloding
endOfDay() as 23:59:59.99999999999 or some such, but then its really
easy to have things roll over when you didn't want them to. It's
better to use < instead of <=, and use midnight of the following day
instead.
Pierce
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden