Why UTC timezone giving ahead time for System.currentTimeMillis in Java? - java

I am getting current time from Ruby on Rails webservice in Unix Timestamp format (ie. in seconds from 1 Jan 1970), the timezone on server is UTC.
In Java I am trying to convert local current time to UTC time. But every time it is giving 6+ minutes ahead time. I want to get the difference of UTC current time and the time returned from service. My Java code is -
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
Date utc_current = new Date(System.currentTimeMillis());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
long serverTime = 1424936268000L;
long resTime = sdf.getCalendar().getTimeInMillis() - serverTime;
System.out.println("Time Diff : " + resTime);
Where serverTime is the time I am getting from webservice. And the value for resTime shows negative value which is approx 6+ minutes.
So my question is why UTC timezone giving ahead time for System.currentTimeMillis?

In contrast to the assumption in a comment of of #JB Nizet the expressions sdf.getCalendar().getTimeInMillis() and System.currentTimeMillis() are not equivalent. Proof:
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
System.out.println("date via System.currentTimeMillis()=" + f.format(utc_current));
System.out.println("date via sdf.getCalendar()=" + f.format(new Date(resTime)));
Output:
date via System.currentTimeMillis()=2015-02-26T12:19:09
date via sdf.getCalendar()=1889-12-31T04:41:21
If you carefully study the source code of SimpleDateFormat and DateFormat you will find within the initialization part code like:
private void initializeDefaultCentury() {
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add( Calendar.YEAR, -80 );
parseAmbiguousDatesAsAfter(calendar.getTime());
}
The conclusion is to strictly avoid the method getCalendar() on your DateFormat-object. It is only used as intermediate mutable object for internal format and parse processing. It is hard to say what you will really get as time this way. Instead use directly System.currentTimeMillis() to compare your local time with server time.
Another problem is the pattern you use. "dd-MM-yyyy hh:mm:ss" is probably not correct because it uses the clock hour of half day in range 1-12 but the information for am/pm is missing. Use better the pattern symbol HH. Check the documentation of webservice for the right format.

Make sure the the clock on the server and on the client machine are synchronized. The 6 minutes could simply be an offset between the two.

Related

How to find epoch format current time of GMT using java

