This seems like a stupid question, but I am not able to understand this creepy behavior. I am completely aware of the fact that java
Epoch timestamp: 1389975349
Timestamp in milliseconds: 1389975349000
Human time (GMT): Fri, 17 Jan 2014 16:15:49 GMT
Human time (your time zone): Friday, January 17, 2014 9:45:49 PM
Date dt = c.getCreatedDate();
DateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm a z");
17/01/2014 04:15 PM IST
17/01/2014 10:45 AM UTC
GMT: Fri, 17 Jan 2014 10:45:49 GMT
Your time zone: Friday, January 17, 2014 4:15:49 PM GMT+5.5
Your question could use some rewriting.
If I make a select query – You should explain this and give the exact query statement.
Since dealing with two separate servers (database server, web app server), each with a different time zone setting, you should separate the question more cleanly. Indeed, the MySQL server seems to be just a red herring, a distraction.
Instead of talking about the irrelevant MySQL server, you should have tested and reported the actual time. Easy to do… Just google "current time in utc".
Thus the old sailors' adage: Use one compass or three, but never two.
Three-letter time zone codes are outmoded, being neither standardized nor unique. "IST" means "India Standard Time" and "Irish Standard Time", for example.
The java.util.Date & Calendar classes are notoriously bad and confusing, as you've come to see. Avoid them. Use either the open-source third-party Joda-Time or, in Java 8, the new java.time.* classes (inspired by Joda-Time).
The code below uses Joda-Time 2.3 and Java 8 on a Mac with US west coast time zone.
Let's establish that 1389975349000L ≈ 16:15 UTC ≈ 21:45 India.
This agrees with EpochConverter.com, as the question stated.
// Specify a time zone rather than depend on defaults. DateTimeZone timeZoneKolkata = DateTimeZone.forID( "Asia/Kolkata" ); long millis = 1389975349000L; DateTime dateTimeUtc = new DateTime( millis, DateTimeZone.UTC ); DateTime dateTimeKolkata = dateTimeUtc.toDateTime( timeZoneKolkata );
Dump to console…
System.out.println( "millis: " + millis ); System.out.println( "dateTimeUtc: " + dateTimeUtc ); System.out.println( "dateTimeKolkata: " + dateTimeKolkata );
millis: 1389975349000 dateTimeUtc: 2014-01-17T16:15:49.000Z dateTimeKolkata: 2014-01-17T21:45:49.000+05:30
The question mentions a second number: 1389955549000L.
That number turns out to be the same date as the first number, with different time.
Let's establish that 1389955549000L ≈ 10:45 UTC ≈ 16:15 India.
long mysteryMillis = 1389955549000L; DateTime mysteryUtc = new DateTime( mysteryMillis, DateTimeZone.UTC ); DateTime mysteryKolkata = mysteryUtc.toDateTime( timeZoneKolkata );
Dump to console…
System.out.println( "mysteryMillis: " + mysteryMillis ); System.out.println( "mysteryUtc: " + mysteryUtc ); System.out.println( "mysteryKolkata: " + mysteryKolkata );
mysteryMillis: 1389955549000 mysteryUtc: 2014-01-17T10:45:49.000Z mysteryKolkata: 2014-01-17T16:15:49.000+05:30
I'm not 100% sure, but…
→ Your web app server machine seems to have its clock set improperly, set to UTC time rather than India time.
The web app server is apparently let to 16:15 time in the India time zone, but apparently at that moment the true time in India was 21:45. In other words, the time did not match the time zone.
Mixing UTC time with non-UTC time zone = WRONG.
If you set an Indian time zone, then set an Indian time to match.
Note that we have "16:15" in common in both sets of numbers.
The java.util.Date class has a very bad design where it has no time zone information itself BUT applies the Java Virtual Machine's default time zone in its implementation of
toString. This is one of many reasons to avoid this class, but may be key to your problem.
Avoid java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat classes. Use only as required for exchanging values as needed with other classes.
Use Joda-Time or the new java.time.* classes (JSR 310).
Specify a time zone, never rely on default time zone.
Match the time to time zone on each server. Verify by googling "current time in utc".
Set host server’s operating system’ time zone to
GMT where possible. No such choice on some OSes, so choose "Atlantic/Reykjavik" as a workaround, because Iceland stays on UTC/GMT year-round without any Daylight Savings Time nonsense.
Do not set the JVM’s default time zone with a call to
TimeZone.setDefault (except as a last resort in the worst situations). Setting the default is rude, as it immediately affects all the code in all the threads in all the apps running in that JVM. And it is unreliable as any of that other code can change it on your app, during runtime. Instead, specify a time zone in all your date-time code. Never rely implicitly on the JVM’s current default. Both Joda-Time and java.time have methods that take an argument of time zone. So, while it is a good practice to set all your server computers’ host OS’ time zone to UTC, you should never depend on that in your Java code.