36

I've tried a million different ways of doing this, but with no avail. Any help would be much appreciated.

long millis = getMillisFromServer();
Date date = new Date(millis);
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
String formatted = format.format(date);

The above doesn't work.

basically, what I want to do is, get the epoch time and convert it to Australian time. My local time is +05.30 but of course I don't want this to be a factor which contributes to this conversion.

EDIT-

Output when I run your exact code,

epoch 1318388699000

Wed Oct 12 08:34:59 GMT+05:30 2011

12/10/2011 03:04:59

12/10/2011 14:04:59

Hades
  • 3,916
  • 3
  • 34
  • 74
  • This code is fine. I don't understand what you want to achieve, and why this code isn't fine for you. Could you give an example with an input and an output of the code? – JB Nizet Oct 12 '11 at 13:46
  • Perhaps the problem the OP is worried about is that "Australia/Sydney" is not recognized as having an offset of 05:30 but rather +10. See http://ideone.com/qydGJ – Ray Toal Oct 12 '11 at 13:51
  • 2
    @Hades: Could you say in what *way* your code doesn't work? What are you seeing, and what were you expecting? The code works for me... – Jon Skeet Oct 12 '11 at 13:58

3 Answers3

41

EDIT: Okay, so you don't want your local time (which isn't Australia) to contribute to the result, but instead the Australian time zone. Your existing code should be absolutely fine then, although Sydney is currently UTC+11, not UTC+10.. Short but complete test app:

import java.util.*;
import java.text.*;

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Date date = new Date(1318386508000L);
        DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        format.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
        String formatted = format.format(date);
        System.out.println(formatted);
        format.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
        formatted = format.format(date);
        System.out.println(formatted);
    }
}

Output:

12/10/2011 02:28:28
12/10/2011 13:28:28

I would also suggest you start using Joda Time which is simply a much nicer date/time API...

EDIT: Note that if your system doesn't know about the Australia/Sydney time zone, it would show UTC. For example, if I change the code about to use TimeZone.getTimeZone("blah/blah") it will show the UTC value twice. I suggest you print TimeZone.getTimeZone("Australia/Sydney").getDisplayName() and see what it says... and check your code for typos too :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1318386508000 < that's the epoch time in milis. Now I want to convert that to Australian time. GMT+10. The local time on my phone is GMT+5. (I want to ignore this) – Hades Oct 12 '11 at 13:51
  • @Hades: Sydney time is currently UTC+11, not UTC+10. So if the only problem is that you were seeing it an hour differently to what you expected, it was probably just your expectations... – Jon Skeet Oct 12 '11 at 13:59
  • the problem is when I convert it..the system prints +0 GMT time instead of the Australian time. epoch 1318388699000 Wed Oct 12 08:34:59 GMT+05:30 2011 12/10/2011 03:04:59 12/10/2011 14:04:59 That's the output when i run your code epoch 1318388699000 Wed Oct 12 08:34:59 GMT+05:30 2011 12/10/2011 03:04:59 12/10/2011 14:04:59 – Hades Oct 12 '11 at 14:10
  • @Hades: What happens if you run the exact short but complete program in my answer? And what do you mean by "the system prints +0 GMT time"? Is it possible that your system doesn't know about the Australia/Sydney time zone? – Jon Skeet Oct 12 '11 at 14:11
  • I am running android, and i'm think it does know it. Edited my answer – Hades Oct 12 '11 at 14:13
  • @Hades: Ah - it would have been really helpful if you'd mentioned that you were on Android before... try looping through `TimeZone.getAvailableIDs()` and have a look at what's available. – Jon Skeet Oct 12 '11 at 14:14
  • @Hades: At the end of one comment you say you've got "12/10/2011 03:04:59 12/10/2011 14:04:59" - that's the right result, isn't it? – Jon Skeet Oct 12 '11 at 14:21
  • no it isn't...the gmt time is 14:26, australian time is 13:26...where is in this...gmt is 03.04 and australian time is 14.04? Am I missing something? – Hades Oct 12 '11 at 14:29
  • From your comment: "That's the output when i run your code epoch 1318388699000 Wed Oct 12 08:34:59 GMT+05:30 2011 12/10/2011 03:04:59 12/10/2011 14:04:59" Basically your comment contained a lot of times and it wasn't clear what you got from what code... – Jon Skeet Oct 12 '11 at 14:33
28

Here’s the modern answer (valid from 2014 and on). The accepted answer was a very fine answer in 2011. These days I recommend no one uses the Date, DateFormat and SimpleDateFormat classes. It all goes more natural with the modern Java date and time API.

To get a date-time object from your millis:

    ZonedDateTime dateTime = Instant.ofEpochMilli(millis)
            .atZone(ZoneId.of("Australia/Sydney"));

If millis equals 1318388699000L, this gives you 2011-10-12T14:04:59+11:00[Australia/Sydney]. Should the code in some strange way end up on a JVM that doesn’t know Australia/Sydney time zone, you can be sure to be notified through an exception.

If you want the date-time in your string format for presentation:

String formatted = dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"));

Result:

12/10/2011 14:04:59

PS I don’t know what you mean by “The above doesn't work.” On my computer your code in the question too prints 12/10/2011 14:04:59.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 1
    I think the problem was that the phone which was running android was in a different timezone when converting; I don't think it would matter when running it on a computer; which I figured out only later. Thanks for the updated answer. – Hades Jun 12 '17 at 23:41
  • 2
    It's almist always a good idea to give explicit time zone to one's time operations. Thanks for reporting back on your old issue. @Hades – Ole V.V. Jun 13 '17 at 04:21
  • Good one. Works smoothly. – NKM May 10 '22 at 10:09
17

Please take care that the epoch time is in second and Date object accepts Long value which is in milliseconds. Hence you would have to multiply epoch value with 1000 to use it as long value . Like below :-

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
Long dateLong=Long.parseLong(sdf.format(epoch*1000));
Anup Mehta
  • 171
  • 1
  • 3
  • 1
    For this to work `epoch` needs to be a `long`. It it’s an `int`, your multiplication will overflow and you will get an incorrect result. Also I don’t think the OP asked for a `Long` result, but maybe someone else can use it. – Ole V.V. Jun 12 '17 at 14:57
  • 2
    As Ole V.V. says you need to multiply `long` values. You could change the `1000` to `1_000L` with an `L` on the end to declare it as a 64-bit integer. The underscore is a new feature in recent versions of Java to make numeric literals more readable. – Basil Bourque Jun 14 '17 at 16:35