I have written below code which is running, and giving output. But I'm not sure It's a right one.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = new Date();
sdf.setTimeZone(TimeZone.getTimeZone("GMT-7"));
String value = sdf.format(date);
System.out.println(value);
Date date2 = sdf.parse(value);
long result = date2.getTime();
System.out.println(result);
return result;
The above code what I'm trying is, I just need to get the current time of GMT time zone and convert it as epoch format which is gonna used in Oracle db.
Can someone tell me that format, and the above code is right?
First, you should not store time since the epoch as a timestamp in your database. Look into the date-time datatypes that your DMBS offers. In Oracle I think that a date column will be OK. For most other DBMS you would need a datetime column. timestamp and timestamp with timezone may be other and possibly even sounder options depending on your exact requirements.
However, taking your word for it: Getting the number of milliseconds since the epoch is simple when you know how:
long millisecondsSinceEpoch = System.currentTimeMillis();
System.out.println(millisecondsSinceEpoch);
This just printed:
1533458641714
The epoch is defined in UTC, so in this case we need to concern ourselves with no other time zones.
If you needed seconds rather than milliseconds, it’s tempting to divide by 1000. However, doing your own time conversions is a bad habit since the libraries already offers them, and using the appropriate library methods gives clearer, more explanatory and less error-prone code:
long secondsSinceEpoch = Instant.now().getEpochSecond();
System.out.println(secondsSinceEpoch);
1533458641
You said:
I just need to get the current time of GMT time zone…
Again taking your word:
OffsetDateTime currentTimeInUtc = OffsetDateTime.now(ZoneOffset.UTC);
System.out.println(currentTimeInUtc);
long millisecondsSinceEpoch = currentTimeInUtc.toInstant().toEpochMilli();
System.out.println(millisecondsSinceEpoch);
2018-08-05T08:44:01.719265Z
1533458641719
I know that GMT and UTC are not exactly the same, but for most applications they can be (and are) used interchangeably.
Can someone tell me (if) the above code is right?
When I ran your code just now, its output agreed with mine except the milliseconds were rounded down to whole thousands (whole seconds):
1533458641000
Your code has some issues, though:
You are using the old, long out-dated and poorly designed classes SimpleDateFormat, Date and TimeZone. The first in particular has a reputation for being troublesome. Instead we should use java.time, the modern Java date and time API.
Bug: In your format pattern string you are using lowercase hh for hour of day. hh is for hour within AM or PM, from 1 through 12, so will give you incorrect results at least half of the day. Uppercase HH is for hour of day.
Don’t use GMT-7 as a time zone. Use for example America/Los_Angeles. Of course select the time zone that makes sense for your situation. Edit: You said:
I just want to specify the timezone for sanjose. GMT-7 is refer to
sanjose current time.
I believe many places are called San Jose. If you mean San Jose, California, USA, you are going to modify your program to use GMT-8 every time California goes back to standard time and opposite when summer time (DST) begins?? Miserable idea. Use America/Los_Angeles and your program will work all year.
Since you ask for time in the GMT time zone, what are you using GMT-7 for at all?
There is no point that I can see in formatting your Date into a string and parsing it back. Even if you did it correctly, the only result you would get would be to lose your milliseconds since there are no milliseconds in your format (it only has second precision; this also explained the rounding down I observed).
Links
Oracle tutorial: Date Time explaining how to use java.time, the modern Java date and time API.
San Jose, California on Wikipedia
Why not use Calendar class?
public long getEpochTime(){
return Calendar.getInstance(TimeZone.getTimeZone("GMT-7")).getTime().getTime()/1000; //( milliseconds to seconds)
}
It'll return the current Date's Epoch/Unix Timestamp.
Based on Harald's Comment:
public static long getEpochTime(){
return Clock.system(TimeZone.getTimeZone("GMT-7").toZoneId() ).millis()/1000;
}
Here is a solution using the java.time API
ZonedDateTime zdt = LocalDateTime.now().atZone(ZoneId.of("GMT-7"));
long millis = zdt.toInstant().toEpochMilli();

Java (Processing Environment) will not provide me with the local time

I'm trying to get the epoc time adjusted for the local timezone (i.e. GMT-7, but it displays GMT). I'm fairly sure this should work, but it's not...
Calendar localTime = new GregorianCalendar(TimeZone.getDefault());
Date dd = localTime.getTime();
long t = dd.getTime()/1000;
System.out.printf("%d\n",t);
But it still outputs the epoc time based on GMT, not GMT-7 (my timezone). After playing around for some time I did get this to work...
Date ddd = new Date();
long t = ddd.getTime() + TimeZone.getDefault().getOffset( ddd.getTime() );
t = t/1000;
But why isn't the first block working?
A Date object simply wraps the UTC time in milliseconds since the epoch. This is how all time is represented 'under the hood' in Java. This also makes it consistent to work with. Whenever you want to print something out, apply the TimeZone offset and DST offset to it.
This is why the SimpleDateFormat class accepts a TimeZone but there is no TimeZone setter on the Date class.
Obligatory: I have heard Joda Time is a much easier to use datetime API.
Also, have a look at this post on the standard date and time libraries in Java.

How can I print a Date without timezone?

