JDK-4736959 : JSpinner won't work for AM/PM field
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-08-26
  • Updated: 2003-04-12
  • Resolved: 2002-10-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2 mantisFixed
Related Reports
Relates :  
Description

Name: rmT116609			Date: 08/26/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

and:

java version "1.4.1-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-rc-b19)
Java HotSpot(TM) Client VM (build 1.4.1-rc-b19, mixed mode)


FULL OPERATING SYSTEM VERSION : Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
A JSpinner created using a SpinnerDateModel on the Calendar.AM_PM field does not roll properly.  It will roll from AM to PM but not vice-versa.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the sample application included with this report.
2. Attempt to change the value of the spinner using the up or down button.
3. The spinner's value will change from AM to PM, but not vice versa.  If you run the example in the afternoon, the field will not change.


EXPECTED VERSUS ACTUAL BEHAVIOR :
I expected the spinner to change from PM to AM using the up or down buttons; it did not.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import javax.swing.*;
import java.awt.*;
import java.util.Calendar;
import java.util.Date;

/**
 * The JSpinner will change from AM to PM but not vice-versa.
 */
public class AmPmBug {
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(600, 400);

        JPanel spinnerPanel = new JPanel(new FlowLayout());

        SpinnerDateModel model = new SpinnerDateModel(new Date(),
                null, null, Calendar.AM_PM);

        JSpinner spinner = new JSpinner(model);
        JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "a");
        spinner.setEditor(editor);

        spinnerPanel.add(spinner);

        f.getContentPane().add(spinnerPanel);
        f.setVisible(true);
    }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
I've tried adding listeners to manually change the value, with no luck.  The best work-around I can find is using a SpinnerListModel with new DateFormatSymbols().getAmPmStrings () and synchronizing with the Calendar.  This seems to require that calendar.roll(Calendar.HOUR_OF_DAY, 12) be
used.
(Review ID: 163349) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis mantis-b02 FIXED IN: mantis mantis-b02 INTEGRATED IN: mantis mantis-b02 mantis-b04
14-06-2004

EVALUATION Name: apR10133 Date: 08/29/2002 Every time we press up or down buttons we commit the edit before spinner value is changed. JSpinner.commitEdit() calls (via its editor) JFormattedTextField.commitEdit(). The last one converts textfield's text to value by using formatter and set this value. The problem is that java.text.SimpleDateFormat incorrectly parse the "AM" and "PM" strings. SimpleDateFormat.parse() returns the same date (zero date in UTC) for both. So, when textfield commit the edit it reset the value to zero date and then adds 12 hours. As result we always get the "PM". I believe the SimpleDateFormat should parse the "PM" not to the zero date. See below the testcase which show the bug in SimpleDateFormat: --------------- SimpleDateFormatTest.java -------------------- import java.text.*; import java.util.*; public class SimpleDateFormatTest { public static void main(String[] argv) { SimpleDateFormat f = new SimpleDateFormat("a"); Date d1 = f.parse("AM", new ParsePosition(0)); System.out.println("Parse AM: "+d1); Date d2 = f.parse("PM", new ParsePosition(0)); System.out.println("Parse PM: "+d2); } } -------------------------------------------------------------- The output is: > java SimpleDateFormatTest Parse AM: Thu Jan 01 00:00:00 GMT+03:00 1970 Parse PM: Thu Jan 01 00:00:00 GMT+03:00 1970 It would rather be correct to return Thu Jan 01 12:00:00 GMT+03:00 1970 for parsing "PM" string. ###@###.### ====================================================================== Calendar takes the HOUR_OF_DAY field value if the HOUR and AM_PM fields are not set together. It should check the setting state of the AM_PM field. ###@###.### 2002-09-02 Changing GregorianCalendar to take AM_PM when HOUR isn't set breaks JCK test cases, GregorianCalendar2057 and SimpleDateFormat0123. Changed SimpleDateFormat to set HOUR to force GregorianCalendar to take the AM_PM value in case only AM_PM is specified. ###@###.### 2002-09-03
03-09-2002

WORK AROUND Name: apR10133 Date: 08/29/2002 Use the editor with customized SimpleDateFormat like below: JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner); SimpleDateFormat format = new SimpleDateFormat("a") { public Date parse(String text, ParsePosition pos) { Date d = super.parse(text, pos); if (text.equals("PM")) { Calendar cal = Calendar.getInstance(); cal.setTime(d); cal.set(Calendar.HOUR_OF_DAY, 12); d = cal.getTime(); } return d; } }; JFormattedTextField.AbstractFormatter formatter = new DateFormatter(format); JFormattedTextField.AbstractFormatterFactory factory = new DefaultFormatterFactory(formatter); editor.getTextField().setFormatterFactory(factory); ###@###.### ====================================================================== Specify the HOUR value together with AM/PM. Sample code: -- import java.text.*; import java.util.*; public class SimpleDateFormatTest2 { public static void main(String[] argv) { SimpleDateFormat f = new SimpleDateFormat("K a"); Date d1 = f.parse("0 AM", new ParsePosition(0)); System.out.println("Parse AM: "+d1); Date d2 = f.parse("0 PM", new ParsePosition(0)); System.out.println("Parse PM: "+d2); } } -- Output: Parse AM: Thu Jan 01 00:00:00 PST 1970 Parse PM: Thu Jan 01 12:00:00 PST 1970 ###@###.### 2002-09-02
02-09-2002