|
转自:http://www.rgagnon.com/javadetails/java-0589.html
We connect to a publicly accessible time server on the internet and parse the result.
List of available time servers : http://tf.nist.gov/service/time-servers.html
NOTE : All users should ensure that their software NEVER queries a server more frequently than once every 4 seconds. Systems that exceed this rate will be refused service. In extreme cases, systems that exceed this limit may be considered as attempting a denial-of-service attack.
<div style="border-left: #4e7fd9 2px solid; background-color: #d3d3d3; padding-left: 0.1cm; color: #000000; margin-left: 0.1cm; font-size: 10px;" class="howtocode">import java.io.*;import java.text.*;import java.util.*;import java.net.*;public final class DateUtils { // NIST, Boulder, Colorado (time-a.timefreq.bldrdoc.gov) public static final String ATOMICTIME_SERVER="http://132.163.4.101:13"; // NIST, Gaithersburg, Maryland (time-a.nist.gov) // public static final String ATOMICTIME_SERVER="http://129.6.15.28:13"; public final static GregorianCalendar getAtomicTime() throws IOException{ BufferedReader in = null; try { URLConnection conn = new URL(ATOMICTIME_SERVER).openConnection(); in = new BufferedReader (new InputStreamReader(conn.getInputStream())); String atomicTime; while (true) { if ( (atomicTime = in.readLine()).indexOf("*") > -1) { break; } } System.out.println("DEBUG : " + atomicTime); String[] fields = atomicTime.split(" "); GregorianCalendar calendar = new GregorianCalendar(); String[] date = fields[1].split("-"); calendar.set(Calendar.YEAR, 2000 + Integer.parseInt(date[0])); calendar.set(Calendar.MONTH, Integer.parseInt(date[1])-1); calendar.set(Calendar.DATE, Integer.parseInt(date[2])); // deals with the timezone and the daylight-saving-time TimeZone tz = TimeZone.getDefault(); int gmt = (tz.getRawOffset() + tz.getDSTSavings()) / 3600000; System.out.println("DEBUG : " + gmt); String[] time = fields[2].split(":"); calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]) + gmt); calendar.set(Calendar.MINUTE, Integer.parseInt(time[1])); calendar.set(Calendar.SECOND, Integer.parseInt(time[2])); return calendar; } catch (IOException e){ throw e; } finally { if (in != null) { in.close(); } } } public static void main(String args[]) throws IOException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Atomic time : " + sdf.format(DateUtils.getAtomicTime().getTime())); } /* ref : http://www.bldrdoc.gov/doc-tour/atomic_clock.html 49825 95-04-18 22:24:11 50 0 0 50.0 UTC(NIST) * | | | | | | | | | These are the last + | | | | | | | | five digits of the | | | | | | | | Modified Julian Date | | | | | | | | | | | | | | | | Year, Month and Day <----+ | | | | | | | | | | | | | | Hour, minute, and second of the <-+ | | | | | | current UTC at Greenwich. | | | | | | | | | | | | DST - Daylight Savings Time code <------+ | | | | | 00 means standard time(ST), 50 means DST | | | | | 99 to 51 = Now on ST, goto DST when local | | | | | time is 2:00am, and the count is 51. | | | | | 49 to 01 = Now on DST, goto ST when local | | | | | time is 2:00am, and the count is 01. | | | | | | | | | | Leap second flag is set to "1" when <-----+ | | | | a leap second will be added on the last | | | | day of the current UTC month. A value of | | | | "2" indicates the removal of a leap second. | | | | | | | | Health Flag. The normal value of this <-+ | | | flag is 0. Positive values mean there may | | | be an error with the transmitted time. | | | | | | The number of milliseconds ACTS is advancing <-+ | | the time stamp, to account for network lag. | | | | Coordinated Universal Time from the National <--------+ | Institute of Standards & Technology. | | The instant the "*" appears, is the exact time. <------------+ */} |
|