0

I am trying to get local time from UTC timestamp and calculating offset . I have a UTC time =1484063246 Here is my code.

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
       dateFormat.setTimeZone(TimeZone.getTimeZone("CET"));
       String formattedDate = dateFormat.format(new Date(1484063246L * 1000L)); 

The formattedDate is returning in date format. How to calculate difference between UTC time and local time from these values. How to setTimeZone based on where server is running instead of hardcoding "CET".

madhu
  • 129
  • 2
  • 6
  • 15

4 Answers4

2

If I understand your question, you can do (JSE >= 1.8):

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

Instant instant = Instant.ofEpochMilli(1484063246L * 1000L);

// You can use this if you already have a Date object
// Instant instant = dateInstance.toInstant();

// You can use this for current offset
// Instant instant = Instant.now(); 

ZoneId.systemDefault().getRules().getOffset(instant);

systemDefault() returns the system default (local) ZoneId and getOffset(instant) returns the offset from that zone to UTC for the specified instant.

e.g.

+01:00 for Europe/Berlin

-02:30 for Canada/Newfoundland

Z for UTC (care any number conversion!!)

Give a look at official docs for details.

EDIT: removed the use of Date class because of its avoidable import (as hinted by Basil Bourque's answer). By the way Date class is old but a very simple and never deprecated class. In fact it is a light abstraction over pure milliseconds.

Linuslabo
  • 1,568
  • 2
  • 24
  • 34
  • @madhu If it works, you can mark it as the correct answer :) – Linuslabo Jan 11 '17 at 17:36
  • why random number or seconds instead of Instant.now() ? – Ewoks Nov 07 '17 at 12:43
  • @Ewoks from OP's question. You can find `Instant.now()` in comments as well :) The offset in question may vary in time and you may be interested to find it out for a specific instant, – Linuslabo Nov 08 '17 at 07:52
0

Get the current timestamp in millisecs and subtract from 1484063246. Start with example below. You will also need to check if offset is positive/negative.

    long now = System.currentTimeMillis();
    long offset = now - 1484063246L * 1000;
    Date date = new Date(offset);
    DateFormat df = new SimpleDateFormat("HH:mm:ss");
    System.out.println(df.format(date));
mapm
  • 1,315
  • 12
  • 14
0

tl;dr

ZoneId.of( "Europe/Paris" )
      .getRules()
      .getOffset( 
          Instant.ofEpochMilli( 1_484_063_246L ) 
      ).getTotalSeconds()

Be careful about the word 'local'

In the Java date-time classes, the word local as in LocalDate, LocalTime, and LocalDateTime mean any locality, no specific locality. These classes purposely have no concept of time zone or offset. Definitely not what you want in the context of this Question.

Avoid legacy date-time classes

The Answer by Linuslabo is correct, and headed in the right direction using the java.time classes, but unnecessarily involves the old legacy java.util.Date class.

Avoid the old legacy date-time classes (Date, Calendar, SimpleDateFormat, etc.) as they have proven to be confusing, poorly designed, and troublesome. Now supplanted by the java.time classes.

Using java.time

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Your input seems to be a count of milliseconds since epoch.

Note that Java allows underscores in numeric literals for easier reading by humans.

Instant instant = Instant.ofEpochMilli( 1_484_063_246L );

You can adjust that into a time zone to see some region’s wall-clock time. Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or CET or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( zoneId );

You can interrogate the ZoneId for an offset-from-UTC (ZoneOffset) via ZoneRules, which seems to be the point of your Question. The offset will vary over time because of anomalies such as Daylight Saving Time (DST). A time zone is a collection of offsets for past, present, and near future. So when asking a zone for an offset, you must specify a moment in time.

ZoneOffset zoneOffset = zoneId.getRules().getOffset( instant );

You can get the offset amount as a total number of seconds, if desired.

int offsetInSeconds = zoneOffset.getTotalSeconds() ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

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

public static int getCurrentTimeZoneToUTCDiff() {
    return ZoneId.systemDefault().getRules()
            .getOffset(Instant.ofEpochMilli(1_484_063_246L))
            .getTotalSeconds()/3600;
}
Mike
  • 61
  • 1
  • 4