如何在Android上在线获取UTC时间?

问题描述:

我正在使用UTC时区和我的应用程序中的时间来获取数据。在应用程序中,无论用户何时可以获取UTC时间并用于获取数据。 我使用这种方法来获取UTC时间。如何在Android上在线获取UTC时间?

String format = "yyyy-MM-dd HH:mm:ss"; 
final SimpleDateFormat sdf = new SimpleDateFormat(format); 
sdf.setTimeZone(TimeZone.getTimeZone("UTC")); 
String utcTime = sdf.format(new Date()); 

该应用程序工作正常。但它将系统时间转换为UTC时间。问题在于,有时用户可能会将时间更改为错误的时间。所以数据不会来。

案例上面的问题是:

例如,在印度当前日期时间是星期四,26 2012年7月,14点27分56秒,时区加尔各答。那么太平洋时区的时间应该是2012年7月26日星期四01:59:30 PDT。

但用户改变了他的设备从时间到14点27分56秒13时27分56秒,所以转换UTC时间是星期四,2012年7月26日零点59分30秒PDT。在这一点上,我的应用程序由于一小时的差异而无法获得日期。

我不想使用日期,Calendar类的Java,我不希望使用该设备的时间。我如何直接获取UTC时间,而不涉及设备的时间,日期。有没有开源的API?

在此先感谢。

long dateInMillis = System.currentTimeMillis(); 

这会返回自1970年1月1日00:00:00 UTC以来的毫秒数。

然后只需将其解析到你想要的最合适的格式:

String format = "yyyy-MM-dd HH:mm:ss"; 
final SimpleDateFormat sdf = new SimpleDateFormat(format); 

String dateString = sdf.format(new Date(dateInMillis))); 
+0

可以请你建议我我如何解析毫秒为UTC当前时间 – 2012-07-26 09:24:29

+0

试试我编辑的代码。 – 2012-07-26 09:27:46

+0

使用java.util.Date类。 “新日期(timeInMili);” – RaphMclee 2012-07-26 09:27:49

您可以使用Joda库来操纵日期/时间数据

http://www.worldweatheronline.com/使用免费的API,你可以执行HTTP通过Java GET来获得UTC当前时间(http://www.worldweatheronline.com/time-zone-api.aspx)

我认为你必须实现SNTP客户端和接入NTP获得网络的时间。 我的代码:

import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.util.Date; 

public class GetTime { 

    public static void main(String[] args) { 
     SntpClient client = new SntpClient(); 
     if (client.requestTime("pool.ntp.org", 30000)) { 
      long now = client.getNtpTime() + System.nanoTime()/1000 
        - client.getNtpTimeReference(); 
      Date current = new Date(now); 
      System.out.println(current.toString()); 
     } 

    } 
} 

class SntpClient { 

    private static final int ORIGINATE_TIME_OFFSET = 24; 
    private static final int RECEIVE_TIME_OFFSET = 32; 
    private static final int TRANSMIT_TIME_OFFSET = 40; 
    private static final int NTP_PACKET_SIZE = 48; 

    private static final int NTP_PORT = 123; 
    private static final int NTP_MODE_CLIENT = 3; 
    private static final int NTP_VERSION = 3; 

    // Number of seconds between Jan 1, 1900 and Jan 1, 1970 
    // 70 years plus 17 leap days 
    private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L; 

    // system time computed from NTP server response 
    private long mNtpTime; 

    // value of SystemClock.elapsedRealtime() corresponding to mNtpTime 
    private long mNtpTimeReference; 

    // round trip time in milliseconds 
    private long mRoundTripTime; 

    /** 
    * Sends an SNTP request to the given host and processes the response. 
    * 
    * @param host 
    *   host name of the server. 
    * @param timeout 
    *   network timeout in milliseconds. 
    * @return true if the transaction was successful. 
    */ 
    public boolean requestTime(String host, int timeout) { 
     try { 
      DatagramSocket socket = new DatagramSocket(); 
      socket.setSoTimeout(timeout); 
      InetAddress address = InetAddress.getByName(host); 
      byte[] buffer = new byte[NTP_PACKET_SIZE]; 
      DatagramPacket request = new DatagramPacket(buffer, buffer.length, 
        address, NTP_PORT); 

      // set mode = 3 (client) and version = 3 
      // mode is in low 3 bits of first byte 
      // version is in bits 3-5 of first byte 
      buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3); 

      // get current time and write it to the request packet 
      long requestTime = System.currentTimeMillis(); 
      long requestTicks = System.nanoTime()/1000; 
      writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime); 

