3

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

4
  • 7
    save yourself a lot of headache, use an existing library for this - I like JodaTime myself. Commented Mar 1, 2012 at 13:48
  • 2
    @Nim - Why not post that as an answer (maybe with some sample code) so we can give you some upvotes! Commented Mar 1, 2012 at 13:51
  • I was actually going to post this as an answer myself, but I didn't want to steal @Nim's thunder. Commented Mar 1, 2012 at 13:51
  • @Dave/Erick, I figured others would chime in with Joda anyway - I've added an answer, will update with some examples once the OP's intentions are clearer... Commented Mar 1, 2012 at 13:57

7 Answers 7

2

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"));
Sign up to request clarification or add additional context in comments.

1 Comment

That's the one!!!!!! Thanks Mark. Brilliant!! That works. I would agree with everyone else that Joda is probably better but in my case - can't be used.
2

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.

1 Comment

Thanks all for your responses.Ok - should have said at the beginning. I have to use the basic libraries as I'm unable to load anything else on the target machine.
0

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.

1 Comment

OK - but that still gives me 2:00
0

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.

1 Comment

That's just the problem. I don't 1:00, I get 2:00. BUt Mark's solution wrioks.
0

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.

5 Comments

Thanks Luiggi. I tried the calendar object but get the same results. My date/times are in seconds so can I use :
@MartinWalke it could be pretty tedious but you can even add or substract milliseconds on a Calendar instance. It would be better if you post your exact requirement and I'll edit my answer to solve it using Calendar methods.
Thanks Luiggi. Unfortunately, I only have the time in seconds. I would first have to convert to day/month/year/hr/mins/sec to use the code.addcode method.
@MartinWalke you can use Calendar c = Calendar.getInstance(); long l = c.getTimeInMillis() / 1000 so you get the time in seconds, use the value for your math operations and convert it again into a Date using c.setTimeInMillis(l*1000)
@MartinWalke I've already tested Mark's answer, and its the right solution for your problem :).
0

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.