From: Rhino on
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
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
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
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
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