java.util.Date shows different values with the same input parameters
I try to System.out the same strings
System.out.println(" DATE 29 " + new Date(1330462800000l) + " Date 01 "
+ new Date(1330549200000l));
but I have different results when I check it in Build(running in console mode) and when i run application from eclipse.
output from eclipse(seems like it is correct result):
DATE 29 Wed Feb 29 00:00:00 EET 2012 Date 01 Thu Mar 01 00:00:00 EET 2012
output from build(console mode)
DATE 29 Tue Feb 28 23:00:00 EET 2012 Date 01 Wed Feb 29 23:00:00 EET 2012
Sorry for stupid question, but do you have any ideas about possible reasons?
PS:I use maven+tycho to make build, packaging-type eclipse-repository.(if it realy matter)
EDIT: In Eclipse I looked at timeZone value:
Calendar calendar=Calendar.getInstance();
System.out.println("!!!time zone before: " + calendar.getTimeZone());
!!!time zone before: sun.util.calendar.ZoneInfo[id="Europe/Minsk",offset=7200000,dstSavings=3600000,useDaylight=true,transitions=121,lastRule=java.util.SimpleTimeZone[id=Europe/Minsk,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=7200000,startTimeMode=1,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=7200000,endTimeMode=1]]
then I set timezone with hardcoded zoneId and made build
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Minsk"));
haven't any results
EDIT: I use different versions and architectures of jres in build and eclipse..Could it be the reason? EDIT:
System.out.println("!!!!!! system.timezone " + System.getProperty("user.timezone"));
System.setProperty("user.timezone", "Europe/Minsk");
System.out.println("!!!!!! system.timezone " + System.getProperty("user.timezone"));
!!!!!! system.timezone Europe/Minsk
!!!!!! system.timezone Europe/Minsk!!!calendar time after zone: sun.util.calendar.ZoneInfo[id="Europe/Minsk",offset=7200000,dstSavings=3600000,useDaylight=true,transitions=121,lastRule=java.util.SimpleTimeZone[id=Europe/Minsk,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=7200000,startTimeMode=1,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=7200000,endTimeMode=1]]
Correct timezone. but date is still wrong
Add to test:
System.out.println(Calendar.getInstance().getTimeZone());
or
System.getProperty("user.timezone");
Java timezone can be set by system property user.timezone, see Java system properties for details.
For time use joda time. You can redefine timezone for all joda objects:
DateTimeZone.setDefault(DateTimeZone.UTC);
tl;dr
Instant.ofEpochMilli( 1_330_462_800_000L ) // Convert count-of-milliseconds-since-epoch to an `Instant`, a moment on the timeline in UTC.
.atZone( ZoneId.of( "Europe/Minsk" ) ) // Adjust into another time zone. Same moment, different wall-clock time.
Avoid legacy date-time classes
You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes. Among the many flaws is the Date::toString
method's application of the JVM's current default time zone dynamically while generating a string. A Date
represents a moment in UTC but this well-intentioned anti-feature brings confusion. The JVM's current default time zone can change at any moment, even during runtime, so you may see various results.
java.time
Use java.time.Instant
in place of java.util.Date
.
Instant
The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.ofEpochMilli( 1_330_462_800_000L ) ;
Learn to think and work in UTC primarily . Think of UTC as the One True Time™. All other time zones are mere variations on that theme. While on the job as a programmer, forget about your personal local time, and stop converting back-and-forth between zones as that can drive you batty. Focus on UTC in your programming and logging.
ZonedDateTime
To view that same moment through the lens of another time zone, apply a ZoneId
to get a ZonedDateTime
object. We still have the same moment, the same point on the timeline, but with another wall-clock time.
ZoneId z = ZoneId.of( "Europe/Minsk" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
See this code run live at IdeOne.com.
instant.toString(): 2012-02-28T21:00:00Z
zdt.toString(): 2012-02-29T00:00+03:00[Europe/Minsk]
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.