Time interval

Discussion in 'Ruby' started by Daniel Berger, Sep 26, 2005.

  1. Hi all,

    I was just wondering if anyone has implemented an "Interval" class of some sort
    out there, i.e. something that would give you the years, months, days, hours,
    minutes and seconds between two fixed DateTime objects, rather than an absolute
    date.

    I see that Gavin Sinclair brought this issue up a couple times last year
    (ruby-talk:95236, ruby-talk:103601), but I didn't see any sort of package on
    the RAA.

    I had something of my own with "fixed-time" but it doesn't handle Date, Time or
    DateTime objects (i.e. it needs a major makeover). Before I do that, though, I
    wanted to see if anyone out there (Gavin?) already had something out there,
    sitting on their hard drive, but unreleased.

    Regards,

    Dan

    PS - I'm very confused by the current implementation of "-" (minus) for Date
    and DateTime, where the returned value is a Rational. Can someone elaborate on
    how this is used?
    Daniel Berger, Sep 26, 2005
    #1
    1. Advertising

  2. Daniel Berger

    Trans Guest

    I don't know of any specific DataTimeInterval, but Mega has two things
    that might help:

    require 'mega/interval'
    require 'mega/time_in_english'

    t= Time.now
    i = Interval[ t, t + 5.days ]
    => #<Interval:0xb7aefde8 @last=Sat Oct 01 14:15:28 EDT 2005,
    @direction=1, @first=Mon Sep 26 14:15:28 EDT 2005, @exclude_last=false,
    @exclude_first=false>

    i.distance / 1.days
    => 5.0

    HTH.

    Hmm... who's wants to put together a generic Delta delgator class?

    T.
    Trans, Sep 26, 2005
    #2
    1. Advertising

  3. On Mon, 26 Sep 2005 18:55:51 +0100, Daniel Berger
    <> wrote:

    > Hi all,
    >
    > I was just wondering if anyone has implemented an "Interval" class of
    > some sort out there, i.e. something that would give you the years,
    > months, days, hours, minutes and seconds between two fixed DateTime
    > objects, rather than an absolute date.
    >

    Doesn't Rails Active Support porvide .ago, .since, .years_since, .from_now
    etc? Any use?
    Graham
    Graham Foster, Sep 26, 2005
    #3
  4. Daniel Berger <> wrote:
    > Hi all,
    >
    > I was just wondering if anyone has implemented an "Interval" class of
    > some sort out there, i.e. something that would give you the years,
    > months, days, hours, minutes and seconds between two fixed DateTime
    > objects, rather than an absolute date.


    Note that it's easy to output difference in seconds, minutes, hours, days
    and weeks but then it starts to get more difficult.

    I once cooked up something albeit in Java that takes two arrays (an array
    with factors and an array with unit names) and a value and constructs a
    string from that. Untested:

    def create_units(val, factors, units)
    raise "mismatch" unless factors.size == units.size

    r = []

    factors.zip(units) do |f,u|
    v = val % f
    r << "#{val} #{v}" if v != 0
    val = (val - v) / f
    end

    r.reverse!
    r.join " "
    end

    Kind regards

    robert
    Robert Klemme, Sep 26, 2005
    #4
  5. Robert Klemme wrote:
    > Daniel Berger <> wrote:
    >
    >> Hi all,
    >>
    >> I was just wondering if anyone has implemented an "Interval" class of
    >> some sort out there, i.e. something that would give you the years,
    >> months, days, hours, minutes and seconds between two fixed DateTime
    >> objects, rather than an absolute date.

    >
    >
    > Note that it's easy to output difference in seconds, minutes, hours,
    > days and weeks but then it starts to get more difficult.


    You mean with the existing DateTime class? How? I thought this was possible,
    but my Google skills appear to be failing me at the moment. My own experiments
    weren't much better.

    Regards,

    Dan
    Daniel Berger, Sep 26, 2005
    #5
  6. Daniel Berger wrote:
    > Robert Klemme wrote:
    >> Daniel Berger <> wrote:
    >>
    >>> Hi all,
    >>>
    >>> I was just wondering if anyone has implemented an "Interval" class
    >>> of some sort out there, i.e. something that would give you the
    >>> years, months, days, hours, minutes and seconds between two fixed
    >>> DateTime objects, rather than an absolute date.

    >>
    >>
    >> Note that it's easy to output difference in seconds, minutes, hours,
    >> days and weeks but then it starts to get more difficult.

    >
    > You mean with the existing DateTime class? How? I thought this was
    > possible, but my Google skills appear to be failing me at the moment.
    > My own experiments weren't much better.


    No, I mean because of the underlying model (our calendar). Months have
    different lengths. Same for years and quarters.

    Kind regards

    robert
    Robert Klemme, Sep 27, 2005
    #6
  7. On Sep 27, 2005, at 2:51 AM, Robert Klemme wrote:
    > Daniel Berger wrote:
    >> Robert Klemme wrote:
    >>> Note that it's easy to output difference in seconds, minutes, hours,
    >>> days and weeks but then it starts to get more difficult.

    >> You mean with the existing DateTime class? How? I thought this was
    >> possible, but my Google skills appear to be failing me at the moment.
    >> My own experiments weren't much better.

    > No, I mean because of the underlying model (our calendar). Months
    > have
    > different lengths. Same for years and quarters.


    For example:

    require 'date'
    d1 = DateTime.parse( "2/1/2000" )
    d2 = DateTime.parse( "3/2/2000" )
    puts d2-d1 #=> 30

    Should the human-readable difference in that time say:
    1 month, 1 day
    30 days
    1 month
    ?

    How about:
    d1 = DateTime.parse( "2/1/2000" )
    d2 = DateTime.parse( "2/1/2001" )
    d3 = DateTime.parse( "2/1/2002" )
    puts d2-d1 #=> 366
    puts d3-d2 #=> 365

    Should those both say "1 year", or "1 year, 1 day" for the first?

    If you standardize and say "All 'months' are 30 days long, all
    'years' are 365 days" then you can run into situations like the above
    where the obvious difference to a human is different from the
    computed difference. This only falls down when you try to go beyond
    weeks; if all your time intervals are short enough that formatting
    them as "3 weeks, 4 days, 5 hours, 27 minutes" is acceptable enough,
    then you're good to go.

    Alternatively, you need to keep year/month/date information along
    with the endpoints of your interval, and do piecewise differencing.
    Gavin Kistner, Sep 27, 2005
    #7
  8. Daniel Berger

    Pit Capitain Guest

    Gavin Kistner schrieb:
    > On Sep 27, 2005, at 2:51 AM, Robert Klemme wrote:
    >>
    >> No, I mean because of the underlying model (our calendar). Months have
    >> different lengths. Same for years and quarters.

    >
    > For example:
    >
    > require 'date'
    > d1 = DateTime.parse( "2/1/2000" )
    > d2 = DateTime.parse( "3/2/2000" )
    > puts d2-d1 #=> 30
    >
    > Should the human-readable difference in that time say:
    > 1 month, 1 day
    > 30 days
    > 1 month
    > ?
    >
    > How about:
    > d1 = DateTime.parse( "2/1/2000" )
    > d2 = DateTime.parse( "2/1/2001" )
    > d3 = DateTime.parse( "2/1/2002" )
    > puts d2-d1 #=> 366
    > puts d3-d2 #=> 365
    >
    > Should those both say "1 year", or "1 year, 1 day" for the first?
    >
    > If you standardize and say "All 'months' are 30 days long, all 'years'
    > are 365 days" then you can run into situations like the above where the
    > obvious difference to a human is different from the computed
    > difference. This only falls down when you try to go beyond weeks; if
    > all your time intervals are short enough that formatting them as "3
    > weeks, 4 days, 5 hours, 27 minutes" is acceptable enough, then you're
    > good to go.
    >
    > Alternatively, you need to keep year/month/date information along with
    > the endpoints of your interval, and do piecewise differencing.


    Recently I've been representing time intervals by two numbers: months
    and seconds. With this representation it is possible to differentiate
    between "1 year" and "365 days":

    1 year = 12 months (and 0 seconds)
    365 days = (0 months and) 365 * 24 * 60 * 60 seconds

    Regards,
    Pit
    Pit Capitain, Sep 27, 2005
    #8
  9. On Sep 27, 2005, at 7:19 AM, Pit Capitain wrote:
    > Recently I've been representing time intervals by two numbers:
    > months and seconds. With this representation it is possible to
    > differentiate between "1 year" and "365 days":
    >
    > 1 year = 12 months (and 0 seconds)
    > 365 days = (0 months and) 365 * 24 * 60 * 60 seconds


    While precise, I claim that that's not very human-friendly.

    "How long ago did I receive this email?"
    "20160 seconds"
    "Whaaaa? Is that long or short?"
    "Er, I meant 2 weeks"
    "Oh, thanks."
    Gavin Kistner, Sep 27, 2005
    #9
  10. Daniel Berger

    Randy Kramer Guest

    On Tuesday 27 September 2005 04:51 am, Robert Klemme wrote:
    > No, I mean because of the underlying model (our calendar). Months have
    > different lengths. Same for years and quarters.


    Two thoughts, which I don't know whether will help or hurt (may be useful
    approximations?):

    * (I guess this is the furthest off point): There seems to be an at least
    "semi-official" designation of the weeks in a year--you will find some
    calendars that number the weeks, and when I've checked, those numbers seem to
    be consistent between calendars, even made in different countries. (I think
    the ones I've noticed, some years ago, were calendars from England, Austria,
    and the US.)

    * Depending on the level of precision I wanted, I might calculate an
    interval in weeks, then consider 4 1/3 weeks ~= 1 month, 13 weeks ~= 1
    quarter, and 52 weeks = 1 year. If I wanted to express some arbitrary number
    of weeks in months, (e.g., 62, I'd divide by 4.34 and round off to the
    nearest integer and call it that number of months.

    Nope, I take that back. I'd more likely just express the difference between
    say, Jan 3rd and Dec 15 as the difference in months then the difference in
    days, i.e., 11 months, 12 days. (and I'd approximate that as either 11, 11
    1/2, or 11 months, 2 weeks).

    If I wanted to express that in weeks, I guess my two choices would be to use
    the semi-official designation of weeks (first bullet above) and get the
    number of weeks by the difference in week numbers, and then depending on the
    days of the week, approximate it to the nearest 1/2 (or actual number of
    days).

    Or, calculate the actual difference in days, then divide by 7, call that
    weeks, and the remainder in days (or rounded off to, say, 1/2 week.

    Do others see the need for other approaches?

    Randy Kramer
    Randy Kramer, Sep 27, 2005
    #10
  11. Daniel Berger

    Pit Capitain Guest

    Gavin Kistner schrieb:
    > On Sep 27, 2005, at 7:19 AM, Pit Capitain wrote:
    >
    >> Recently I've been representing time intervals by two numbers: months
    >> and seconds. With this representation it is possible to differentiate
    >> between "1 year" and "365 days":
    >>
    >> 1 year = 12 months (and 0 seconds)
    >> 365 days = (0 months and) 365 * 24 * 60 * 60 seconds

    >
    > While precise, I claim that that's not very human-friendly.
    >
    > "How long ago did I receive this email?"
    > "20160 seconds"
    > "Whaaaa? Is that long or short?"
    > "Er, I meant 2 weeks"
    > "Oh, thanks."


    Huh? I'm sure you know the difference between obj and obj.to_s.

    I use those two number representation to be able to add intervals like
    "1 month" to timestamps. You seem to need a string representation of
    time intervals, which is a different task.

    Regards,
    Pit
    Pit Capitain, Sep 27, 2005
    #11
  12. Daniel Berger

    Phrogz Guest

    I understand; you're talking about internal representation, while I'm
    talking about what (I think) the OP was talking about - a
    human-sensible representation of the interval.

    Quoth the OP:
    > I was just wondering if anyone has implemented an "Interval" class of some sort
    > out there, i.e. something that would give you the years, months, days, hours,
    > minutes and seconds between two fixed DateTime objects, rather than an absolute
    > date.
    Phrogz, Sep 27, 2005
    #12
  13. Gavin Kistner wrote:
    > On Sep 27, 2005, at 2:51 AM, Robert Klemme wrote:
    >
    >> Daniel Berger wrote:
    >>
    >>> Robert Klemme wrote:
    >>>
    >>>> Note that it's easy to output difference in seconds, minutes, hours,
    >>>> days and weeks but then it starts to get more difficult.
    >>>
    >>> You mean with the existing DateTime class? How? I thought this was
    >>> possible, but my Google skills appear to be failing me at the moment.
    >>> My own experiments weren't much better.

    >>
    >> No, I mean because of the underlying model (our calendar). Months have
    >> different lengths. Same for years and quarters.

    >
    >
    > For example:
    >
    > require 'date'
    > d1 = DateTime.parse( "2/1/2000" )
    > d2 = DateTime.parse( "3/2/2000" )
    > puts d2-d1 #=> 30
    >
    > Should the human-readable difference in that time say:
    > 1 month, 1 day
    > 30 days
    > 1 month
    > ?


    I wouldn't try to get more specific than *days*. :)

    Regards,

    Dan
    Daniel Berger, Sep 27, 2005
    #13
  14. Daniel Berger

    xmlblog Guest

    While not in Ruby, I recently created a DateTime / Interval library in
    Javascript based on the same ideas you've all been tossing around in
    here. Ultimately, the language has very little impact on the design
    questions that have been raised and there are some surprises in working
    with dates as well.

    When I wrote the Date Extras Javascript Library, I initially took the
    approach of setting 30 days approx. = 1 month, 365 days approx = 1 year
    (based on what I saw in Rails). But IMO the methods in Rails weren't
    designed with the goal of high fidelity to the actual time. It seems to
    me that they were designed to enable cool things like
    time_ago_in_words.

    In reality, chasing down accuracy in a general purpose Date library is
    not an easy task. Subtle design choices like what time of day is
    Date.parse("12/1/2005") have big implications depending on the
    application. In Date Extras I chose noon as the default time for some
    methods because it made generating a calendar simpler.
    Consider that doing something like this:
    365.times do |i|
    puts Date.today.add_days(i)
    end
    will produce unintended results due to daylight savings time if
    Date.today returns a date with 0 hours, minutes, seconds, and
    milliseconds. Using a time like 12 Noon was easy because the clocks
    tend to change at 1 or 2 in the morning.

    I'll finish up by throwing an idea out there for the Interval
    implementation and verturing an answer to the question of why date
    subtraction yields a Rational. In JS, subtrating dates yields their
    difference in milliseconds. This is because JS measures time as a
    millisecond offset from 1/1/1970. To make my life easier, I created a
    TimeSpan class whose initializer accepts milliseconds and provides
    convenience properties to access that same interval in different
    granularities. I also chose to use the absolute value of the
    milliseconds in case the client code accidentally reversed the dates,
    plus some might think it looks more natural to write:

    elvis_lived = TimeSpan.new(Date.new("1/8/1935") -
    Date.new("8/16/1977")).days

    Anyway, if you're inclined to look at the library you can find it here:
    http://www.xml-blog.com/articles/2005/09/19/date-extras-javascript-library-part-ii

    Comments, suggestions, (flames?) welcome.
    xmlblog, Sep 27, 2005
    #14
  15. Daniel Berger

    Pit Capitain Guest

    Phrogz schrieb:
    > I understand; you're talking about internal representation, while I'm
    > talking about what (I think) the OP was talking about - a
    > human-sensible representation of the interval.


    Yeah, that's right. I wasn't responding to the OP, but to Robert (I
    think) who talked about some problems with time intervals like "1 month"
    because of the varying length of months.

    Regards,
    Pit
    Pit Capitain, Sep 27, 2005
    #15
  16. --------------010508030200020505080006
    Content-Type: text/plain; charset=ISO-8859-1; format=flowed
    Content-Transfer-Encoding: 7bit

    Daniel Berger wrote:

    > Hi all,
    >
    > I was just wondering if anyone has implemented an "Interval" class of
    > some sort out there, i.e. something that would give you the years,
    > months, days, hours, minutes and seconds between two fixed DateTime
    > objects, rather than an absolute date.
    >
    > I see that Gavin Sinclair brought this issue up a couple times last
    > year (ruby-talk:95236, ruby-talk:103601), but I didn't see any sort of
    > package on the RAA.
    >
    > I had something of my own with "fixed-time" but it doesn't handle
    > Date, Time or DateTime objects (i.e. it needs a major makeover).
    > Before I do that, though, I wanted to see if anyone out there (Gavin?)
    > already had something out there, sitting on their hard drive, but
    > unreleased.
    >
    > Regards,
    >
    > Dan
    >
    > PS - I'm very confused by the current implementation of "-" (minus)
    > for Date and DateTime, where the returned value is a Rational. Can
    > someone elaborate on how this is used?
    >


    You may wish to look into Runt - http://raa.ruby-lang.org/project/runt/

    From the description:

    Runt is an implementation of select temporal patterns by Martin
    Fowler in the super-fantastic Ruby language. Runt provides:

    * recurring events defined using simple, set-like expressions
    * an API for creating schedules for arbitrary events/objects
    * precisioned date types using Time Points
    * date Ranges
    * everlasting peace and/or eternal life


    -Justin

    --------------010508030200020505080006--
    Justin Collins, Sep 27, 2005
    #16
  17. Daniel Berger

    Dave Howell Guest

    On Sep 27, 2005, at 6:58, Randy Kramer wrote:

    > On Tuesday 27 September 2005 04:51 am, Robert Klemme wrote:
    >> No, I mean because of the underlying model (our calendar). Months
    >> have
    >> different lengths. Same for years and quarters.

    >
    > Two thoughts, which I don't know whether will help or hurt (may be
    > useful
    > approximations?):
    >
    >
    > * Depending on the level of precision I wanted, I might calculate an
    > interval in weeks, then consider 4 1/3 weeks ~= 1 month, 13 weeks ~= 1
    > quarter, and 52 weeks = 1 year. If I wanted to express some arbitrary
    > number
    > of weeks in months, (e.g., 62, I'd divide by 4.34 and round off to the
    > nearest integer and call it that number of months.
    >
    > Nope, I take that back. I'd more likely just express the difference
    > between
    > say, Jan 3rd and Dec 15 as the difference in months then the
    > difference in
    > days, i.e., 11 months, 12 days. (and I'd approximate that as either
    > 11, 11
    > 1/2, or 11 months, 2 weeks).


    [text deleted]

    > Do others see the need for other approaches?



    There is no "answer" to this problem because the correct usage is
    tremendously context sensitive.

    There are 58 shopping days until Christmas.

    The convention is in 8 weeks. (58 days = 8.2 weeks)

    Your work on the Monster House must be complete in 2 days, 12 hours, 14
    minutes, and 34.5 seconds.

    The Date class (if I recall correctly) uses Days and fractions of Days
    for the internal representation, and lets you access a variety of
    interval measures. Which ones you use will depend very much on what
    kind of events you're measuring the distance between.
    Dave Howell, Sep 28, 2005
    #17
  18. Daniel Berger

    Randy Kramer Guest

    On Tuesday 27 September 2005 08:18 pm, Dave Howell wrote:
    > On Sep 27, 2005, at 6:58, Randy Kramer wrote:
    > > On Tuesday 27 September 2005 04:51 am, Robert Klemme wrote:
    > >> No, I mean because of the underlying model (our calendar). Months
    > >> have
    > >> different lengths. Same for years and quarters.

    > [text deleted]
    >
    > > Do others see the need for other approaches?

    >
    > There is no "answer" to this problem because the correct usage is
    > tremendously context sensitive.


    Thanks, you're right!

    > There are 58 shopping days until Christmas.
    >
    > The convention is in 8 weeks. (58 days = 8.2 weeks)
    >
    > Your work on the Monster House must be complete in 2 days, 12 hours, 14
    > minutes, and 34.5 seconds.


    Good examples.

    Randy Kramer

    > The Date class (if I recall correctly) uses Days and fractions of Days
    > for the internal representation, and lets you access a variety of
    > interval measures. Which ones you use will depend very much on what
    > kind of events you're measuring the distance between.
    Randy Kramer, Sep 28, 2005
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dica
    Replies:
    0
    Views:
    409
  2. Wes Harrison

    Measuring a short interval in time

    Wes Harrison, Sep 14, 2004, in forum: Java
    Replies:
    2
    Views:
    579
    Paul Lutus
    Sep 14, 2004
  3. Graeme Longman
    Replies:
    1
    Views:
    302
    Waldemar Osuch
    Aug 4, 2004
  4. Replies:
    2
    Views:
    325
  5. Andrew Poulos

    'point in time' time interval

    Andrew Poulos, Jun 14, 2005, in forum: Javascript
    Replies:
    4
    Views:
    252
    Andrew Poulos
    Jun 15, 2005
Loading...

Share This Page