      socket.send(request); 

      // read the response 
      DatagramPacket response = new DatagramPacket(buffer, buffer.length); 
      socket.receive(response); 
      long responseTicks = System.nanoTime()/1000; 
      long responseTime = requestTime + (responseTicks - requestTicks); 
      socket.close(); 

      // extract the results 
      long originateTime = readTimeStamp(buffer, ORIGINATE_TIME_OFFSET); 
      long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET); 
      long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET); 
      long roundTripTime = responseTicks - requestTicks 
        - (transmitTime - receiveTime); 
      // receiveTime = originateTime + transit + skew 
      // responseTime = transmitTime + transit - skew 
      // clockOffset = ((receiveTime - originateTime) + (transmitTime - 
      // responseTime))/2 
      // = ((originateTime + transit + skew - originateTime) + 
      // (transmitTime - (transmitTime + transit - skew)))/2 
      // = ((transit + skew) + (transmitTime - transmitTime - transit + 
      // skew))/2 
      // = (transit + skew - transit + skew)/2 
      // = (2 * skew)/2 = skew 
      long clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime))/2; 
      // if (Config.LOGD) Log.d(TAG, "round trip: " + roundTripTime + 
      // " ms"); 
      // if (Config.LOGD) Log.d(TAG, "clock offset: " + clockOffset + 
      // " ms"); 

      // save our results - use the times on this side of the network 
      // latency 
      // (response rather than request time) 
      mNtpTime = responseTime + clockOffset; 
      mNtpTimeReference = responseTicks; 
      mRoundTripTime = roundTripTime; 
     } catch (Exception e) { 

      return false; 
     } 

     return true; 
    } 

    /** 
    * Returns the time computed from the NTP transaction. 
    * 
    * @return time value computed from NTP server response. 
    */ 
    public long getNtpTime() { 
     return mNtpTime; 
    } 

    /** 
    * Returns the reference clock value (value of 
    * SystemClock.elapsedRealtime()) corresponding to the NTP time. 
    * 
    * @return reference clock corresponding to the NTP time. 
    */ 
    public long getNtpTimeReference() { 
     return mNtpTimeReference; 
    } 

    /** 
    * Returns the round trip time of the NTP transaction 
    * 
    * @return round trip time in milliseconds. 
    */ 
    public long getRoundTripTime() { 
     return mRoundTripTime; 
    } 

    /** 
    * Reads an unsigned 32 bit big endian number from the given offset in the 
    * buffer. 
    */ 
    private long read32(byte[] buffer, int offset) { 
     byte b0 = buffer[offset]; 
     byte b1 = buffer[offset + 1]; 
     byte b2 = buffer[offset + 2]; 
     byte b3 = buffer[offset + 3]; 

     // convert signed bytes to unsigned values 
     int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0); 
     int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1); 
     int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2); 
     int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3); 

     return ((long) i0 << 24) + ((long) i1 << 16) + ((long) i2 << 8) 
       + (long) i3; 
    } 

    /** 
    * Reads the NTP time stamp at the given offset in the buffer and returns it 
    * as a system time (milliseconds since January 1, 1970). 
    */ 
    private long readTimeStamp(byte[] buffer, int offset) { 
     long seconds = read32(buffer, offset); 
     long fraction = read32(buffer, offset + 4); 
     return ((seconds - OFFSET_1900_TO_1970) * 1000) 
       + ((fraction * 1000L)/0x100000000L); 
    } 

    /** 
    * Writes system time (milliseconds since January 1, 1970) as an NTP time 
    * stamp at the given offset in the buffer. 
    */ 
    private void writeTimeStamp(byte[] buffer, int offset, long time) { 
     long seconds = time/1000L; 
     long milliseconds = time - seconds * 1000L; 
     seconds += OFFSET_1900_TO_1970; 

     // write seconds in big endian format 
     buffer[offset++] = (byte) (seconds >> 24); 
     buffer[offset++] = (byte) (seconds >> 16); 
     buffer[offset++] = (byte) (seconds >> 8); 
     buffer[offset++] = (byte) (seconds >> 0); 

     long fraction = milliseconds * 0x100000000L/1000L; 
     // write fraction in big endian format 
     buffer[offset++] = (byte) (fraction >> 24); 
     buffer[offset++] = (byte) (fraction >> 16); 
     buffer[offset++] = (byte) (fraction >> 8); 
     // low order bits should be random data 
     buffer[offset++] = (byte) (Math.random() * 255.0); 
    } 
} 