I have a mobile application where I capture a date/time and send it as miliseconds to a servlet. -For example I capture 12:55 AM in my cellphone and send it to my server-
So, I construct the date from the sent miliseconds and print it with SimpleDateFormat but the time is diferent, it prints 8:55 AM.
I know that the problem is because I use 2 diferent timezones, my question is:
how can I show that time without apply any timezone to show the same time?
Thanks in advance
You need to use Calendar to change the TimeZone but there is no API for that.
// Change a date in another timezone
public static Date changeTimeZone(Date date, TimeZone zone) {
Calendar first = Calendar.getInstance(zone);
first.setTimeInMillis(date.getTime());
Calendar output = Calendar.getInstance();
output.set(Calendar.YEAR, first.get(Calendar.YEAR));
output.set(Calendar.MONTH, first.get(Calendar.MONTH));
output.set(Calendar.DAY_OF_MONTH, first.get(Calendar.DAY_OF_MONTH));
output.set(Calendar.HOUR_OF_DAY, first.get(Calendar.HOUR_OF_DAY));
output.set(Calendar.MINUTE, first.get(Calendar.MINUTE));
output.set(Calendar.SECOND, first.get(Calendar.SECOND));
output.set(Calendar.MILLISECOND, first.get(Calendar.MILLISECOND));
return output.getTime();
}
Link: http://blog.vinodsingh.com/2009/03/date-and-timezone-in-java.html
I think this should work. I haven't extensively tested it.
Calendar and Date objects store their date information in milliseconds in relation to UTC.
(the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC)
This means that Calendar/Date Objects do not store different values for different Time Zones. They always use the same value internally... the format is what normally changes.
Maybe you can use a SimpleDateFormat in your local/default timezone:
SimpleDateFormat sdf = new SimpleDateFormat("S")
Date d = sdf.parse(milliseconds);
You can also try to change the DateFormat's timezone until it matches your expected output.
sdf.setTimeZone(TimeZone.getTimeZone("GMT-8"));
System.out.println(sdf.toString());
sdf.setTimeZone(TimeZone.getTimeZone("GMT-4"));
System.out.println(sdf.toString());

Date difference includes Timezone offset, what's wrong?

I have this code:
Date now = new Date();
// the string is in UTC format, so a UTC date must be constructed, I don't know if that happens in this format
Date measure = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(utcDateTime);
long diff = now.getTime() - measure.getTime();
if (diff < 1000* 60 * 15) {
// measure is less then 15 minutes recent
do some work
}
When I get the diff, it includes the timezone. I know the Date object internally is UTC.
So what's wrong here?
While a Date object is indeed in UTC, your SimpleDateFormat may not be. I suspect it default's to the system time zone - that's certainly what experimentation would suggest. You can change this using DateFormat.setTimeZone. So if your text represents a UTC date/time, you should set the time zone of the formatter to UTC as well.
Or you could use Joda Time, which is a generally better date and time API :)

Get Time in London

How can I get the current local wall clock time (in number of millis since 1 Jan 1970) in London? Since my application can run on a server in any location, I think I need to use a TimeZone of "Europe/London". I also need to take Daylight Savings into account i.e. the application should add an hour during the "summer".
I would prefer to use the standard java.util libraries.
Is this correct?
TimeZone tz = TimeZone.getTimeZone("Europe/London") ;
Calendar cal = Calendar.getInstance(tz);
return cal.getTime().getTime() + tz.getDSTSavings();
Thanks
I'm not sure what this quantity represents, since the "number of millis since 1 Jan 1970" doesn't vary based on location or daylight saving. But, perhaps this calculation is useful to you:
TimeZone london = TimeZone.getTimeZone("Europe/London");
long now = System.currentTimeMillis();
return now + london.getOffset(now);
Most applications are better served using either UTC time or local time; this is really neither. You can get the UTC time and time in a particular zone like this:
Instant now = Instant.now(); /* UTC time */
ZonedDateTime local = now.atZone(ZoneId.of("Europe/London"));
Others have said that it may well not be a good idea to do this - I believe it depends on your situation, but using UTC is certainly something to consider.
However, I think you've missed something here: the number of seconds which have occurred since January 1st 1970 UTC (which is how the Unix epoch is always defined - and is actually the same as in London, as the offset on that date was 0) is obtainable with any of these expressions:
System.currentTimeMillis()
new Date().getTime()
Calendar.getInstance().getTime().getTime()
If you think about it, the number of milliseconds since that particular instant doesn't change depending on which time zone you're in.
Oh, and the normal suggestion - for a much better date and time API, see Joda Time.
To get the current time in London:
SimpleDateFormat f = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(f.format(GregorianCalendar.getInstance().getTime()));

Categories

Resources