String qtm = "00:02:00";
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
java.util.Date d = null;
try
{
d = formatter.parse(qtm);}
catch (java.text.ParseException e) {
System.err.println("Error: " + e.getMessage());
}
System.out.println(d);
this code gives me:-
Thu Jan 01 00:02:00 IST 1970
in my program I want to keep a time quantum of 2 minutes for roundrobin algo, how can I do that?? please help me.
when I give
long curr= d.getTime();
system.out.println(d);
it gives the output:-
-19500000
please tell me how to give just 2 minutes as an interval and to assign it to a variable....
The problem at the moment is that your SimpleDateFormat is in your local time zone, whereas Date.getTime() gives you the milliseconds since the Unix epoch in UTC.
You can fix this as:
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
... and then use getTime() as before.
Ideally, it would be better to use Joda Time or the Java 8 java.time package, both of which have a Duration type to represent this sort of value. Joda Time has a PeriodFormatter which could be used to parse this as a Period and convert that into a Duration, which is a bit long-winded, admittedly. I don't see a way of parsing straight to a Duration for either of them...
If you just want two minutes then why not go for the milliseconds equivalent (120000L) ?
If you are planning to use it within a scheduled thread pool executor, you could use (2, TimeUnit.Seconds).
IMHO, the solution really depends on what purpose you want to use it for.
Related
I know this has been asked several times and I am risking a downvote/duplicate close, but most of the questions posted here were resolved by chaing YYYY into yyyy..so, searching does not really help :/
These are the given timestamps inside the block
date new Block: 2017-11-02T06:17:05.079481
date old Block: 2017-11-02T06:17:04.608960
My conversion code:
public static Date getDate(JSONObject block){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
try {
return sdf.parse(block.get("timestamp").toString());
} catch (ParseException e) {
e.printStackTrace();
return new Date(0);
}
}
And this is the result of parse
date new block: Thu Nov 02 06:18:24 KST 2017
date old block: Thu Nov 02 06:27:12 KST 2017
How is that possible? The new block was created after the old block, as seen in the timestamp. but now it is the other way around
How is that possible? The new block was created before the old block, as seen in the timestamp. but now it is the other way around
S in a SimpleDateFormat format string always represents milliseconds - not just "fractions of a second" which is what you're assuming at the moment.
Your "new" block is being parsed as adding 79481 milliseconds whereas the "old" block has 608960.
That explains the results, but doesn't give you a way forward. There are two options here:
Use java.time.* - this is a much more modern API, with nanosecond precision instead of millisecond precision.
Drop the last three characters of your inputs, and parse to only millisecond precision.
Following up on Jon Skeet’s knowledgable answer, using java.time isn’t hard. The date-time format from your JSON block is ISO 8601, the standard format for exchange of date and time data, and the java.time classes parse this format as their default, that is, without the need for an explicit format:
String blockTimestamp = "2017-11-02T06:17:05.079481";
LocalDateTime dateTime = LocalDateTime.parse(blockTimestamp);
If you try printing the resulting dateTime, you will again see its default format, ISO 8601, since this is also what its toString method produces: 2017-11-02T06:17:05.079481.
The potential downside of LocalDateTime is it doesn’t represent an unambiguous point on the timeline. So if you know in which time zone to interpret the date and time, you will probably want to convert it to a ZonedDateTime, for example:
ZoneId koreaTimeZone = ZoneId.of("Asia/Seoul");
ZonedDateTime koreaDateTime = dateTime.atZone(koreaTimeZone);
This yields 2017-11-02T06:17:05.079481+09:00[Asia/Seoul].
In your Simple Date Format, you need to change 'DD' to lowercase 'dd'
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
This will hopefully solve your problem.
EDIT: Same is the case with hours. **
Replace **'HH' with 'hh' (lowercase).
Thanks
I'm trying to convert 5007 to HH:mm:ss:SSS, I'm using Netbeans IDE v8.2:
Date date = new Date(5007);
DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS");
String dateFormatted = formatter.format(date);
But this gives me an incorrect result:
01:00:05:007
^^-------------------------why does it print to me 01 in the hours?
But it should get:
00:00:05:007
^^-------------------------correct result
When I use ideone for example it gives me a correct result:
Any explication about this problem?
I testes with both versions: Java 7 and Java 8.
When you ask for the explanation of your problem I will be honest with you: You are misusing SimpleDateFormat for formatting a duration. It was never meant for this use and is not designed to give you the expected result if you try it anyway. The problem you got is not the only problem you will have. If your duration grows to more than 24 hours, the whole days will not be formatted, so your result will be wrong in a different way.
Apart from that, these days I recommend not using the SimpleDateFormat class at all. Its replacement is java.time.format.DateTimeFormatter, it came out in 2014 and comes with quite fewer negative surprises. It is not a good choice for formatting a duration either, though.
So what is a good choice? I will give you the Java 9 answer first because it is easy:
Duration dur = Duration.ofMillis(5007);
String hmss = String.format("%02d:%02d:%02d:%03d",
dur.toHours(),
dur.toMinutesPart(),
dur.toSecondsPart(),
dur.toMillisPart());
The main advantage isn’t even the ease, it’s the clarity. For example, with this code no one needs to ask the question I asked in a comment, is it a point it time or a duration? The code very clearly states that it is a duration.
For Java 6, 7 and 8, you may still use the Duration class (in Java 6 and 7 through the ThreeTen Backport), but it doesn’t lend itself that easily to formatting, so I think I would resort to using the TimeUnit enum as in the question I had linked to (the link you asked me to remove again):
long millis = 5007;
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
millis -= TimeUnit.SECONDS.toMillis(seconds);
String hmss = String.format("%02d:%02d:%02d:%03d", hours, minutes, seconds, millis);
The result is the desired
00:00:05:007
To illustrate the point I was trying to make about what happens when the duration is more than 24 hours, let’s try to give it 100 000 000 milliseconds (there are 86 400 000 millis in a day):
27:46:40:000
Date date = new Date(5007);
creates a Date which is 5007 milliseconds after January 1, 1970, 00:00:00 GMT.
When you format it with SimpleDateFormat, it is converted to your machine's timezone (which I'm assuming is GMT+1).
When I run your code I get
02:00:05:007
And my timezone is GMT+2.
If you set the timezone of the DateFormat instance to GMT, you'll get the expected output:
Date date = new Date(5007);
DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS");
formatter.setTimeZone (TimeZone.getTimeZone ("GMT"));
String dateFormatted = formatter.format(date);
System.out.println (dateFormatted);
This prints
00:00:05:007
It is definitely a Locale issue. When you do not specify one it will use the (your system) default one. To override this;
try either adding this
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
or passing a Locale when constructing the SimpleDateFormat instance. For example:
DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS", Locale.ENGLISH);
I assume Locale.ENGLISH has UTC timezone btw, but I hope you get the idea.
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.
I'm trying to do a simple subtraction of dates and getting odd results. For some reason when I format it with SimpleDateFormat, there are 7 extra hours difference.
package timedemo;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Timedemo {
public static void main(String[] args) {
Date start = new Date(); // time right now
Date stop = new Date();
long startTime = start.getTime()-1000; // introduce a second of skew
long stopTime = stop.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
// First one shows up prior to 1970 epoch. Okay, except for 5 hour variance.
// Probably a timezone thing, as I'm in EST (-5).
System.out.println("New date is "+new Date(stopTime - startTime));
System.out.println("Raw Start is "+startTime); // fine
System.out.println("Raw Stop is "+stopTime); // fine
System.out.println("Raw Difference is "+(stopTime-startTime));
System.out.println("Formatted Start is "+sdf.format(startTime));
System.out.println("Formatted Stop is "+sdf.format(stopTime));
System.out.println("Formatted Difference is "+sdf.format(stopTime-startTime));
}
}
And the results are:
New date is Wed Dec 31 19:00:01 EST 1969
Raw Start is 1418397344360
Raw Stop is 1418397345360
Raw Difference is 1000
Formatted Start is 10:15:44
Formatted Stop is 10:15:45
Formatted Difference is 07:00:01
I had thought it was a timezone thing, but I'm in EST (-5), not MST (-7).
I would suspect Daylight Savings, but it's 7 hours, not 1.
12/24 hour difference? 12-7=5 which is my timezone offset... not sure what to make of it though.
Kind of out of ideas at this point.
Why the seven hour shift on the last line?
The "12-7 = 5" is definitely related to the problem... or more accurately, it's "12-5=7", i.e. 5 hours before midnight is 7pm. You'll see that if you format it as a full date/time:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Heck, you can see that in your first line: "Wed Dec 31 19:00:01 EST 1969" - that 19:00 is 7pm, which you're formatting using hh as 07.
Fundamentally, the problem is that you're trying to treat a difference in time as if it's a point in time. I would very strongly urge you not to do that. If you absolutely want to do that (and the difference will always be non-negative but less than 24 hours), then you should set the time zone on SimpleDateFormat to UTC, and use HH instead of hh. But it would be better to use Joda Time or java.time from Java 8 which can represent a Duration, i.e. the difference between two points in time. Date is simply not an appropriate data type for that.
I'm trying to do simple date/time calculations and no matter what I do I'm getting confused with what appears to be time zones etc.
I need to add (and subtract)different date/times together so I figured the easiest way would be to convert them to seconds, perform the calculations and then format back to a string. But no matter what I do, I'm one hour out - which sounds like timezone/DST etc.
What's wrong with this:
long dateInMillis = 3600000L;
DateFormat formatter = new SimpleDateFormat("HH:mm");
Date dt = new Date();
dt.setTime(dateInMillis);
System.out.println( formatter.format(dt.getTime()));
The answer I get is 2:00. Even if I use:
long dateInMillis = 1;
I still get 1:00
Help please ;-)
TIA
Martin
I agree that using Joda is likely to make life easier. However what you are seeing is the effect of a TimeZone sensitive formatter.
You could try adding:
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Save yourself a lot of headache, use an existing library for this - I like Joda Time myself.
For example the DateTime class supports various calculations (to add or subtract specific periods etc.) If you want an example, post your exact requirement, and I'll add it to the answer.
You should not try and format a long as a date. Just use:
long dateInMillis = 3600000L;
DateFormat formatter = new SimpleDateFormat("HH:mm");
Date dt = new Date();
dt.setTime(dateInMillis);
System.out.println( formatter.format(dt));
However, I would use a 3rd party lib for handling time-calculations like JodaTime as #Nim suggested, if your calculations are in anyway complicated.
I also suggest to use a framework as suggested in the comments.
However, Date is based on the milliseconds after Jan. 1st 1970. So 3600000L is just one hour from there, so 1:00 is correct.
According to people here, you could use Joda Time to resolve this calculations. If you want to stay with pure Java code, you can look for Calendar class to do your operations with dates. Here is a sample:
Calendar c = Calendar.getInstance();
DateFormat df = new SimpleDateFormat("HH:mm");
Date d = c.getTime();
System.out.println(df.format(d)); //actual hour:minute
c.add(Calendar.HOUR, -4);
d = c.getTime();
System.out.println(df.format(d)); //actual hour:minute minus 4 hours
Still, I won't rely too much in this kind of code. You'll have less problems using Joda Time.
When you're calling new Date(), current date in current timezone is created. When you're calling 'dt.setTime(dateInMillis);' you set offset in milliseconds from 1 January 1970 in GMT timezone. Let me explain, here in Msk, first call will give me Thu Mar 01 17:02:22 MSK 2012, the second call will give me 1 hour offset, thus in Msk it will be original offset (+3) plus 1, so it'll be Thu Jan 01 04:00:00 MSK 1970. Then when you're calling formatter.format(? extends Number) it calls new Date(((Number)obj).longValue()) inside, so it creates back you date which is Thu Jan 01 04:00:00 MSK 1970 and prints hours and minutes. So, you're right, it prints out time in your current timezone.
For posterity, here's example code using the Joda-Time 2.3 library as mentioned by the other answers and comments.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
long dateTimeInMillis = 3600000L; // 1,000 * 60 * 60 = 3600000L = 1 hour.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html (not quite up-to-date, read page for details)
DateTime dateTimeInUtc = new DateTime( dateTimeInMillis, DateTimeZone.UTC );
// Paris happens to be one hour ahead of UTC/GMT.
DateTime dateTimeInParis = dateTimeInUtc.toDateTime( DateTimeZone.forID( "Europe/Paris" ) );
Dump to console…
System.out.println( "dateTimeInUtc: " + dateTimeInUtc );
System.out.println( "dateTimeInParis: " + dateTimeInParis );
When run…
dateTimeInUtc: 1970-01-01T01:00:00.000Z
dateTimeInParis: 1970-01-01T02:00:00.000+01:00