getActualMaximum of Calendar.WEEK_OF_MONTH confusion

Discussion in 'Java' started by pit.grinja@gmx.de, Oct 8, 2005.

  1. Guest

    Hi there,
    For a custom dialog that will allow users to select a date I wrote a
    JTable that displays the days of one complete month. The JTable gets an
    instance of GregorianCalendar as parameter. The table has seven
    columns, first header is "Sun",last header is "Sat". To correctly
    determine the number of rows, I wanted to use the method
    getActualMaximum(Calendar.WEEK_OF_MONTH). However, for some months, the
    return value is less than I would expect. Here is a sample program:
    import java.util.*;

    public class DatePrinter{
    private GregorianCalendar cal;
    private final String[] WEEKDAYS =
    {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
    public DatePrinter(){
    this.cal = new GregorianCalendar();
    cal.setFirstDayOfWeek(Calendar.SUNDAY);
    int year = this.cal.get(Calendar.YEAR);
    int month = this.cal.get(Calendar.MONTH);
    int firstWeekdayOfMonth = (new
    GregorianCalendar(year,month,1).get(Calendar.DAY_OF_WEEK));
    System.out.println("First Day of Month:
    "+WEEKDAYS[firstWeekdayOfMonth-1]);
    System.out.println("Day: "+this.cal.get(Calendar.DAY_OF_MONTH));
    System.out.println("Month: "+(this.cal.get(Calendar.MONTH)+1));
    System.out.println("Year: "+this.cal.get(Calendar.YEAR));
    System.out.println("Weeks in actual month:
    "+this.cal.getActualMaximum(Calendar.WEEK_OF_MONTH));
    System.out.println("Number of days in actual month:
    "+this.cal.getActualMaximum(Calendar.DAY_OF_MONTH));
    }
    public static void main(String[] ARGS){
    DatePrinter dp = new DatePrinter();
    }
    }
    //end of code
    For october, I would expect a value of 6 for
    this.cal.getActualMaximum(Calendar.WEEK_OF_MONTH): first week: just the
    saturday of october 1st, 2nd week: oct 2-8, 3rd week: 9-15,... 6th
    week: 30-31. But the return value is 5. For january, april,
    july,september and december, i also get wrong (i.e. to small) values.
    Is this a flaw in Java? I am using 1.4.2_08b03 on Win2000. Or is my
    thinking wrong?
    Many thanks for any pointers

    Piet
     
    , Oct 8, 2005
    #1
    1. Advertising

  2. Roedy Green Guest

    On 8 Oct 2005 08:05:37 -0700, wrote or quoted :

    >For october, I would expect a value of 6 for
    >this.cal.getActualMaximum(Calendar.WEEK_OF_MONTH): first week: just the
    >saturday of october 1st, 2nd week: oct 2-8, 3rd week: 9-15,... 6th
    >week: 30-31. But the return value is 5. For january, april,
    >july,september and december, i also get wrong (i.e. to small) values.
    >Is this a flaw in Java? I am using 1.4.2_08b03 on Win2000. Or is my
    >thinking wrong?
    >Many thanks for any pointers


    Date and Calendar are born to surprise. You have to read the JavaDoc
    very carefully. There are many gotchas. I have documented some at
    http://mindprod.com/jgloss/gotchas.html#DATE and
    http://mindprod.com/jgloss/calendar.html

    If you just want to get the job done, you can use the BigDate methods
    instead which behave more as you might expect. See
    http://mindprod.com/products1..html#BIGDATE
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 9, 2005
    #2
    1. Advertising

  3. Guest


    > >For october, I would expect a value of 6 for
    > >this.cal.getActualMaximum(Calendar.WEEK_OF_MONTH): first week: just the
    > >saturday of october 1st, 2nd week: oct 2-8, 3rd week: 9-15,... 6th
    > >week: 30-31. But the return value is 5. For january, april,
    > >july,september and december, i also get wrong (i.e. to small) values.


    > Date and Calendar are born to surprise. You have to read the JavaDoc
    > very carefully. There are many gotchas. I have documented some at
    > http://mindprod.com/jgloss/gotchas.html#DATE and
    > http://mindprod.com/jgloss/calendar.html

    Many thanks for the links. Now I know where to look when the next
    strange things happen.
    > If you just want to get the job done, you can use the BigDate methods
    > instead which behave more as you might expect. See
    > http://mindprod.com/products1..html#BIGDATE

    Since all I wanted to achieve is to get the right number of rows in my
    MonthCalendarJTable, I simply calculated the value on my own. Here is
    the solution. It assumes that your week starts on sunday:
    int firstWeekdayOfMonth = (new
    GregorianCalendar(year,month,1).get(Calendar.DAY_OF_WEEK));
    int correctNumberOfWeeks =
    (int)((firstWeekdayOfMonth+this.cal.getActualMaximum(Calendar.DAY_OF_MONTH)+5)/7));
    That formula handles july 2005 correctly (last day of this month is
    sunday, thus the last row has only one active cell) and also december
    2005 (last day is saturday, so the last row is full).
    Best wishes
    Piet
     
    , Oct 9, 2005
    #3
  4. P.Hill Guest

    wrote:
    >>>For october, I would expect a value of 6 for
    >>>this.cal.getActualMaximum(Calendar.WEEK_OF_MONTH): first week: just the
    >>>saturday of october 1st, 2nd week: oct 2-8, 3rd week: 9-15,... 6th
    >>>week: 30-31. But the return value is 5. For january, april,
    >>>july,september and december, i also get wrong (i.e. to small) values.

    >
    >
    >>Date and Calendar are born to surprise. You have to read the JavaDoc
    >>very carefully. There are many gotchas. I have documented some at
    >>http://mindprod.com/jgloss/gotchas.html#DATE and
    >>http://mindprod.com/jgloss/calendar.html


    AFAIK, None of which actually answer the question of the OP.

    > Since all I wanted to achieve is to get the right number of rows in my
    > MonthCalendarJTable, I simply calculated the value on my own.



    Hi Piet,

    What's up with the value you calculated? Despite Roedy's assumption
    that no value from Calendar or Date could possibly be right, running
    your code under 1.4.2_08 gave me the result you wanted of 6 not 5
    which you reported for the number of weeks in the month.

    -Paul
     
    P.Hill, Oct 10, 2005
    #4
  5. Guest

    Paul,
    > wrote:
    > >>>For october, I would expect a value of 6 for
    > >>>this.cal.getActualMaximum(Calendar.WEEK_OF_MONTH): first week: just the
    > >>>saturday of october 1st, 2nd week: oct 2-8, 3rd week: 9-15,... 6th
    > >>>week: 30-31. But the return value is 5. For january, april,
    > >>>july,september and december, i also get wrong (i.e. to small) values.


    > > Since all I wanted to achieve is to get the right number of rows in my
    > > MonthCalendarJTable, I simply calculated the value on my own.


    > What's up with the value you calculated? Despite Roedy's assumption
    > that no value from Calendar or Date could possibly be right, running
    > your code under 1.4.2_08 gave me the result you wanted of 6 not 5
    > which you reported for the number of weeks in the month.

    With "your code" you mean my "DatePrinter" class, right? I just tried
    that again and got ... five weeks in october. Have you tried other
    months? When you have some time to spend you can try the following:

    import java.util.*;

    public class DatePrinter{
    private GregorianCalendar cal;
    private final String[] WEEKDAYS =
    {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
    public DatePrinter(){
    this.cal = new GregorianCalendar();
    cal.setFirstDayOfWeek(Calendar.SUNDAY);
    int year = this.cal.get(Calendar.YEAR);
    System.out.println("Month:\tWeeks\tWeeks,corr");
    for (int i =0;i<12;i++){
    this.cal.set(Calendar.MONTH,i);
    int firstWeekdayOfMonth = (new
    GregorianCalendar(year,i,1).get(Calendar.DAY_OF_WEEK));
    int weeks =
    this.cal.getActualMaximum(Calendar.WEEK_OF_MONTH);
    int weeks_corr =
    (int)((firstWeekdayOfMonth+this.cal.getActualMaximum(Calendar.DAY_OF_MONTH)+5)/7);
    System.out.println((i+1)+"\t"+weeks+"\t"+weeks_corr);
    }
    }
    public static void main(String[] ARGS){
    DatePrinter dp = new DatePrinter();
    }
    }

    On my system, I get the following triples:
    1-5-6;2-5-5;3-5-5;4-4-5;5-5-5;6-5-5;7-5-6;8-5-5;9-4-5;10-5-6;11-5-5;12-4-5.
    As already posted, I sometimes get one day less than I expect.
    Anyway, that doesn´t bother me any more. Instead of calculating the
    number of rows for my MonthCalendarTable by whatAlgorithmEver, I fixed
    it to 6. Now I have one or even two completely empty rows in my table,
    but that´s fine.
    Best wishes
    Piet
     
    , Oct 12, 2005
    #5
  6. Roedy Green Guest

    On 9 Oct 2005 03:43:57 -0700, wrote or quoted :

    >Since all I wanted to achieve is to get the right number of rows in my
    >MonthCalendarJTable, I simply calculated the value on my own. Here is
    >the solution.


    here is some code to generate an HTML calendar

    package com.mindprod.lisa;

    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;

    import com.mindprod.business.BigDate;

    /**
    * produces an HTML table calendar for any month
    * suitable as a skeleton for a coming events schedule.
    * put yyyy mm on command line.
    *
    * Requires BigDate from
    * http://mindprod.com/products.html#BIGDATE
    *
    * May be freely used for any purpose but military
    *
    * @author Roedy Green
    * @author copyright (c) 2003-2005 Roedy Green, Canadian Mind Products
    * @version 1.0
    */
    public class CalMaker
    {

    /**
    * Months of the year
    */
    private static final String[] monthNames = {
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",};

    /**
    * days of the week 3 letter abbreviations in English. Index Sunday
    = 0.
    */
    private static final String[] shortDayName = { "sun" , "mon",
    "tue", "wed" , "thu", "fri", "sat"};

    /**
    * outputs cal.html in current directory with an HTML table for
    that month.
    *
    * @param args year month, e.g. 2003 11
    * @exception IOException
    */
    public static void main ( String[] args ) throws IOException
    {
    System.out.println("Results appear in cal.html" );

    int year = Integer.parseInt( args [0] );
    int month = Integer.parseInt( args [1] );
    PrintWriter out = new PrintWriter ( new FileWriter( "cal.html"
    ));
    out.println ( "<table width=\"620\" border=\"1\"
    cellspacing=\"1\" bordercolor=\"#808080\" cellpadding=\"7\">" );

    // header
    out.println ( "<tr><th colspan=\"7\">Coming events for "
    + monthNames[ month-1]
    + " "
    + year
    + "</th></tr>" );

    // label days of the week
    out.println( "<tr>" );
    for ( int i=0; i<7; i++ )
    {
    out.println( "<th>"
    + shortDayName[ i ]
    + "</th>" );
    }
    out.println( "</tr>" );

    // dummy boxes before the month starts, possibly none.
    BigDate firstOfMonth = new BigDate ( year, month, 1 );
    int dummystarts = firstOfMonth.getDayOfWeek();
    for ( int i=0; i<dummystarts; i++ )
    {
    if ( i== 0 )
    {
    out.println("<tr>");
    }
    out.println("<td>&nbsp;</td>");
    }

    // label days of the month
    int daysInMonth = BigDate.daysInMonth( month, year );
    for ( int day=1; day<=daysInMonth; day++ )
    {
    BigDate d = new BigDate ( year, month, day );
    if ( d.getDayOfWeek() == 0 )
    {
    out.println("<tr>");
    }
    out.println( "<td width=\"90\"><span class=\"daynumber\">"
    + day
    +
    "</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>");
    if ( d.getDayOfWeek() == 6 )
    {
    out.println("</tr>");
    }
    }

    // dummy boxes after the month ends, possibly none.
    BigDate lastOfMonth = new BigDate ( year, month, daysInMonth );
    int dummyStops = 6 - lastOfMonth.getDayOfWeek();
    for ( int i=0; i<dummyStops; i++ )
    {
    out.println("<td>&nbsp;</td>");
    if ( i == dummyStops-1 )
    {
    out.println("</tr>");
    }
    }

    out.println ( "</table>" );
    out.close();

    }
    }

    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 12, 2005
    #6
  7. P.Hill Guest

    wrote:
    > Paul,
    > On my system, I get the following triples:
    >

    Yours
    1-5-6;2-5-5;3-5-5;4-4-5;5-5-5;6-5-5;7-5-6;8-5-5;9-4-5;10-5-6;11-5-5;12-4-5.
    Mine
    1-6-6;2-5-5;3-5-5;4-5-5;5-5-5;6-5-5;7-6-6;8-5-5;9-5-5;10-6-6;11-5-5;12-5-5;
    * * * * *

    I got this by changing your coded to end with:
    System.out.print((i+1)+"-"+weeks+"-"+weeks_corr+";");
    }
    System.out.println();
    }


    I even tried using one calendar for all calculations (changing the
    the second occurance of new Calendar()), and setting the one cal's
    timezone to CET -- assuming your are in Central European Time -- but got
    the good results. What IS your TZ?

    Placing the line:
    System.out.println(cal.getTimeZone().getDisplayName());
    in your code (after I made sure to override the TZ) results in:
    Central European Time

    I think we only differ in OS and TZ and the time of day we run the code,
    but once in the VM I would think the OS would reduce a difference in TZ.
    Do you get different results if you set the hours, minutes and seconds to 0?

    -Paul
     
    P.Hill, Oct 13, 2005
    #7
    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. Shevek
    Replies:
    3
    Views:
    6,129
    Shevek
    Jun 23, 2004
  2. Shevek
    Replies:
    0
    Views:
    428
    Shevek
    Jun 23, 2004
  3. Parthiv Joshi
    Replies:
    1
    Views:
    821
    Samuel L Matzen
    Jul 6, 2004
  4. Ulrich Scholz

    Date/Calendar confusion

    Ulrich Scholz, Sep 6, 2012, in forum: Java
    Replies:
    0
    Views:
    287
    Ulrich Scholz
    Sep 6, 2012
  5. Ulrich Scholz

    Date/Calendar confusion

    Ulrich Scholz, Sep 6, 2012, in forum: Java
    Replies:
    8
    Views:
    483
Loading...

Share This Page