Time Converstions Issues

The Time object in Rails 2.3.2 is problematic because it acts like a
datetime whenever possible, especially in hash conversions.

I am not using time zones, and I am not using and Datetimes. The mysql
Time object simply holds a string, hh:mm:ss. All I want to do is
render :xml with that time to show up that way, no UTC and no date,
just hh:mm:ss

I can override time.to_s in enviornment.rb but when I use the to_xml
it still defaults to the datetime format. I tried to override the
attribute reader and then I get this error.

NoMethodError: undefined method `xmlschema' for "21:25:42":String
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/
active_support/core_ext/hash/conversions.rb:38

After looking into conversions.rb. It appears that rails thinks of
time as a datetime and this doesn't seem proper, especially when Date
does not. Why should a random date be assigned to the time?

I'll happily make a patch, but I thought to ask if there was some sort
of reasoning behind this, or a special circumstance I will destroy
when allowing to a Time hash conversion like Date has, which is
independent of datetime?

-Josh

After looking into conversions.rb. It appears that rails thinks of
time as a datetime and this doesn't seem proper, especially when Date
does not. Why should a random date be assigned to the time?

I'll happily make a patch, but I thought to ask if there was some sort
of reasoning behind this, or a special circumstance I will destroy
when allowing to a Time hash conversion like Date has, which is
independent of datetime?

The root of the issue is that there is no pure time of day class in
ruby (which is why Time is used). Maybe the right thing to do would be
to write such a class (although you'd have a large backwards
compatibility task).

Fred

Right.

Ruby Time and DateTime instances both represent a point in time (which
includes the date). They vary mostly in internal representation.
DateTIme has a broader range that it can represent, since TIme uses
the underlying C library time data structures and has a platform
dependent earliest and latest value.

ActiveSupport has a Duration class, which is closer to something like
the time interval which the OP seems to be seeking. But Duration is
really used only to represent a value to be added/subtracted from a
Time/Date time. It's what you get when you evaluate an expression
like 1.second, 1.hour, or (1.second + 1.hour). And it normally comes
into play in an expressions like

Time.now + 1.day

or 1.week.from_now

You said that you have a time object but that it holds a "string". If
you are updating your mysql db with a string format of time and you
specify the column as a string you can return it as a string and format
it anyway you want using gsub.

In either case, you can convert anything returned from mysql using gsub.

The first question you should ask yourself is what type of column do I
have in my mysql db?

Thanks for all the points and it is useful to think about the rails
time not having time_of_day. I still am not sure my problem was clear.
It seems to me that there should at least be a :emulate_datetime =>
false sort of option like with booleans, ex.

ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans =
false

The table simply holds 21:25:42, but activerecord retrieves the
information in the AR Hash as

time => "2000-01-01 21:25:42"

Where then does date, 2000-01-01 come from? It looks to me like rails
is just guessing, Shouldn't thee be a way for it to retreive time as
a string, time=> "2001-01-01" ?

I think the last suggestion from Alpha Blue will have to be my current
solution, don't use the mysql time object and instead use a string.

If you use a string in the db to hold time then you will not be able
to do a find querying for all records where the time is within a
range, for example, though this may not be an issue. Unless you use
LIKE on the string which could get messy. If you just remember to
always ignore the date part of the DateTime object then all will be
well.

Somebody should develop a TimeOfDay class derived from DateTime that
handles any messiness automatically. It is on my list but I have not
managed to get round to it so far.

Colin

You may be interested in the _before_type_cast accessor - that will
let you read whatever the DB is actually returning.

I'm somewhat curious what makes sense for a dateless, zoneless time.
Either the app that consumes the data is *assuming* the missing info
(hard to do, as even time comparisons get nasty across DST boundaries)
or the data is (maybe?) some kind of elapsed time.

--Matt Jones

What time do you normally wake up? 7:00 would be one answer :slight_smile:
No date or TZ associated with that...

Hassan Schroeder wrote:

I'm somewhat curious what makes sense for a dateless, zoneless time.

What time do you normally wake up? 7:00 would be one answer :slight_smile:
No date or TZ associated with that...

I don't really think I agree. When I go to sleep tonight, I will get up
at 7:30 a.m. Eastern Time (not Pacific or Central European), on Tuesday
14 July 2009 (not Wednesday 15 July).

--
Hassan Schroeder

Best,

"what time will you get up tomorrow" and "what time do you typically
get up" seem pretty obviously different to me... :slight_smile:

Hassan Schroeder wrote:
[...]

"what time will you get up tomorrow" and "what time do you typically
get up" seem pretty obviously different to me... :slight_smile:

True. But even here, there's a time zone. If I get up at 7:30 Pacific
Time tomorrow instead of 7:30 Eastern Time, I will miss my appointments.
If I get up at 7:30 Central European Time, I'll be extremely tired from
getting only about 3 hours of sleep. A time without a time zone is 100%
meaningless.

--
Hassan Schroeder

Best,

And that's 100% silly. If I say that I typically get up at 7:00, it's totally
irrelevant where I am. I get up at 7 in San Jose. I get up at 7 in New
York. I get up at 7 in Frankfurt. I get up at 7 in Ubud. It's 7 hours after
midnight wherever I happen to be.

There is utterly no "time zone" component to the concept (and use
case) I'm talking about.

Hassan Schroeder wrote:
[...]

And that's 100% silly. If I say that I typically get up at 7:00, it's
totally
irrelevant where I am. I get up at 7 in San Jose. I get up at 7 in New
York. I get up at 7 in Frankfurt. I get up at 7 in Ubud. It's 7 hours
after
midnight wherever I happen to be.

Yes -- *wherever you happen to be*. Not in some other time zone.

There is utterly no "time zone" component to the concept (and use
case) I'm talking about.

There absolutely is a time zone component -- namely, the local time
zone. This would be like saying (in Rubyish pseudocode:

@hassan.set_alarm(Time.new(:hour => 7, :minute => 0, :zone =>
DEFAULT_TIME_ZONE))
# I know Time.new's syntax is not like this -- just trying for clarity.

A clock time cannot be a useful without a time zone -- even if that time
zone is set to a sensible default, it's still *there*.

Best,

Gah. I give up. That's like saying you can't discuss the abstract idea
of "pancakes" without specifying the meal they will be (or were) eaten
at.

Sorry you can't visualize the use case of an *abstract* time of day.

But whatever.

It might, but it isn't to me, and it *isn't the use case I described*.

"What time do you typically get up?" How simple is that?

Build me a survey form, collect the responses, calculate average,
mean, do whatever desired statistical analysis, on data in the range
of 00:00 to 23:59.

But there is not *any* time zone info associated with that. Period.
It simply isn't part of the question. Utterly, totally, irrelevant.

Hassan Schroeder wrote:

I do understand that it might be useful to do

@hassan.set_alarm_clock(AbstractTime.new(:hour => 7, :minute => 0))

It might, but it isn't to me, and it *isn't the use case I described*.

"What time do you typically get up?" How simple is that?

Build me a survey form, collect the responses, calculate average,
mean, do whatever desired statistical analysis, on data in the range
of 00:00 to 23:59.

Yes, that would be a perfect candidate for AbstractTime...now I
understand your use case! (Though to me, at least, it's nearly
equivalent to the use case I described with the alarm.)

But there is not *any* time zone info associated with that. Period.
It simply isn't part of the question. Utterly, totally, irrelevant.

In this use case, you are quite right about that. Thanks for the
explanation.

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
twitter: @hassan

Best,

Many use cases for a TimeOfDay do imply or require a time zone, some
uses cases do not, but there are certainly many use cases for
TimeOfDay where the Date is irrelevant. It is the fact that a db Time
object maps to a DateTime in Rails and then we have to mess about
explicitly ignoring the Date part that is the key annoyance for me.

Colin

But there are definitely use cases where the time zone is NOT
inherently part of the time value.

I've spent quite a bit of time looking at things like this in
implementing ri_cal. One set of use cases comes from the various ways
RFC 2445 allows date/date-time values to be represented in icalendar
data.

It may be expressed in UTC or Zulu time. For example within an event
might have its start time specified by:
   DTSTART:200907T1100000Z

It may be expressed with a specific local time zone e.g.
   DTSTART;TZID=America/New_York:200907T14070000

It may be expressed with a floating time zone
  DTSTART:20090714T070000

In this last case the actual time is determined by having the time
zone supplied by the user or the user's calendar application,
presumably that will be the user's local time zone.

Uses for floating times might be to represent when the beginning of
the New Year is celebrated, which tends to happen at xxxx0101T000000

or midnight at the beginning of 1 January in each local time zone.

Or expressing that I wake up, or try to, at 7:00 a.m. in whatever time
zone I happen to find my body in.

The last RFC value for a time attribute is just a date e.g.
DTSTART:20090714 which is inherently floating with respect to time
zone.

That said, this discussion has been ignoring the fact that a time
might not represent a time of day, but can in certain cases represent
a duration, and there are differing standards on representing these.

RFC2445 has a period value which represents a signed time duration,
which can have week, day, hour, minute and second parts.

The Duration class in ActiveSupport is similar, it represents a signed
period with the same parts as are defined for Time#advance, years,
months, days, hours, minutes, and seconds. But as far as I can tell,
this really isn't surfaced very well, in rails durations are pretty
much used as temporary results in time calculations.

And some SQL implementations, MySQL for one, have time values which
are really durations with hour, minute, and second parts. MySql allows
such a time to represent periods longer than a day, so 132:20:00 is a
valid time, although it would be a lousy time of day, except perhaps
for Bill Murray's character in Ground Hog Day to use.

I asked a similar question on #jruby yesterday and got the answer that
all times have a date/TZ component.

I'm developing a running log and need *only* hh:mm:ss (no TZ or date
component) to store the time taken to run a particular distance. AIU,
there is no clean solution and so using datetime and then masking
date.

Is there something better ?

-Arun