Get server date problem - java

I have problem with getting server date (linux server). When I use linux 'date' command I get properly date value (real date). If I modify some file
on server, modify date is also properly (real date). But if i use java code System.out.println(new Date()) on server I get date with 1 hour difference
i.e. linux 'date' command result = Wed Sep 16 08:48:25 CEST, System.out.println(new Date()) result = Wed Sep 16 07:48:25 GMT+1
Is this linux configuration problem or wrong getting date using java.
Thanks
date --rfc-2822; date +%s
Wed, 16 Sep 2009 09:59:36 +0200
1253087976
System.out.println(new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z").format(new Date()));
System.out.println(new Date().getTime() / 1000);
16 wrz 2009 09:00:33 +0100
1253088033

You must make sure you use the correct time zone before using Date (or Calendar, for that matter - wasn't Date deprecated?).
For instance:
/* Skipping the boring class def part. */
public static void main(String[] args) {
Date date = new Date();
DateFormat myDateFormat = new SimpleDateFormat();
TimeZone firstTime = TimeZone.getTimeZone(args[0]);
myDateFormat.setTimeZone(firstTime);
System.out.println("-->"+args[0]+": " + myDateFormat.format(date));
}
the argument then can be your desired time zone, for example "IST", "GMT", or whatever.

This is probably a timezone/daylight savings issue. Use:
java.util.Timezone.getDefault()
to see which timezone is Java configured to use and whether daylight savings apply or not.

I suggest you upgrade your Java installation. Your JRE likely doesn't have the latest daylight savings rules in place. Java gets the time since the epoch, and uses your current TZ setting to compute what the local time is. DST rules change from time to time, and both the operating system and the JDK need to be updated when this occurs.
Can you add the output of the following to your question:
# unix
date --rfc-2822; date +%s
# Java
System.out.println(new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z").format(new Date()));
System.out.println(new Date().getTime() / 1000);
The should both output something like:
Wed, 16 Sep 2009 17:26:08 +1000
1253085968

Related

Changing Java Timestamp format causes a change of the timestamp

I'm a bit puzzled regarding the Java timestamp formatting functions as they seem to change the timestamp by a few minutes.
My Pivotal CloudFoundry app writes a new entry into a PostgreSQL 9.4.5 database. Doing so, I let PostgreSQL generate and store a timestamp for that entry (within the SQL statement I use 'now()' for that particular column).
All that works fine so far. Problems arise when I read the entry with my app because I have to format the timestamp to ISO 8601 (company policy) and this seems to change the timestamp. I've used this code:
public String parseTimestamp(String oldDate) {
System.out.println("String oldDate: " + oldDate);
TimeZone timeZone = TimeZone.getTimeZone("Europe/Berlin");
SimpleDateFormat oldDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSS");
SimpleDateFormat newDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
newDateFormat.setTimeZone(timeZone);
Date tempDate = null;
try {
tempDate = oldDateFormat.parse(oldDate);
} catch (ParseException e) {
//TODO
}
System.out.println("tempDate before format(): " + tempDate);
String newDate = newDateFormat.format(tempDate);
System.out.println("tempDate after format(): " + tempDate);
System.out.println("String newDate: " + newDate);
return newDate;
}
Output:
String oldDate: 2018-06-18 13:07:27.624828+02
tempDate before format(): Mon Jun 18 13:17:51 CEST 2018
tempDate after format(): Mon Jun 18 13:17:51 CEST 2018
String newDate: 2018-06-18T13:17:51Z
As you can see, the timestamp changed from 13:07 to 13:17. All the other queried entries also show a difference, varying between ~2 to 10 minutes. However, when I re-run the query, each difference stays the same. OPs told me that all involved systems have synchronised time and I'm not sure if system time should play a role here at all.
Does someone know what is going on?
First, I was really puzzled and thought, you might have found some kind of bug in SimpleDateFormat. Your code can be reduced to the following lines to show the same behaviour:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSS");
String str = "2018-06-18 13:07:27.624828+02";
System.out.println(str);
System.out.println(format.parse(str));
Result:
2018-06-18 13:07:27.624828+02
Mon Jun 18 13:17:51 CEST 2018
The parsed Date object got ten additional minutes (and some seconds).
Taking a closer look reveals the problem - it is NOT a bug in JDK:
Your millisecond-part is 624828 - these are six(!) digits (not three). 624828 milliseconds are about 624 seconds, which are 10 minutes and 24 seconds.
The SimpleDateFormat correctly summed up this additional seconds and minutes.
What's wrong too: Your date format contains five digits for the milliseconds part.
Solution:
The (new) Java Time API can handle larger fractions of a second - and also convert easily between different time zones:
String str = "2018-06-18 13:07:27.624828+02";
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSx");
OffsetDateTime date = OffsetDateTime.parse(str, pattern);
System.out.println(date);
System.out.println(date.withOffsetSameInstant(ZoneOffset.UTC));
Result:
2018-06-18T13:07:27.624828+02:00
2018-06-18T11:07:27.624828Z
Your input date contains micro seconds but SimpleDateFormat supports only milli seconds (up to 3 digits). When parsing the value with the flag lenient enabled the complete 6 digits are evaluated as micro seconds. So at the end you have 624 seconds that are added to the date additionally.
You can try to use the SSSSSS pattern with DateTimeFormatter that has been introduced in Java 8.
But you may have further issues. Your code parses the input date without the time zone information +02 that is included at the end. You should add one letter X for the ISO8601 time zone format. When formatting the date for outputting you use letter 'Z' that indicates time zone UTC. But you set time zone CET (Berlin). So the output date is not in UTC. The correct ouput in UTC for the specified input date is:
2018-06-18 11:07:27Z

Converting java.util.Date to java.sql.Timestamp results into wrong value

Server side code (server timezone is UTC):-
Date aDate = new Date();
java.sql.Timestamp aTimestamp = new java.sql.Timestamp(aDate.getTime());
Client side (Mobile app, timezone GMT +5:30):-
Hitting a service request which runs above code on server side
The issue is when i debugged on server, found following values :-
aDate.getTime() prints to -> 1470472883877 milliseconds i.e., Sat Aug 06 2016 14:11:23 GMT+0530
but
aTimestamp prints to -> (java.sql.Timestamp) 2016-08-06 08:41:44.109
It's kinda weird, i've no idea what's going on in conversion !! please help
UTC and GMT are formats.
java.util.Date and java.sql.Timestamp are independent of the timezone. They store a long time in ms for representing their inner state.
For information, Calendar is timezone aware.
So with Date or Timestamp, to differentiate GMT or UTC format in an output, you have to use a formater which outputs the date into string by being aware the timezone.
In your output : 2016-08-06 08:41:44.109, you don't use a formater which is aware of the timezone. It's probably the result of a toString() on the java.sql.Timestamp instance or something of similar.
What you consider as a conversion is not a conversion but a formatting since the timestamp stays the same between the two objects.
If you want to display in the UTC format, use the appropriate formater with a
SimpleDateFormat for example :
SimpleDateFormat dt= new SimpleDateFormat("MM/dd/yyyy hh:mm:ss z");
dt.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateStringInUTC = dt.format(new Date(yourSqlTimestamp.getTime()));
The following is probably what you are looking for:
Calendar cal = Calendar.getInstance(Locale.GERMANY); // use your locale here
Timestamp aTimestamp = new Timestamp(cal.getTimeInMillis());
System.out.println(aTimestamp);
System.out.println(cal.getTime());
And the output:
2016-08-06 19:12:54.613
Sat Aug 06 19:12:54 CEST 2016

SimpleDateFormat ignoring DST offset in Android

In Central Europe, the current time zone (as of 3rd October) is:
CEST / UTC+2
But when I create an instance of SimpleDateFormat in Android now ...
dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
... it returns CET / UTC+1 as the time zone. So it's ignoring the DST offset which must still be there at the moment. Why is this?
Furthermore, when using the (now deprecated) method getTimezoneOffset() of Date instances, it returns inconsistent results:
(new Date()).getTimezoneOffset() correctly returns -120 (2 hours) while dateTimeFormat.parse("2012-10-03T22:00:00.000+0000").getTimezoneOffset() returns -60 (1 hour).
How can this happen? Am I doing something wrong or is this a known bug?
Note: I've heard that there are libraries which offer better time calculations (e.g. Joda Time), and I've heard that quite often now ;) But using some workarounds, you can just as easily use the built-in Java time library.
And, of course, the timezone is correctly set on my machine.
I don't know if I have properly understood your use case, but from what I have understood when I try this code.
public static void main(String[] args) {
SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String date="2012-10-03T22:00:00.000+0000";
try {
System.out.println(dateTimeFormat.getTimeZone().getDisplayName());
System.out.println("Today : "+new Date().toString()+ ", Timezone Offset :" +
+(new Date()).getTimezoneOffset());
System.out.println("Parsed Date : "+
dateTimeFormat.parse(date).toString()
+ ", Timezone Offset : "
+dateTimeFormat.parse(date).getTimezoneOffset());
} catch (ParseException e) {
e.printStackTrace();
}
}
I am getting an consistent Output i.e :
Central European Time
Today : Wed Oct 03 09:44:56 CEST 2012, Timezone Offset : -120
Parsed Date : Wed Oct 03 23:00:00 CEST 2012, Timezone Offset : -120
I have just switched to JODA with is great.
It also works good on Android with the comments in this link:
Android Java - Joda Date is slow
That make it run faster.

Converting unix timestamp to date in Android emulator

I have a timestamp I want to convert to a date. I tried this timestamp: 1336425840. This should be Mon, 07 May 2012 21:24:00 GMT, where GMT is the timezone the emulator should be set to. I tried this:
final Calendar c = Calendar.getInstance();
c.setTimeInMillis(1336425840*1000);
Date d = c.getTime();
Log.i("MyTag", "Hours: " + d.getHours());
The result is: Hours: 23.
So it seems like the returned date is computed according to GMT+2, which is the timezone set for my system. I expected g.hetHours() to return 21, since the emulator's timezone seems to be set to GMT.
Also, that timestamp results from reading the actual date in C using mktime, which seems to return the correct timestamp. But Java seems to refer to a different timezone. Am I doing anything wrong? Why isn't Mon, 07 May 2012 21:24:00 GMT returned?
I'm pretty sure 1336425840*1000 will give you a value outside the regular range of int. In fact, if you would print the full date of the Calendar object, you'll see it displays Thu Jan 08 23:56:50 GMT 1970, which explains the 23 hours you see.
Change the multiplication to: (note the L at the end)
c.setTimeInMillis(1336425840 * 1000L);
// Edit: easy to confirm:
System.out.println((1336425840 * 1000L > Integer.MAX_VALUE));
:)
You should use a DateFormat object, and then set the time zone with setTimeZone().

java.util.Date returning different dates in JDK 5 and JDK 6

The below code when run with JDK5(1.5.0_09) prints
Fri May 03 00:00:00 GMT 3912
5/3/12 5:30 AM
and when run with JDK6(1.6.0_23) prints
Fri May 03 00:00:00 IST 3912
5/3/12 12:00 AM
Obviously the difference is because of the timezone used then the Date object is created. But doesn't this cause problems for existing code when the JDK is upgraded? Is this behavior documented somewhere or am I missing something?
class TimeTest {
public static void main(String[] args) {
Date d = new Date(2012, 04, 3);
Locale l = new Locale("en", "US","");
DateFormat df= DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, l );
TimeZone t = TimeZone.getTimeZone("Asia/Calcutta");
df.setTimeZone(t);
System.out.println(d);
System.out.println(df.format(d));
}
}
The strange year 3192 is arising because that deprecated Date constructor assumes you are using a 2-digit year with 0 meaning 1900. It adds 1900 to the year number.
The difference in the timezones is not the fault of the Date constructor. Your code is using TimeZone.getTimeZone("Asia/Calcutta") to get the timezone. That method is documented as returning the GMT timezone if it doesn't recognize the timezone string. It would appear that Sun ADDED support for more timezones in Java 1.6. (Most people would view this as a good thing rather than as a portability concern.)
I haven't tried it, but the following should be sufficient to insulate yourself against using GMT when your requested zone id is unrecognised.
public TimeZone getZone(String id) {
TimeZone tz = TimeZone.getTimeZone();
if (!tz.getID().equals(id)) {
throw new IllegalArgumentException("unrecognized zone " + id);
}
return tz;
}
In summary, your code is broken in two respects:
It is using a deprecated constructor.
It is assuming that getTimeZone will understand all of your timezone Strings, and this is clearly not the case for Java 1.5.

Categories