What a mess: Date, milliseconds, GregorianCalendar

Discussion in 'Java' started by Erwin Moller, Aug 19, 2004.

  1. Erwin Moller

    Erwin Moller Guest

    Hi group,

    (Sorry for complaining)
    Is it just me or do dates, milliseconds, GregorianCalendar completely
    confusing?

    I needed to build a simple JSP that displays a simple countdown for an
    election.
    It should show how many days untill elections start.
    During elections it should show how many days are left to vote, and when the
    election closingdate is over it should say: elections are passed.

    This took me 4 hours and a lot of frustration. the API wasn't really a help
    either.
    I came up with the following huge script. (at the end)
    I code such things in PHP on 3 lines...

    I was just wondering: Am I missing something completely or is working with
    dates really confusing?
    (Like the double getTime().getTime() constructions.)

    What is your experience?

    Thanks for your time.
    And again, sorry for the ranting.
    I love working with Java, but the Date-related logic just isn't compatible
    with my brains. :-(

    Regards,
    Erwin Moller


    -------------------


    <%@ page import="java.util.Date" %>
    <%@ page import="java.util.Calendar" %>
    <%@ page import="java.text.SimpleDateFormat" %>
    <%@ page import="java.util.Date" %>
    <%@ page import="java.util.Calendar" %>
    <%@ page import="java.util.GregorianCalendar" %>
    <%
    // this file represents a countdontcounter

    // We have 2 dates:
    // startElectionDate = startdate of elections
    // endElectionDate = enddate of elections

    // format them: (yyyy,mm,dd)
    // warning, month is 0 based! 0 = januari, 1 = februari
    GregorianCalendar startElectionGregorianCalendar = new
    GregorianCalendar(2004, 7 , 2);
    GregorianCalendar endElectionGregorianCalendar = new
    GregorianCalendar(2004, 8, 1);

    GregorianCalendar nowGregorianCalendar = new GregorianCalendar();

    long mssecInADay = (1000*60*60*24);

    // if <0 already passed
    double dDaysToStartDate = (double)
    (startElectionGregorianCalendar.getTime().getTime() -
    nowGregorianCalendar.getTime().getTime()) / mssecInADay;

    // if <0 already passed
    double dDaysToEndDate = (double)
    (endElectionGregorianCalendar.getTime().getTime() -
    nowGregorianCalendar.getTime().getTime()) / mssecInADay;

    String strDisplay = "";
    if (dDaysToStartDate >0){
    strDisplay = ""+dDaysToStartDate+" days untill elections.";
    } else {
    if (dDaysToEndDate >0) {
    strDisplay = "Elections running. you have "+dDaysToEndDate+" days
    to vote left.";
    } else {
    strDisplay = "Voting is over.";
    }
    }
    %>
    <!-- Start countdown -->
    <%= strDisplay %>
    <!-- End countdown -->
     
    Erwin Moller, Aug 19, 2004
    #1
    1. Advertising

  2. Erwin Moller

    Jacob Guest

    Erwin Moller wrote:

    > (Sorry for complaining)
    > Is it just me or do dates, milliseconds, GregorianCalendar completely
    > confusing?


    You're allowed to complain!

    It's not a mess as it contains a lot of complex logic to handle
    the complicated world of calendars, days and time, but the API
    is not suitable for the many simple cases like yours.

    The main problem (I think) is that dates and times are mixed into
    the same class: java.util.Date. It is difficult to work with *dates*
    without getting into all kind of time issues.

    You can look at http://geosoft.no/software/day/Day.java.html
    where only the *day* part of a calendar is exposed, and a set of
    simple date arithmetic methods like you requests has been included.
     
    Jacob, Aug 19, 2004
    #2
    1. Advertising

  3. Erwin Moller

    Paul Lutus Guest

    Erwin Moller wrote:

    > Hi group,
    >
    > (Sorry for complaining)
    > Is it just me or do dates, milliseconds, GregorianCalendar completely
    > confusing?


    It is calendars that are confusing. The classes that deal with this topic
    merely reflect the true complexity of human calendars.

    >
    > I needed to build a simple JSP that displays a simple countdown for an
    > election.
    > It should show how many days untill elections start.
    > During elections it should show how many days are left to vote, and when
    > the election closingdate is over it should say: elections are passed.
    >
    > This took me 4 hours and a lot of frustration. the API wasn't really a
    > help either.
    > I came up with the following huge script. (at the end)
    > I code such things in PHP on 3 lines...
    >
    > I was just wondering: Am I missing something completely or is working with
    > dates really confusing?


    Yes. :)

    > (Like the double getTime().getTime() constructions.)
    >
    > What is your experience?


    Here's my experience (not really that different from your own):

    // CalendarCountdown.java

    import java.util.GregorianCalendar;

    public class CalendarCountdown {

    public static void main(String args[])
    {
    final long millisToDays = 86400000;
    GregorianCalendar today = new GregorianCalendar();
    // remember: months are numbered 0 - 11 in this class
    // GregorianCalendar(year, month-1, day of month)
    GregorianCalendar electionDay = new GregorianCalendar(2004,10,15);
    long days = (electionDay.getTimeInMillis() - today.getTimeInMillis())
    / millisToDays;
    String s = (days > 0)?"It is " + days + " days until election day."
    :(days == 0)?"Election day is today."
    :"Election day has passed.";
    System.out.println(s);

    }
    }

    --
    Paul Lutus
    http://www.arachnoid.com
     
    Paul Lutus, Aug 19, 2004
    #3
  4. Erwin Moller

    Paul Lutus Guest

    Jacob wrote:

    > Erwin Moller wrote:
    >
    >> (Sorry for complaining)
    >> Is it just me or do dates, milliseconds, GregorianCalendar completely
    >> confusing?

    >
    > You're allowed to complain!
    >
    > It's not a mess as it contains a lot of complex logic to handle
    > the complicated world of calendars, days and time, but the API
    > is not suitable for the many simple cases like yours.
    >
    > The main problem (I think) is that dates and times are mixed into
    > the same class: java.util.Date.


    That is not a problem, as most of Date has been deprecated, and it appears
    people are being advised to avoid Date for now projects.

    --
    Paul Lutus
    http://www.arachnoid.com
     
    Paul Lutus, Aug 19, 2004
    #4
  5. Erwin Moller

    Jacob Guest

    Paul Lutus wrote:
    > Jacob wrote:
    >
    >
    >>Erwin Moller wrote:
    >>
    >>
    >>>(Sorry for complaining)
    >>>Is it just me or do dates, milliseconds, GregorianCalendar completely
    >>>confusing?

    >>
    >>You're allowed to complain!
    >>
    >>It's not a mess as it contains a lot of complex logic to handle
    >>the complicated world of calendars, days and time, but the API
    >>is not suitable for the many simple cases like yours.
    >>
    >>The main problem (I think) is that dates and times are mixed into
    >>the same class: java.util.Date.

    >
    >
    > That is not a problem, as most of Date has been deprecated, and it appears
    > people are being advised to avoid Date for now projects.


    java.util.Date as such is not deprecated (as I know of),
    though many of its access functions are.
    And I am not sure using a GregorianCalendar instead
    improves matters? :)
     
    Jacob, Aug 19, 2004
    #5
  6. Erwin Moller

    Paul Lutus Guest

    Jacob wrote:

    / ...

    >> That is not a problem, as most of Date has been deprecated, and it
    >> appears people are being advised to avoid Date for now projects.

    >
    > java.util.Date as such is not deprecated (as I know of),
    > though many of its access functions are.


    Because so many of Date's methods are deprecated (23 altogether), that's
    saying the same thing.

    > And I am not sure using a GregorianCalendar instead
    > improves matters? :)


    Yes, of course it does. GregorianCalendar was written to address the
    deficiencies in Date. Unless by "matters" you mean making things simpler
    for the programmer.

    --
    Paul Lutus
    http://www.arachnoid.com
     
    Paul Lutus, Aug 19, 2004
    #6
  7. Erwin Moller wrote:

    > I was just wondering: Am I missing something completely or is working with
    > dates really confusing?
    > (Like the double getTime().getTime() constructions.)
    >
    > What is your experience?


    Java's date/time API are confusing, inconsistent, and sometimes
    counter-intuitive. I have found that the API docs do help me, but they
    can't solve the underlying problem that the API themselves are not well
    designed. The API and docs can be used fairly easily once one has
    become familiar with them, however.

    > <%@ page import="java.util.Date" %>
    > <%@ page import="java.util.Calendar" %>
    > <%@ page import="java.text.SimpleDateFormat" %>
    > <%@ page import="java.util.Date" %>
    > <%@ page import="java.util.Calendar" %>
    > <%@ page import="java.util.GregorianCalendar" %>


    You import Date and Calendar twice, but don't explicitly use either one.
    You import SimpleDateFormat but don't use it at all. You only need
    the last (GregorianCalendar) import.

    > <%
    > // this file represents a countdontcounter
    >
    > // We have 2 dates:
    > // startElectionDate = startdate of elections
    > // endElectionDate = enddate of elections
    >
    > // format them: (yyyy,mm,dd)
    > // warning, month is 0 based! 0 = januari, 1 = februari
    > GregorianCalendar startElectionGregorianCalendar = new
    > GregorianCalendar(2004, 7 , 2);
    > GregorianCalendar endElectionGregorianCalendar = new
    > GregorianCalendar(2004, 8, 1);


    Your code would be clearer (and you wouldn't need the warning comment)
    if you used the month number static constants declared in Calendar
    instead of plain int arguments.

    > GregorianCalendar nowGregorianCalendar = new GregorianCalendar();


    You only use that calendar to get the current time, so you could just as
    well say:

    long now = System.currentTimeMillis();

    > long mssecInADay = (1000*60*60*24);
    >
    > // if <0 already passed
    > double dDaysToStartDate = (double)
    > (startElectionGregorianCalendar.getTime().getTime() -
    > nowGregorianCalendar.getTime().getTime()) / mssecInADay;


    Instead of .getTime().getTime() you might want to use .getTimeInMillis()

    > // if <0 already passed
    > double dDaysToEndDate = (double)
    > (endElectionGregorianCalendar.getTime().getTime() -
    > nowGregorianCalendar.getTime().getTime()) / mssecInADay;
    >
    > String strDisplay = "";
    > if (dDaysToStartDate >0){
    > strDisplay = ""+dDaysToStartDate+" days untill elections.";
    > } else {
    > if (dDaysToEndDate >0) {
    > strDisplay = "Elections running. you have "+dDaysToEndDate+" days
    > to vote left.";
    > } else {
    > strDisplay = "Voting is over.";
    > }
    > }
    > %>
    > <!-- Start countdown -->
    > <%= strDisplay %>
    > <!-- End countdown -->


    My earlier comments notwithstanding, that doesn't seem particularly big
    or complicated.


    John Bollinger
     
    John C. Bollinger, Aug 19, 2004
    #7
  8. Paul Lutus wrote:
    > Jacob wrote:
    >
    >
    >>>That is not a problem, as most of Date has been deprecated, and it
    >>>appears people are being advised to avoid Date for now projects.

    >>
    >>java.util.Date as such is not deprecated (as I know of),
    >>though many of its access functions are.

    >
    >
    > Because so many of Date's methods are deprecated (23 altogether), that's
    > saying the same thing.
    >


    Actually it is not the same thing.

    As mentioned in the javadoc comments of the Date class, it is only the methods
    of Date that perform the conversion from/to the human readable year/month....
    (and the Locale specific stuff that takes care of TimeZones and daylight saving)
    that have been deprecated in favour of the Calendar class. For performing any
    relative time computations as what the OP wanted, Date is what he would really
    need to use. (The getTimeInMillis() function does use a Date object internally
    and is only a shortcut to calendar.getTime().getTime()).

    It is another matter that without the deprecated functions, the Date class is
    simply a wrapper around a longint - but it is certainly not deprecated, and its
    use is essential for several applications (like date formatting, SQL date/time
    functions etc)

    BK
     
    Babu Kalakrishnan, Aug 19, 2004
    #8
  9. Erwin Moller

    Paul Lutus Guest

    Babu Kalakrishnan wrote:

    > Paul Lutus wrote:
    >> Jacob wrote:
    >>
    >>
    >>>>That is not a problem, as most of Date has been deprecated, and it
    >>>>appears people are being advised to avoid Date for now projects.
    >>>
    >>>java.util.Date as such is not deprecated (as I know of),
    >>>though many of its access functions are.

    >>
    >>
    >> Because so many of Date's methods are deprecated (23 altogether), that's
    >> saying the same thing.
    >>

    >
    > Actually it is not the same thing.


    Because Date's remaining non-deprecated methods have some residual
    usefulness, I guess I agree. But if it were a deprecation Olypmpics, Date
    would lose (or win, depending on your outlook).

    --
    Paul Lutus
    http://www.arachnoid.com
     
    Paul Lutus, Aug 19, 2004
    #9
  10. Erwin Moller

    Chris Smith Guest

    Paul Lutus wrote:
    > Because Date's remaining non-deprecated methods have some residual
    > usefulness, I guess I agree. But if it were a deprecation Olypmpics, Date
    > would lose (or win, depending on your outlook).


    In my view, it's not so much that Date has remaining useful methods (it
    really doesn't do much versus long), but that it's used in the standard
    API as a marker that a parameter represents a date/time, versus some
    other kind of number. There's no indication that it's use as such
    should be discouraged in other code as well, and I consider it good form
    versus declaring a lot of parameters of type long, or certainly versus
    writing your own wrapper for a date/time to compensate.

    It speaks volumes, for example, that the replacement for all of that
    lost functionality of the Date class is now provided by classes that
    can't reasonable be used without Date (java.text.DateFormat and
    java.util.Calendar, for example).

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Aug 19, 2004
    #10
  11. Erwin Moller

    Paul Lutus Guest

    Chris Smith wrote:

    > Paul Lutus wrote:
    >> Because Date's remaining non-deprecated methods have some residual
    >> usefulness, I guess I agree. But if it were a deprecation Olypmpics, Date
    >> would lose (or win, depending on your outlook).

    >
    > In my view, it's not so much that Date has remaining useful methods (it
    > really doesn't do much versus long), but that it's used in the standard
    > API as a marker that a parameter represents a date/time, versus some
    > other kind of number.


    Yes, I should have mentioned that. It's the same issue with StringTokenizer,
    another class "in trouble" so to speak, but because of its presence in
    existing code, there can be no question of getting rid of it. It's the
    legacy issue.

    > There's no indication that it's use as such
    > should be discouraged in other code as well, and I consider it good form
    > versus declaring a lot of parameters of type long, or certainly versus
    > writing your own wrapper for a date/time to compensate.


    I concur, and I should have thought of the point you are making.

    > It speaks volumes, for example, that the replacement for all of that
    > lost functionality of the Date class is now provided by classes that
    > can't reasonable be used without Date (java.text.DateFormat and
    > java.util.Calendar, for example).


    Let's face it -- it's an inelegant but necessary repair job. It reminds me
    of the very annoying total overhaul of the handling of actions between (if
    memory serves) 1.0 and 1.1. The original scheme just wasn't thought out
    very well. Same with Date, and I have had to rewrite a lot of my early code
    to accommodate the changes in both cases (I always take "deprecated" to be
    a synonym for "remove or eventually lose").

    --
    Paul Lutus
    http://www.arachnoid.com
     
    Paul Lutus, Aug 20, 2004
    #11
  12. Erwin Moller

    P.Hill Guest

    John C. Bollinger wrote:
    > Erwin Moller wrote:
    >
    >> I was just wondering: Am I missing something completely or is working
    >> with dates really confusing?
    >> (Like the double getTime().getTime() constructions.)
    >>
    >> What is your experience?


    It is many things:
    1. Messy because our calendar is a real kludge.
    2. Messy because daylight savings adds another level of complexity.
    2. Date and Calendar contain some things inhereted from Unix date manipulation:
    0=January, the use of name getTime() to get the things which is actually a Date+Time
    3. You have to understand that Date IS still intended to be used to
    HOLD a binary time value while CALCULATIONS on dates are done with a
    calendar. One is a token pattern, the other a strategy pattern, but
    not entirely.

    4. java.util.Calendar is incomplete for many useful calculations.

    Given all that, it is no wonder you'd get it wrong and you did,
    particularly since you didn't try very many representative times
    to see if they work, because it breaks on some obvious ones.

    That is one reason you should not use scriptlets but instead
    write a class which returns the number of delta days. Then
    try the days right around the target date and see what happens.

    So first let's write a testable class using your algorithm.

    import java.util.Calendar;
    import java.util.GregorianCalendar;

    /**
    * @author Paul Hill
    * @since Aug 19, 2004
    */
    public class Election {
    private static final int MILLISECSPERDAY = (1000*60*60*24);
    private GregorianCalendar startElection;

    private GregorianCalendar endElection;

    public Election() {
    startElection = new GregorianCalendar(2004, Calendar.AUGUST, 2);
    endElection = new GregorianCalendar(2004, Calendar.SEPTEMBER, 1);
    }

    public String getDayStatement() {

    GregorianCalendar now = new GregorianCalendar();

    return getDayStatement(now);
    }

    public double getDaysToStart(GregorianCalendar now) {
    double dDaysToStartDate = (double)(startElection.getTime().getTime() -
    now.getTime().getTime()) / MILLISECSPERDAY;

    return dDaysToStartDate;
    }

    public double getDaysToEnd(GregorianCalendar now) {
    double dDaysToEndDate = (double)(endElection.getTime().getTime() -
    now.getTime().getTime()) / MILLISECSPERDAY;
    return dDaysToEndDate;
    }
    }

    **************************************************
    Then a JUnit class to test it. Just look at the 3 asserts at the bottom.
    **************************************************
    import junit.framework.TestCase;

    /**
    * @author Paul Hill
    * @since Aug 19, 2004
    */
    public class ElectionTest extends TestCase {
    public ElectionTest(String name) {
    super(name);
    }
    public static void main(String[] args) {
    junit.textui.TestRunner.run(ElectionTest.class);
    }

    public void testSomeDays( ) {
    Election e = new Election();
    assertEquals( 0d, e.getDaysToStart( new GregorianCalendar( 2004,
    Calendar.AUGUST, 2 )), 0.1d );
    assertEquals( 0d, e.getDaysToEnd( new GregorianCalendar( 2004,
    Calendar.SEPTEMBER, 1 )), 0.1d );
    /// sometime the day before
    assertEquals( 1d, e.getDaysToStart( new GregorianCalendar( 2004,
    Calendar.AUGUST, 1, 17, 0, 0 )), 0.1d );
    }
    }
    ***************************************************************************
    Boink! The third assert fails to find that a date in the evening the day before
    the election should be reported as 1 day to go. Instead I got:

    There was 1 failure:
    1) testSomeDays(ElectionTest)junit.framework.AssertionFailedError:
    expected:<1.0> but was:<0.2916666666666667>

    ****************************************************************************
    Why? Because you need to correctly convert to days to drop any fractions
    AND THEN SUBTRACT
    ************************************************************************
    Let me help you:

    Try this class:
    import java.util.GregorianCalendar;
    import java.util.Calendar;

    /**
    * @author Paul Hill
    */
    public class FAQCalendar extends GregorianCalendar {
    /**
    * All minutes have this many milliseconds except the last minute of the
    day on a day defined with
    * a leap second.
    */
    public static final long MILLISECS_PER_MINUTE = 60*1000;

    /**
    * Number of leap seconds per hour, except when a leap second is inserted.
    */
    public static final long MILLISECS_PER_HOUR = 60*MILLISECS_PER_MINUTE;

    /**
    * Number of leap seconds per day expect on
    * <BR/>1. days when a leap second has been inserted, e.g. 1999 JAN 1.
    * <BR/>2. Daylight-savings spring forward or fall back days.
    */
    protected static final long MILLISECS_PER_DAY = 24*MILLISECS_PER_HOUR;

    public FAQCalendar() {
    super();
    }
    public FAQCalendar( int y, int m, int d ) {
    super( y, m, d );
    }

    public FAQCalendar( int y, int m, int d, int h, int min, int s ) {
    super( y, m, d, h, min, s );
    }
    /**
    * @return Day number where day 0 is 1/1/1970, as per the Unix/Java
    date/time epoch.
    */
    public long getUnixDay() {
    long offset = get(Calendar.ZONE_OFFSET) + get(Calendar.DST_OFFSET);
    long day = (long)Math.floor( (double)(getTime().getTime() + offset ) /
    ((double)MILLISECS_PER_DAY) );
    return day;
    }
    }
    *************************************************
    Then you can rewrite the Election class to use this class that knows
    how to correctly find the day.
    *************************************************
    import java.util.GregorianCalendar;

    /**
    * This should really be a rewrite, but I have subclassed to not repeat
    * what was shown above.
    * @author Paul Hill
    * @since Aug 19, 2004
    */
    public class Election2 extends Election {
    private FAQCalendar startElection;
    private FAQCalendar endElection;

    public Election2() {
    super();
    }

    public double getDaysToStart(GregorianCalendar now) {
    FAQCalendar c = new FAQCalendar();
    c.setTime( now.getTime() );

    double dDaysToStartDate = startElection.getUnixDay() - c.getUnixDay();

    return dDaysToStartDate;
    }

    public double getDaysToEnd(GregorianCalendar now) {
    FAQCalendar c = new FAQCalendar();
    c.setTime( now.getTime() );
    double dDaysToEndDate = endElection.getUnixDay() - c.getUnixDay();
    return dDaysToEndDate;
    }
    }
    ******************************************************
    If you write the above test to try using this class you find it does
    the right things.
    ******************************************************

    HTH,
    -Paul

    p.s. Your algorithm also suffers from Daylight savings problems.
     
    P.Hill, Aug 20, 2004
    #12
  13. Erwin Moller

    P.Hill Guest

    Paul Lutus wrote:

    >(I always take "deprecated" to be
    > a synonym for "remove or eventually lose").


    But just because a bunch of methods are deprecated
    doesn't mean the class has no use; Date to hold a binary date-times,
    Calendar to manipulate date-times.

    -Paul
     
    P.Hill, Aug 20, 2004
    #13
  14. Erwin Moller

    Chris Smith Guest

    Paul Lutus wrote:
    > > In my view, it's not so much that Date has remaining useful methods (it
    > > really doesn't do much versus long), but that it's used in the standard
    > > API as a marker that a parameter represents a date/time, versus some
    > > other kind of number.

    >
    > Yes, I should have mentioned that. It's the same issue with StringTokenizer,
    > another class "in trouble" so to speak, but because of its presence in
    > existing code, there can be no question of getting rid of it. It's the
    > legacy issue.


    Hmm... I'm still not sure if we're saying the same thing. We might be,
    but I'm unsure. What I mean is that using java.util.Date is in no way a
    "legacy" thing at all. I would happily design new APIs that take Date
    objects as parameters or return them as results, though obviously the
    deprecated APIs are to be avoided.

    In essence, if I were asked to redesign the Java core API right now with
    no backward compatibility issues, I still think there'd be a use for a
    class that encapsulates a date/time in a strongly typed package, so I
    would include the Date class and use it every bit as much as it is now.
    (That isn't to say that I wouldn't make some additional changes, such as
    making instances of Date immutable, but that's a different matter.)

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Aug 20, 2004
    #14
  15. Erwin Moller

    Paul Lutus Guest

    Chris Smith wrote:

    > Paul Lutus wrote:
    >> > In my view, it's not so much that Date has remaining useful methods (it
    >> > really doesn't do much versus long), but that it's used in the standard
    >> > API as a marker that a parameter represents a date/time, versus some
    >> > other kind of number.

    >>
    >> Yes, I should have mentioned that. It's the same issue with
    >> StringTokenizer, another class "in trouble" so to speak, but because of
    >> its presence in existing code, there can be no question of getting rid of
    >> it. It's the legacy issue.

    >
    > Hmm... I'm still not sure if we're saying the same thing. We might be,
    > but I'm unsure. What I mean is that using java.util.Date is in no way a
    > "legacy" thing at all.


    My legacy remark was more about StringTokenizer. Clearly the truncated Date
    class has a remaining vital purpose.

    > I would happily design new APIs that take Date
    > objects as parameters or return them as results, though obviously the
    > deprecated APIs are to be avoided.
    >
    > In essence, if I were asked to redesign the Java core API right now with
    > no backward compatibility issues, I still think there'd be a use for a
    > class that encapsulates a date/time in a strongly typed package, so I
    > would include the Date class and use it every bit as much as it is now.
    > (That isn't to say that I wouldn't make some additional changes, such as
    > making instances of Date immutable, but that's a different matter.)


    Well, given that hypothetical condition (no legacy burdens and a free hand)
    I think the Date class and the GregorianCalendar class would be merged into
    a single class that handles what is left of Date and all of the present
    GregorianCalendar. There is a lot of commmonality of purpose, and even some
    overlap in function (like the default GregorianCalendar constructor that
    produces an object set to the current time, exactly as the default Date
    constructor does).

    At this point, and seeing the blurring of function between the classes, it
    is reasonable to ask (granted the hypothetical power described above)
    whether the two classes are really distinct in purpose any more.

    Speaking hypothetically, of course.

    --
    Paul Lutus
    http://www.arachnoid.com
     
    Paul Lutus, Aug 20, 2004
    #15
  16. Erwin Moller

    P.Hill Guest

    Paul Lutus wrote:

    > There is a lot of commmonality of purpose, and even some
    > overlap in function (like the default GregorianCalendar constructor that
    > produces an object set to the current time, exactly as the default Date
    > constructor does).


    So because two things start with a similar initial value they have overlapping
    purpose? Sorry I don't see that.

    > At this point, and seeing the blurring of function between the classes,


    Really what does the Date class do which is a repeat of what is in
    a Calendar? The only thing Date does is that it gives and takes a binary
    number. Yes, Calendar does that because it delegates to a Date object!

    > it
    > is reasonable to ask (granted the hypothetical power described above)
    > whether the two classes are really distinct in purpose any more.


    Yes, a Date HOLDS not much more than a binary value (the other field, if it is
    still there is transient) while the other class, GregorianCalendar has a binary
    value in it, HELD IN a DATE object, but also has an array of fields that are
    that binary value broken up, plus it holds a timezone, plus ...

    The point is one is a simple representation, the other is (almost) everything
    needed to manipulate dates. One is used to push around a datetime stamp
    (assuming you don't need it to know the timezone) while the other would be a
    really stupid thing to push down a wire to communicate some moment.

    > Speaking hypothetically, of course.


    If Chris rewrites the Date and Calendar, one
    will be a token which will be the smallest representation of a date-time
    and the other will be something to break one of those date-times up into a
    myriad fields and helps with calculations upon these fields. Two different
    beasts; please keep them straight.

    (Gregorian)Calendar is NOT a new and improved Date, it is an encapsulation of
    how a moment in time is converted to the fields of a particular calendar.
    Consider how you would make the One-True DateTimeCalendar class which could
    handle different Calendars. A Calendar algorithm is not a Date(Time) in the
    IS-A OO sense.

    -Paul
     
    P.Hill, Aug 20, 2004
    #16
  17. Erwin Moller

    Paul Lutus Guest

    P.Hill wrote:

    > Paul Lutus wrote:
    >
    >> There is a lot of commmonality of purpose, and even some
    >> overlap in function (like the default GregorianCalendar constructor that
    >> produces an object set to the current time, exactly as the default Date
    >> constructor does).

    >
    > So because two things start with a similar initial value they have
    > overlapping
    > purpose? Sorry I don't see that.


    Two classes, one nearly deprecated out of existence, have identical
    constructors weith identical outcomes. Please remember this is a
    hypothetical discussion -- IF we could start over, etc., etc..

    >
    >> At this point, and seeing the blurring of function between the classes,

    >
    > Really what does the Date class do which is a repeat of what is in
    > a Calendar?


    GregorianCalendar is the topic. They both have constructors that serve the
    same purpose and produce the same outcome. It suggests that the designers
    of GregorianCalendar wanted to save a few steps for people constructing an
    object set to the current time.

    > The only thing Date does is that it gives and takes a binary
    > number. Yes, Calendar does that because it delegates to a Date object!
    >
    >> it
    >> is reasonable to ask (granted the hypothetical power described above)
    >> whether the two classes are really distinct in purpose any more.

    >
    > Yes, a Date HOLDS not much more than a binary value (the other field, if
    > it is still there is transient) while the other class, GregorianCalendar
    > has a binary value in it, HELD IN a DATE object, but also has an array of
    > fields that are that binary value broken up, plus it holds a timezone,
    > plus ...


    Yes, and you are making my point. GregorianCalendar uses Date to accomplish
    some things that *might* be better handled within GregorianCalendar, now
    that Date is nearly deprecated to death, and granted the very hypothetical
    nature of this entire discussion. As I pointed out, thay already share a
    constructor, for all practical purposes.

    --
    Paul Lutus
    http://www.arachnoid.com
     
    Paul Lutus, Aug 20, 2004
    #17
  18. Paul Lutus wrote:
    > Well, given that hypothetical condition (no legacy burdens and a free hand)
    > I think the Date class and the GregorianCalendar class would be merged into
    > a single class that handles what is left of Date and all of the present
    > GregorianCalendar. There is a lot of commmonality of purpose, and even some
    > overlap in function (like the default GregorianCalendar constructor that
    > produces an object set to the current time, exactly as the default Date
    > constructor does).


    And what of those places that don't use the Gregorian calendar? I think
    the separation between Date and Calendar is correct. I would change the
    Date(String) constructor and toString() methods to use ISO8601 format.

    Mark Thornton
     
    Mark Thornton, Aug 20, 2004
    #18
  19. Erwin Moller

    Erwin Moller Guest

    Hi all,

    Thanks a lot for all your responses!
    Many were valuable for me.
    I learned a lot by just watching you all discussing the subject. :)

    It is clear to me now that actual complexity lies foremost in the fact that
    calendars themself are really complex in the real world. So any
    implementation must reflext this complexity (or try to hide it).

    And yes, My samplecode was importing too much and even double.
    Sloppy code, created with some frustration.
    I corrected it of course. (Thanks John Bollinger)

    I also understand it is easy for me to look at the API now and say they
    should have done a better job.
    In the real world you have to deal with backwards compatibility. Old code
    new versions of Java 'should' support.

    I have 1 question left:
    Why didn't Sun just release a better version of Date? (the GoodDate class or
    something)
    Or should I consider GregorianCalendar as the improved version?

    I ask this because I find myself doing basic stuff like getting intervals
    (or elapsed time) based on 2 dates.

    (A bit like public int daysBetween (Day day) in
    http://geosoft.no/software/day/Day.java.html (posted by Jacob) )

    What I miss in GregorianCalendar is things like:
    (phantasy-code)
    GregorianCalendar Cal1 = new GregorianCalendar(2004,7,2);
    GregorianCalendar Cal2 = new GregorianCalendar(2005,8,28);
    // express the difference in seconds.
    double dDiffInSecs = GregorianCalendar.getDiff(Cal1,Cal2,CALENDAR_SEC);
    // express the difference in days.
    double dDiffInDays = GregorianCalendar.getDiff(Cal1,Cal2,CALENDAR_DAY);

    Ideally the getDiff method would correct for any leapseconds, timesettings,
    etc.

    Maybe similar are classes around somewhere and I just missed them
    completely. :)

    It has been many years now since I coded VBscript, but if memory serves me
    well those VB guys had functions that did this. Handy.
    (If I sound lazy and spoiled, sorry for that!)

    Thanks for your time!

    Regards,
    Erwin Moller
     
    Erwin Moller, Aug 20, 2004
    #19
  20. Paul Lutus wrote:
    >
    > Yes, and you are making my point. GregorianCalendar uses Date to accomplish
    > some things that *might* be better handled within GregorianCalendar, now
    > that Date is nearly deprecated to death, and granted the very hypothetical
    > nature of this entire discussion. As I pointed out, thay already share a
    > constructor, for all practical purposes.
    >


    I think you didn't quite catch Paul Hill's point. What he was stressing was the
    fact that the Date and the Calendar classes are two different things altogether.
    java.util.Date (once you delete the deprecated methods from it) is a lightweight
    class which is an abstraction for an instance in time - (which is an essential
    component in any computation involving time). Trying to use a Calendar object
    which is much more complex beast for this is certainly overkill.

    Also a far as I can remember, the Calendar class does not use a Date object or
    any of its methods for anything (other than of course for its methods that take
    a Date as an argument or return a Date object). On the other hand, the Date
    class does use a Calendar object internally to support the deprecated methods -
    so it is no longer lightweight if you use its deprecated methods.

    BK
     
    Babu Kalakrishnan, Aug 20, 2004
    #20
    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. Manoj Nair
    Replies:
    4
    Views:
    21,410
    Manoj Nair
    Sep 4, 2003
  2. TT \(Tom Tempelaere\)

    Convert from java.sql.Date to GregorianCalendar

    TT \(Tom Tempelaere\), Jan 29, 2004, in forum: Java
    Replies:
    17
    Views:
    50,133
    P.Hill
    Feb 1, 2004
  3. Peter Grison

    Date, date date date....

    Peter Grison, May 28, 2004, in forum: Java
    Replies:
    10
    Views:
    3,295
    Michael Borgwardt
    May 30, 2004
  4. Replies:
    5
    Views:
    72,520
    Lee Fesperman
    Mar 9, 2005
  5. KevinSimonson
    Replies:
    6
    Views:
    638
Loading...

Share This Page