0

Ok, so I've pretty much tried everything. I bet it's something really simple but I can't seem to get a hold of it.

The server sends me the time, which is epoch. However when I put this into a date object it seems to automatically pick up the time zone and it adds +3 to the server time. So if the gmt time is 00.00, it says its 03.00.

I also need to add a timezone of my own. Let's say the epoch time is 00.00 again, it should read 10.00 after I add the timezone.

any help would be much appreciated. Thank you

Hades
  • 3,916
  • 3
  • 34
  • 74

2 Answers2

1

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Also, quoted below is a notice from the home page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        long millis = 1316391494L;

        Instant instant = Instant.ofEpochMilli(millis);
        System.out.println(instant);

        // The same instant at a specific timezone
        ZonedDateTime zdt = instant.atZone(ZoneId.of("Australia/Brisbane"));
        System.out.println(zdt);
    }
}

Output:

1970-01-16T05:39:51.494Z
1970-01-16T15:39:51.494+10:00[Australia/Brisbane]

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.

What went wrong with your code?

A java.util.Date object simply represents an instant on the timeline — a wrapper around the number of milliseconds since the UNIX epoch (January 1, 1970, 00:00:00 GMT). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        long millis = 1316391494L;
        Date date = new Date(millis);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX[zzzz]", Locale.ENGLISH);

        sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
        String strDateUtc = sdf.format(date);
        System.out.println(strDateUtc);

        sdf.setTimeZone(TimeZone.getTimeZone("Australia/Brisbane"));
        String strDateBrisbane = sdf.format(date);
        System.out.println(strDateBrisbane);
    }
}

Output:

1970-01-16T05:39:51.494Z[Coordinated Universal Time]
1970-01-16T15:39:51.494+10:00[Australian Eastern Standard Time]

ONLINE DEMO


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
1

"It seems to add" - I suspect you're using Date.toString() which does indeed use the local time zone. The Date object itself is effectively in UTC though. Use DateFormat to perform the conversion to a string instead, and you can specify which time zone to use. You may also need to use Calendar - it depends what you're trying to do.

(Alternatively, use Joda Time in the first place, which is a better API. It may be a little bulky for your Android project though. I wouldn't be surprised if there were a "Joda Time lite" project around somewhere for precisely this sort of thing...)

EDIT: Quick sample, although it's not entirely clear what you need...

long millis = getMillisFromServer();
Date date = new Date(millis);
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
format.setTimeZone(customTimeZone);
String formatted = format.format(date);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • could I have an example. I need to compare it against something else – Hades Sep 19 '11 at 10:02
  • @Hades: Have added one now, although it's not entirely clear what you're trying to do, or what format you need. – Jon Skeet Sep 19 '11 at 10:05
  • Let's say this is what I get from the server "1316391494", I want to convert that to Australian time...how do I go about doing that..using Joda Time or standard date util. – Hades Sep 19 '11 at 10:30
  • @Hades: It looks like that's in seconds - the first thing you need to do is multiply the value by 1000. Then just feed it into the code above using the appropriate Australian time zone, and it should be fine. – Jon Skeet Sep 19 '11 at 10:32