Wrong result from System.currentTimeMillis()

A

alberto.poz

Hi, running in a RedHat linux 2.6.9 environment I get:


# date
Thu Jan 3 11:14:29 Europe/Rome 2008

# hwclock
Thu 03 Jan 2008 11:14:49 AM Europe/Rome -0.940606 seconds

but

System.out.println(new Date(System.currentTimeMillis()));

produces:

Thu Jan 03 12:14:38 CET 2008

What's wrong?
 
N

Nigel Wade

Hi, running in a RedHat linux 2.6.9 environment I get:


# date
Thu Jan 3 11:14:29 Europe/Rome 2008

# hwclock
Thu 03 Jan 2008 11:14:49 AM Europe/Rome -0.940606 seconds

but

System.out.println(new Date(System.currentTimeMillis()));

produces:

Thu Jan 03 12:14:38 CET 2008

What's wrong?

Maybe Java isn't picking up the default timezone correctly.

What does this output?

System.out.println(TimeZone.getDefault().getID());
 
A

alberto.poz

Maybe Java isn't picking up the default timezone correctly.

What does this output?

System.out.println(TimeZone.getDefault().getID());

--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : (e-mail address removed)
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555

It shows the expected output:

Europe/Rome

I don't think it depends on timezone: I tried to compare the output of
System.currentTimeMillis() in my RedHat and in a Win XP where I get
correct results. They differ by about 1 hour (60 * 60 * 1000) as if
system clock was wrong but it isn't.
 
A

Andrew Thompson

It shows the expected output:

Europe/Rome

I don't think it depends on timezone: I tried to compare the output of
System.currentTimeMillis() in my RedHat and in a Win XP where I get
correct results. They differ by about 1 hour (60 * 60 * 1000) as if
system clock was wrong but it isn't.

What exact Java versions are being run on these two machines?

It almost seems as if one system is assuming 'summer time'
and the other is not. Do you have 'summer time' or 'Daylight
Savings Time' in Rome?

But wait.. it's *winter* over there* at the moment! My
'summer time' theory is not looking very solid.

* The northern hemisphere, where you poor souls
apparently reside.

--
Andrew Thompson
http://www.physci.org/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200801/1
 
A

alberto.poz

(e-mail address removed) wrote:

..


What exact Java versions are being run on these two machines?

It almost seems as if one system is assuming 'summer time'
and the other is not. Do you have 'summer time' or 'Daylight
Savings Time' in Rome?

But wait.. it's *winter* over there* at the moment! My
'summer time' theory is not looking very solid.

* The northern hemisphere, where you poor souls
apparently reside.

The same java version on both machines: 1.5.0_11
 
R

Roedy Green

They differ by about 1 hour (60 * 60 * 1000) as if
system clock was wrong but it isn't.

That sounds suspiciously like a daylight saving problem.

Did someone manually adjust the clock by one hour rather than setting
the timezone and letting the OS adjust?

In all your calculations, keep printing the timezone to make sure it
is what you think, also the various offsets. See
http://mindprod.com/jgloss/timezone.html
 
A

alberto.poz

That sounds suspiciously like a daylight saving problem.

Did someone manually adjust the clock by one hour rather than setting
the timezone and letting the OS adjust?

In all your calculations, keep printing the timezone to make sure it
is what you think, also the various offsets. Seehttp://mindprod.com/jgloss/timezone.html

As I said both system clock and TZ appear to be correct .

That's what this code fragment produces:

TimeZone tz1 = TimeZone.getDefault();
System.out.println(tz1.getDisplayName());
System.out.println(System.getProperty( "user.timezone" ));
System.out.println(new Date());

Central European Time
Europe/Rome
Fri Jan 04 09:22:36 CET 2008

While the OS date command produces:

Fri Jan 4 08:22:48 Europe/Rome 2008

(1 hour less)


N.B. the env command shows:

..
..
..
TZ=Europe/Rome
..
..
 
A

