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


Solution 1:

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 :)

Solution 2:

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.

Solution 3:

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));