Prev: Basic JUnit questions
Next: Discount CHLOE True leather AAA Wholesale (www.supertradeonline06.com )
From: Rhino on 20 Mar 2010 20:59 On Mar 20, 6:22 pm, Lew <no...(a)lewscanon.com> wrote: > Eric Sosman wrote: > >> 5) Refrain from calling non-final instance methods on objects > >> that haven't finished construction! This is a Big No-No; > Rhino wrote: > > With regards to your fifth point, I'm afraid I still get a little > > muddled when someone makes a generalized commment like that without > > also pointing to the specific thing I've done wrong. Can you clarify > > which object hasn't finished construction? > > 'TestHour'. > > You call a bunch of methods from inside the constructor, ergo the object > hasn't finished construction when you call methods like > 'getCurrentHour12HourClock()'. It is better (usually) to let an object finish > construction before it does anything useful. > Okay, I see your point now. (Well, actually it was Eric's point and you are clarifying it.) But I'm not clear on what I have to do differently. How do I know the object has finished construction so that I know it is safe to use it? In other words, how should I code it differently. For what it's worth, your point is well taken that I should be using DateFormat and SimpleDateFormat. I'm actually rewriting my methods to use that approach as I wait for replies to my problem. I think I originally wrote my DateTimeUtils class before I knew about DateFormat and SimpleDateFormat so my code is way overdue to be brought up to date anyway. > (TAB characters removed for readability.) > > > public TestHour() { > > > System.out.println("The current hour on the 12 hour clock is: " + > > getCurrentHour12HourClock() + ".\n"); > > System.out.println("The current hour on the 24 hour clock is: " + > > getCurrentHour24HourClock() + ".\n"); > > System.out.println("The current time is: " + getCurrentTime() + ". > > \n"); > > } > > And please, please, please, please, please use narrower indentation for Usenet > code posts - a maximum of four spaces per indent level. It makes the code so > hard to read when you use such wide indentation. Stop using TAB characters > for indentation. > Sorry about that! The tabs just look like spaces and its hard to find them all. > > The output wraps horribly so I'll just summarize it verbally: > > The hour still shows as 7 PM even though it was not yet 7 PM > > when I executed the code. > > The actual output still has a marginal chance of being useful to those of us > not there who attempt to help from here. Every time you redact information > you risk losing the piece that solves the puzzle. > Okay, I'll include that as well. Also for what it's worth, when I wrote the code using SimpleDateFormat, the hour is still one hour later than it should be. Now for some new output. I've modified TestHour slightly to display the values you've requested. I modified the three methods along these lines and added a single instance variable, DEBUG which is a boolean set to true. public int getCurrentHour12HourClock() { /* Get the current date, then the current hour (12 hour clock). */ GregorianCalendar now = new GregorianCalendar(); if (DEBUG) { System.out.println("now.toString(): " + now.toString()); System.out.println("Calendar.getInstance().toString(): " + Calendar.getInstance().toString()); } return now.get(Calendar.HOUR); } Each of the three methods were modified in exactly the same way with the exact same if (DEBUG) and the exact same printlin() statements in the exact same position within the method. This is the output from running TestHour, INCLUDING all the output from the new println() statements. -------------------------------------------- now.toString(): java.util.GregorianCalendar[time=1269135963921,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/ New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/ New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=46,SECOND=3,MILLISECOND=921,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] Calendar.getInstance().toString(): java.util.GregorianCalendar[time=1269135963937,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/ New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/ New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=46,SECOND=3,MILLISECOND=937,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] The current hour on the 12 hour clock is: 9. now.toString(): java.util.GregorianCalendar[time=1269135963937,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/ New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/ New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=46,SECOND=3,MILLISECOND=937,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] Calendar.getInstance().toString(): java.util.GregorianCalendar[time=1269135963937,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/ New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/ New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=46,SECOND=3,MILLISECOND=937,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] The current hour on the 24 hour clock is: 21. Calendar: java.util.GregorianCalendar[time=1269135963937,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/ New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/ New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=46,SECOND=3,MILLISECOND=937,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] now.toString(): java.util.GregorianCalendar[time=1269135963937,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/ New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/ New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=46,SECOND=3,MILLISECOND=937,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] Calendar.getInstance().toString(): java.util.GregorianCalendar[time=1269135963937,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/ New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/ New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=20,DAY_OF_YEAR=79,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=46,SECOND=3,MILLISECOND=937,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] The current time is: 21:46:03. -------------------------------------------- As you see, the hour is now indicated as 9/21 but it is still not quite 9 PM here so the hour is still one hour later than the actual time. I've also rewritten the routines along the lines you suggested with DateFormat and SimpleDateFormat and now present TestHour2: ------------------------------------------- import java.text.SimpleDateFormat; import java.util.Date; public class TestHour2 { final static boolean DEBUG = true; public static void main(String[] args) { new TestHour2(); } public TestHour2() { System.out.println("The current hour on the 12 hour clock is: " + getCurrentHour12HourClock() + ".\n"); System.out.println("The current hour on the 24 hour clock is: " + getCurrentHour24HourClock() + ".\n"); System.out.println("The current time is: " + getCurrentTime() + ". \n"); } public int getCurrentHour12HourClock() { Date now = new Date(); SimpleDateFormat hourFormat = new SimpleDateFormat("h"); String strCurrentHour = hourFormat.format(now).toString(); int currentHour = 0; try { currentHour = Integer.parseInt(strCurrentHour.trim()); } catch (NumberFormatException nf_excp) { throw new NumberFormatException("The current hour is not an integer."); } return(currentHour); } public int getCurrentHour24HourClock() { Date now = new Date(); SimpleDateFormat hourFormat = new SimpleDateFormat("H"); String strCurrentHour = hourFormat.format(now).toString(); int currentHour = 0; try { currentHour = Integer.parseInt(strCurrentHour.trim()); } catch (NumberFormatException nf_excp) { throw new NumberFormatException("The current hour is not an integer."); } return(currentHour); } public String getCurrentTime() { Date now = new Date(); SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm:ss"); String strCurrentTime = timeFormat.format(now).toString(); return(strCurrentTime); } } ------------------------------------------- The output from this version of the date routines is, as you might have guessed: ------------------------------------------- The current hour on the 12 hour clock is: 9. The current hour on the 24 hour clock is: 21. The current time is: 09:58:06. ------------------------------------------- In other words, rewriting the methods to use better techniques still causes the hour to be one hour later than it should be. Have we proven now that the problem is with the OS or is there still a chance that this is a Java issue? -- Rhino
From: Rhino on 20 Mar 2010 21:05 On Mar 20, 6:23 pm, Arved Sandstrom <dces...(a)hotmail.com> wrote: > Rhino wrote: > > [ SNIP ] > > > If you'd like to see the JUnit tests, I could include them but I'm pretty > > sure that there is nothing wrong with them. > > It can't hurt - you've asked for feedback concerning testing in general, > and JUnit specifically, and that's a good way to get some. > > AHS Here are the test cases for the three methods that are giving me the wrong hour. As you can imagine, the hour changes regularly - hourly ;-) - so I have to keep revising the expectedResult to match. (This is a much bigger problem with the second and millisecond by the way! I wonder what a professional test class would do to make it unnecessary to recode the expected hour, minute, second (or whatever) by hand all the time....) ------------------------------------ public void testGetCurrentHour12() { //TODO: why does this method return 9 (PM) when it is actually 8 in this time zone right now? int currentHour = dateTimeUtils.getCurrentHour12HourClock(); int expectedHour = 8; assertTrue("The actual hour (12 hour clock), " + currentHour + ", does not equal the expected hour, " + expectedHour, currentHour==expectedHour); } public void testGetCurrentHour24() { //TODO: why does this method return 21 hours (24-hour clock) when it is actually 20 in this time zone right now? int currentHour = dateTimeUtils.getCurrentHour24HourClock(); int expectedHour = 20; assertTrue("The actual hour (24 hour clock), " + currentHour + ", does not equal the expected hour, " + expectedHour, currentHour==expectedHour); } public void testGetCurrentTime() { String currentTime = dateTimeUtils.getCurrentTime(); String expectedTime = "20:24:00"; //$NON-NLS-1$ assertTrue("The actual time, " + currentTime + ", does not equal the expected time, " + expectedTime, currentTime.equals(expectedTime)); } ------------------------------------ Are we agreed that these test cases are okay? -- Rhino
From: Martin Gregorie on 20 Mar 2010 21:32 On Sat, 20 Mar 2010 16:49:20 -0700, Rhino wrote: > I'm running XP SP2, not SP3. I asked about DST issue on one of the > Microsoft newsgroups and they pointed me to a web page which is supposed > to help me install whatever I need. I went to that page, and had to > identify my skill level; I chose programmer and it started blathering > about C# and .NET but I don't develop in those. So I re- selected the > skill level to home user. It asked me which program I was updating; I > chose Outlook 2007 but it failed to execute with a cryptic error > message. > > Frankly, I suspect the OS very strongly here but am baffled about what I > need to do to fix this issue. > > If you can enlighten me, I'd appreciate it. > I've been purely a Linux user for the last 8 years, so the last Windows version I understand in any depth is Win95. I still have it installed for the rare occasions when I need to run a couple of programs I haven't yet tried to run under Wine. That box dual-boots, so I am very familiar with local-clock Win95 and UTC Linux fighting over the RTC. My only experience of a more recent Window was a three month contract writing Java with IntelliJ on an XP box, which I treated as a black box platform since testing, etc. was done under RHEL. This is why I posed the questions I'd want to look into rather than giving you answers. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
From: Arved Sandstrom on 20 Mar 2010 21:37 Rhino wrote: > On Mar 20, 6:22 pm, Lew <no...(a)lewscanon.com> wrote: >> Eric Sosman wrote: >>>> 5) Refrain from calling non-final instance methods on objects >>>> that haven't finished construction! This is a Big No-No; >> Rhino wrote: >>> With regards to your fifth point, I'm afraid I still get a little >>> muddled when someone makes a generalized commment like that without >>> also pointing to the specific thing I've done wrong. Can you clarify >>> which object hasn't finished construction? >> 'TestHour'. >> >> You call a bunch of methods from inside the constructor, ergo the object >> hasn't finished construction when you call methods like >> 'getCurrentHour12HourClock()'. It is better (usually) to let an object finish >> construction before it does anything useful. >> > Okay, I see your point now. (Well, actually it was Eric's point and > you are clarifying it.) But I'm not clear on what I have to do > differently. How do I know the object has finished construction so > that I know it is safe to use it? In other words, how should I code it > differently. [ SNIP ] Section 12.5 of the Java Language Specification (JLS) discusses creation of new class instances, but for your purposes what it boils down to is that the last things to execute before you get a finished ready-to-go object are the statements in the body of your constructor (excepting this() and super() statements, which occur earlier). IOW, when you leave the body of the constructor is when you've got your finished object. AHS
From: Lew on 20 Mar 2010 21:54
Rhino wrote: > public void testGetCurrentHour12() { > > //TODO: why does this method return 9 (PM) when it is actually 8 in > this time zone right now? > int currentHour = dateTimeUtils.getCurrentHour12HourClock(); > int expectedHour = 8; > assertTrue("The actual hour (12 hour clock), " + currentHour + ", > does not equal the expected hour, " + expectedHour, > currentHour==expectedHour); > } Just out of curiosity, if you put, just after the declaration of 'expectedHour', the line Calendar calinst = Calendar.getInstance() int calendarHour = calinst.get( Calendar.HOUR ); what does it give you? While we're at it, what do calinst.getTimeZone.getDisplayName() and calinst.getTimeZone.getOffset( calinst.getTimeInMillis() ) return? > Are we agreed that these test cases are okay? I wonder why you write a utility method to get the current hour when the standard API already provides a one-line way to do so. -- Lew |