Andrew Thompson

...
As I said both system clock and TZ appear to be correct .

That's what this code fragment produces:

TimeZone tz1 = TimeZone.getDefault();
System.out.println(tz1.getDisplayName());
System.out.println(System.getProperty( "user.timezone" ));
System.out.println(new Date());

What about the code fragment show at Roedy's page?
It also mentions things like tz.getOffset() and
tz.getRawOffset().

I am no expert on dealing with calenders and timezones,
beyond knowing there are a lot of pitfalls to this very
complicated area of development.

As an aside. I am not in '1.5' mode at the moment (heavily
into 1.6), but.. is 1.5.0_11 the very latest 1.5 offered?

--
Andrew Thompson
http://www.physci.org/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200801/1
 
N

Nigel Wade

As I said both system clock and TZ appear to be correct .

That's what this code fragment produces:

TimeZone tz1 = TimeZone.getDefault();
System.out.println(tz1.getDisplayName());
System.out.println(System.getProperty( "user.timezone" ));
System.out.println(new Date());

Central European Time
Europe/Rome
Fri Jan 04 09:22:36 CET 2008

While the OS date command produces:

Fri Jan 4 08:22:48 Europe/Rome 2008

(1 hour less)


N.B. the env command shows:

.
.
.
TZ=Europe/Rome
.
.

Hmm, you shouldn't need to have TZ set. Maybe there is a fault in the system
clock and you have modified your shell environment to counter this. What
version of RedHat are you running? The timezone should be set
by /etc/localtime. The Linux system clock works in UTC, or more correctly the
number of seconds since 00:00 Jan 1 1970 UTC. When you ask for a date/time this
is converted into a local wall clock time based on your timezone setting.

The hardware clock must be set to either UTC or local wall clock time, and the
system configured accordingly. This allows the system clock to be set correctly
when the system boots, which is the only time that Linux normally consults the
hardware clock. Using wall clock time for the hardware clock means you are
responsible for manually altering the hardware clock for DST otherwise the
system clock will be wrong after a re-boot, hence you normally set it to UTC.
You would normally only use wall clock time if the system is dual-boot with
Windows because Windows works in local time (and adjusts the hardware clock for
DST). Linux does its best to correct the broken way that Windows does things,
but it's not infallible.

The system may be converting the "seconds since the epoch" to local time
differently from that of your shell. However I'd expect that Java would use the
same environment as your shell, always supposing you are running Java from the
same shell. What does the command 'date "+%s"' output? This is what the system
clock (not the hardware clock) thinks is the number of seconds since the start
of 1970 (in UTC). It is also what Java System.currentTimeMillis() should
output (times 1000). If this is wrong it most likely means the hardware (and
therefore system) clock is incorrectly set.

Is your hardware clock set to UTC or CET? Is the system setup accordingly so the
system clock is correctly set from the hardware clock? What's
in /etc/sysconfig/clock?
 
A

alberto.poz

They differ by about 1 hour (60 * 60 * 1000) as if
system clock was wrong but it isn't.
That sounds suspiciously like a daylight saving problem.
Did someone manually adjust the clock by one hour rather than setting
the timezone and letting the OS adjust?
In all your calculations, keep printing the timezone to make sure it
is what you think, also the various offsets.
Seehttp://mindprod.com/jgloss/timezone.html


As I said both system clock and TZ appear to be correct .
That's what this code fragment produces:
TimeZone tz1 = TimeZone.getDefault();
System.out.println(tz1.getDisplayName());
System.out.println(System.getProperty( "user.timezone" ));
System.out.println(new Date());
Central European Time
Europe/Rome
Fri Jan 04 09:22:36 CET 2008
While the OS date command produces:
Fri Jan 4 08:22:48 Europe/Rome 2008
(1 hour less)
N.B. the env command shows:
.
.
.
TZ=Europe/Rome
.
.