希望能帮助到你。

UTC时间超过SntpClient以上,如果该系统正时改变例如不工作手动8小时。因为它使用System.currentTimeMillis来返回false值!

 // get current time and write it to the request packet 
     long requestTime = System.currentTimeMillis(); 
     long requestTicks = SystemClock.elapsedRealtime(); 

更好地使用这个类来从NTP服务器得到正确的UTC时间:

import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 


class NTP_UTC_Time 
{ 
private static final String TAG = "SntpClient"; 

private static final int RECEIVE_TIME_OFFSET = 32; 
private static final int TRANSMIT_TIME_OFFSET = 40; 
private static final int NTP_PACKET_SIZE = 48; 

private static final int NTP_PORT = 123; 
private static final int NTP_MODE_CLIENT = 3; 
private static final int NTP_VERSION = 3; 

// Number of seconds between Jan 1, 1900 and Jan 1, 1970 
// 70 years plus 17 leap days 
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L; 

private long mNtpTime; 

public boolean requestTime(String host, int timeout) { 
    try { 
     DatagramSocket socket = new DatagramSocket(); 
     socket.setSoTimeout(timeout); 
     InetAddress address = InetAddress.getByName(host); 
     byte[] buffer = new byte[NTP_PACKET_SIZE]; 
     DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT); 

     buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3); 

     writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET); 

     socket.send(request); 

     // read the response 
     DatagramPacket response = new DatagramPacket(buffer, buffer.length); 
     socket.receive(response);   
     socket.close(); 

     mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);    
    } catch (Exception e) { 
     // if (Config.LOGD) Log.d(TAG, "request time failed: " + e); 
     return false; 
    } 

    return true; 
} 


public long getNtpTime() { 
    return mNtpTime; 
} 


/** 
* Reads an unsigned 32 bit big endian number from the given offset in the buffer. 
*/ 
private long read32(byte[] buffer, int offset) { 
    byte b0 = buffer[offset]; 
    byte b1 = buffer[offset+1]; 
    byte b2 = buffer[offset+2]; 
    byte b3 = buffer[offset+3]; 

    // convert signed bytes to unsigned values 
    int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0); 
    int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1); 
    int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2); 
    int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3); 

    return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3; 
} 

/** 
* Reads the NTP time stamp at the given offset in the buffer and returns 
* it as a system time (milliseconds since January 1, 1970). 
*/  
private long readTimeStamp(byte[] buffer, int offset) { 
    long seconds = read32(buffer, offset); 
    long fraction = read32(buffer, offset + 4); 
    return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L)/0x100000000L);   
} 

/** 
* Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900 
*/  
private void writeTimeStamp(byte[] buffer, int offset) {   
    int ofs = offset++; 

    for (int i=ofs;i<(ofs+8);i++) 
     buffer[i] = (byte)(0);    
} 

} 

并在使用它: “现在”

 long now = 0; 

     NTP_UTC_Time client = new NTP_UTC_Time(); 

     if (client.requestTime("pool.ntp.org", 2000)) {    
      now = client.getNtpTime(); 
     } 

如果您需要UTC时间为DateTimeString使用功能:

private String get_UTC_Datetime_from_timestamp(long timeStamp){ 

    try{ 

     Calendar cal = Calendar.getInstance(); 
     TimeZone tz = cal.getTimeZone(); 

     int tzt = tz.getOffset(System.currentTimeMillis()); 

     timeStamp -= tzt; 

     // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault()); 
     DateFormat sdf = new SimpleDateFormat(); 
     Date netDate = (new Date(timeStamp)); 
     return sdf.format(netDate); 
    } 
    catch(Exception ex){ 
     return ""; 
    } 
    } 

并用它来与:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now); 
+0

并且不要使用权限:互联网 – vuhung3990 2015-01-18 05:21:48