Hmm, you shouldn't need to have TZ set. Maybe there is a fault in the system
clock and you have modified your shell environment to counter this. What
version of RedHat are you running? The timezone should be set
by /etc/localtime. The Linux system clock works in UTC, or more correctly the
number of seconds since 00:00 Jan 1 1970 UTC. When you ask for a date/time this
is converted into a local wall clock time based on your timezone setting.

The hardware clock must be set to either UTC or local wall clock time, and the
system configured accordingly. This allows the system clock to be set correctly
when the system boots, which is the only time that Linux normally consults the
hardware clock. Using wall clock time for the hardware clock means you are
responsible for manually altering the hardware clock for DST otherwise the
system clock will be wrong after a re-boot, hence you normally set it to UTC.
You would normally only use wall clock time if the system is dual-boot with
Windows because Windows works in local time (and adjusts the hardware clock for
DST). Linux does its best to correct the broken way that Windows does things,
but it's not infallible.

The system may be converting the "seconds since the epoch" to local time
differently from that of your shell. However I'd expect that Java would use the
same environment as your shell, always supposing you are running Java from the
same shell. What does the command 'date "+%s"' output? This is what the system
clock (not the hardware clock) thinks is the number of seconds since the start
of 1970 (in UTC). It is also what Java System.currentTimeMillis() should
output (times 1000). If this is wrong it most likely means the hardware (and
therefore system) clock is incorrectly set.

Is your hardware clock set to UTC or CET? Is the system setup accordingly so the
system clock is correctly set from the hardware clock? What's
in /etc/sysconfig/clock?

--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : (e-mail address removed)
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555

Actually I forget to specify that my RedHat is a VMware virtual
appliance.
That's what I can get from OS:

# uname -a
Linux sec-rfid-prod 2.6.9-42.0.3.EL #1 Mon Sep 25 17:14:19 EDT 2006
i686 i686 i386 GNU/Linux

# cat /etc/sysconfig/clock
ZONE="Europe/Rome"
UTC=true
ARC=false

# hwclock
Mon 07 Jan 2008 01:10:04 PM Europe/Rome -0.454620 seconds

# date +%s
1199711211

System.currentTimeMillis()
1199711210192

(they seem to be equal ...)


Can you suggest me any other thing to check?

Thank you
 
N

Nigel Wade

Actually I forget to specify that my RedHat is a VMware virtual
appliance.

Ahhhhh. So it's a virtual OS. I really have no idea how that would affect the
hardware clock and its interpretation by the Linux kernel.
That's what I can get from OS:

# uname -a
Linux sec-rfid-prod 2.6.9-42.0.3.EL #1 Mon Sep 25 17:14:19 EDT 2006
i686 i686 i386 GNU/Linux

# cat /etc/sysconfig/clock
ZONE="Europe/Rome"
UTC=true
ARC=false

Try setting the clock to UTC=false, the hardware clock is probably set to local
time if it's running under VMware, but check it. Don't edit this file, use
system-config-date and in the Time Zone tab uncheck the "System clock uses UTC"
checkbox.
# hwclock
Mon 07 Jan 2008 01:10:04 PM Europe/Rome -0.454620 seconds

# date +%s
1199711211

System.currentTimeMillis()
1199711210192

(they seem to be equal ...)

Not exactly equal. Which did you output first? The date value is 1 second after
the Java value, if you output date first how has your clock gone backward?

The important point, though, is that value is for 13:06:51 UTC, i.e. 14:06:51
CET. So it looks like Java is correct, and date is wrong.
Can you suggest me any other thing to check?

Not really. I don't have VMware so can't check anything.
 
A

alberto.poz

Ahhhhh. So it's a virtual OS. I really have no idea how that would affect the
hardware clock and its interpretation by the Linux kernel.




Try setting the clock to UTC=false, the hardware clock is probably set to local
time if it's running under VMware, but check it. Don't edit this file, use
system-config-date and in the Time Zone tab uncheck the "System clock uses UTC"
checkbox.





Not exactly equal. Which did you output first? The date value is 1 second after
the Java value, if you output date first how has your clock gone backward?

The important point, though, is that value is for 13:06:51 UTC, i.e. 14:06:51
CET. So it looks like Java is correct, and date is wrong.




Not really. I don't have VMware so can't check anything.

--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : (e-mail address removed)
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555

Thank you for your help. All you said sounds good to me. Unfortunatly
I can't access to the machine running VMware server right now so I
can't check for hardware clock.

Best regards

Alberto Pozzato

Direzione produzione
Standards & Architetture
Middleware e Tecnologie d'integrazione
Insiel S.p.A.
Via Pieri, 2
33100 Udine
tel. +39 0432 557943
fax. +39 0432 557999
e-mail: (e-mail address removed)
 
M

Mark Rafn

As I said both system clock and TZ appear to be correct .

That's what this code fragment produces:

TimeZone tz1 = TimeZone.getDefault();
System.out.println(tz1.getDisplayName());
System.out.println(System.getProperty( "user.timezone" ));
System.out.println(new Date());

Central European Time
Europe/Rome
Fri Jan 04 09:22:36 CET 2008

While the OS date command produces:

Fri Jan 4 08:22:48 Europe/Rome 2008


Let's run a more complete test - I want to see TZ offsets and actual
epoch values (which are timezone-agnostic). I suspect something's
wrong with your timezone definition either in the VM or in the OS.

For the OS (assuming GNU date):

date +%s # seconds since epoch
date +%c # formatted local date
date "+%Z (%z)" # timezone info

for the VM:
import java.util.*;
import java.text.*;
import java.io.*;

public class PrintTime {
public static void main(String[] args) {
PrintStream out = System.out;
long now = System.currentTimeMillis();
Date nowD = new Date(now);
TimeZone tz = TimeZone.getDefault();

out.println("TZ id: " + tz.getID());
out.println("TZ name: " + tz.getDisplayName());
out.println("TZ short no-DST name: " + tz.getDisplayName(false,
TimeZone.SHORT));
out.println("TZ short DST name: " + tz.getDisplayName(true,
TimeZone.SHORT));
out.println("TZ offset (mins): " + tz.getOffset(now) / (60 * 1000));
out.println("TZ uses DST: " + tz.useDaylightTime());
out.println("TZ in DST now: " + tz.inDaylightTime(nowD));
out.println("TZ DST savings (mins): " +
tz.getDSTSavings() / (60 * 1000));
out.println();

out.println("seconds since epoch: " + now / 1000);
out.println("Date toString: " + nowD);
out.println("SDF: " + new SimpleDateFormat("d MMM yyyy HH:mm:ss z(Z)").
format(nowD));
}
}
 
A

alberto.poz

As I said both system clock and TZ appear to be correct .
That's what this code fragment produces:
TimeZone tz1 = TimeZone.getDefault();
System.out.println(tz1.getDisplayName());
System.out.println(System.getProperty( "user.timezone" ));
System.out.println(new Date());
Central European Time
Europe/Rome
Fri Jan 04 09:22:36 CET 2008
While the OS date command produces:
Fri Jan 4 08:22:48 Europe/Rome 2008

Let's run a more complete test - I want to see TZ offsets and actual
epoch values (which are timezone-agnostic). I suspect something's
wrong with your timezone definition either in the VM or in the OS.

For the OS (assuming GNU date):

date +%s # seconds since epoch
date +%c # formatted local date
date "+%Z (%z)" # timezone info

for the VM:
import java.util.*;
import java.text.*;
import java.io.*;

public class PrintTime {
public static void main(String[] args) {
PrintStream out = System.out;
long now = System.currentTimeMillis();
Date nowD = new Date(now);
TimeZone tz = TimeZone.getDefault();

out.println("TZ id: " + tz.getID());
out.println("TZ name: " + tz.getDisplayName());
out.println("TZ short no-DST name: " + tz.getDisplayName(false,
TimeZone.SHORT));
out.println("TZ short DST name: " + tz.getDisplayName(true,
TimeZone.SHORT));
out.println("TZ offset (mins): " + tz.getOffset(now) / (60 * 1000));
out.println("TZ uses DST: " + tz.useDaylightTime());
out.println("TZ in DST now: " + tz.inDaylightTime(nowD));
out.println("TZ DST savings (mins): " +
tz.getDSTSavings() / (60 * 1000));
out.println();

out.println("seconds since epoch: " + now / 1000);
out.println("Date toString: " + nowD);
out.println("SDF: " + new SimpleDateFormat("d MMM yyyy HH:mm:ss z(Z)").
format(nowD));
}}

Here are the results:

# date +%s
1199782449

# date +%c
Tue 08 Jan 2008 08:54:14 AM Europe/Rome

# date "+%Z (%z)"
Europe/Rome (+0000)

# java PrintTime
TZ id: Europe/Rome
TZ name: Central European Time
TZ short no-DST name: CET
TZ short DST name: CEST
TZ offset (mins): 60
TZ uses DST: true
TZ in DST now: false
TZ DST savings (mins): 60

seconds since epoch: 1199782558
Date toString: Tue Jan 08 09:55:58 CET 2008
SDF: 8 Jan 2008 09:55:58 CET(+0100)
 
N

Nigel Wade

Looks like you might be onto something here...
Here are the results:

# date +%s
1199782449

# date +%c
Tue 08 Jan 2008 08:54:14 AM Europe/Rome

# date "+%Z (%z)"
Europe/Rome (+0000)

Here, I get:

$ date "+%Z (%z)"
GMT (+0000)
$ export TZ="Europe/Rome"
$ date "+%Z (%z)"
CET (+0100)

It looks as though the zoneinfo, or your setting of TZ, is incorrect.

What happens if you unset TZ?
TZ should not be needed in a correctly configured RH setup.
# java PrintTime
TZ id: Europe/Rome
TZ name: Central European Time
TZ short no-DST name: CET
TZ short DST name: CEST
TZ offset (mins): 60
TZ uses DST: true
TZ in DST now: false
TZ DST savings (mins): 60

seconds since epoch: 1199782558
Date toString: Tue Jan 08 09:55:58 CET 2008
SDF: 8 Jan 2008 09:55:58 CET(+0100)

So the Java timezone is correct.
 
M

Mark Rafn

Nigel Wade said:
It looks as though the zoneinfo, or your setting of TZ, is incorrect.

And perhaps your system clock too.

My theory is that your system has the clock set one hour too early, and the
system timezone file hacked to have the CET offset one hour off.
What happens if you unset TZ?

TZ=UTC date

Should be informative. If it gives you correct UTC (aka GMT) time, then
my theory is wrong.

This epoch time is Tue Jan 8 08:55:58 2008 UTC.

Which is 9:55 CET. Good.
So the Java timezone is correct.

Yup. Java is behaving just fine.

THIS is just wrong:
Epoch time 1199782449 is Tue Jan 8 08:54:09 2008 GMT or 9:54:09 CET.

This is incorrectly reporting an hour earlier than the system clock says.

And this says your timezone has no offset from UTC. Which is wrong.

Fix your system timezone files, and fix your system clock.
 
A

alberto.poz

Looks like you might be onto something here...







Here, I get:

$ date "+%Z (%z)"
GMT (+0000)
$ export TZ="Europe/Rome"
$ date "+%Z (%z)"
CET (+0100)

It looks as though the zoneinfo, or your setting of TZ, is incorrect.

What happens if you unset TZ?
TZ should not be needed in a correctly configured RH setup.





So the Java timezone is correct.

--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : (e-mail address removed)
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555


Finally the mistery is solved.

/usr/share/zoneinfo/Europe/Rome was corrupted (0 in size). Replaced it
everything works fine.

Thank to everybody.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top