java使用JNA設置系統時間

使用JNA windows系統調用kernel32.dll庫, inux系統調用libc.so庫

 

1. 環境

     jdk1.7

     windows7

    centos 7

2. 依賴的jar

   本程序需要依賴JNA框架.

   jna.jar

3. 接口

import java.util.Date;

public interface JNative {

    /**
     * 設置系統時間
     * @param date Date
     */
    public void setLocalTime(Date date);
    
}

 

4. windows實現


 

import java.util.Calendar;
import java.util.Date;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;

public class WindowsImpl implements JNative{

    public static class SYSTEMTIME extends Structure {
        public short wYear;
        public short wMonth;
        public short wDayOfWeek;
        public short wDay;
        public short wHour;
        public short wMinute;
        public short wSecond;
        public short wMilliseconds;
    }
    
    public interface Kernel32 extends Library{
        
        public boolean SetLocalTime(SYSTEMTIME st); //帶時區
        public int GetCurrentProcessId();
        
    }
    
    public static Kernel32 kernel32Instance = null;
    
    public WindowsImpl(){
        kernel32Instance = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
    }
    
    @Override
    public void setLocalTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        
        SYSTEMTIME st = new SYSTEMTIME();
        st.wYear = (short)c.get(Calendar.YEAR);
        st.wMonth = (short)(c.get(Calendar.MONTH) + 1);
        st.wDay = (short)c.get(Calendar.DAY_OF_MONTH );
        st.wDayOfWeek = (short)c.get(Calendar.DAY_OF_WEEK);
        st.wHour = (short)c.get(Calendar.HOUR_OF_DAY);
        st.wMinute = (short)c.get(Calendar.MINUTE);
        st.wSecond = (short)c.get(Calendar.SECOND);
        st.wMilliseconds = (short)c.get(Calendar.MILLISECOND);
        
        kernel32Instance.SetLocalTime(st);
    }

}

 

5. linux實現

import java.util.Date;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Structure;

public class LinuxImpl implements JNative {

    public static class tm extends Structure{
        
        public static class ByReference extends tm implements Structure.ByReference{}
        public static class ByValue extends tm implements Structure.ByValue{}
        
        public int tm_sec;//seconds 0-61
        public int tm_min;//minutes 1-59
        public int tm_hour;//hours 0-23
        public int tm_mday;//day of the month 1-31
        public int tm_mon;//months since jan 0-11
        public int tm_year;//years from 1900
        public int tm_wday;//days since Sunday, 0-6
        public int tm_yday;//days since Jan 1, 0-365
        public int tm_isdst;//Daylight Saving time indicator
    }
    public static class timeval extends Structure{
        public static class ByReference extends timeval implements Structure.ByReference{}
        public static class ByValue extends timeval implements Structure.ByValue{}
        
        public NativeLong tv_sec; /* 秒數 */
        public NativeLong tv_usec; /* 微秒數 */
    }
    public static class timezone extends Structure{
        public static class ByReference extends timezone implements Structure.ByReference{}
        public static class ByValue extends timezone implements Structure.ByValue{}
        
        public int tz_minuteswest;
        public int tz_dsttime; 
    }
    
    public interface CLibrary extends Library{
        
        int gettimeofday(timeval.ByReference tv, timezone.ByReference tz);
        int settimeofday(timeval.ByReference tv, timezone.ByReference tz);
        
    }
    
    public static CLibrary cLibraryInstance = null;
    
    public LinuxImpl(){
        cLibraryInstance = (CLibrary)Native.loadLibrary("c", CLibrary.class);
    }
    
    @Override
    public void setLocalTime(Date date) {
        long ms = date.getTime();
        
        long s = ms / 1000; //秒
        long us = (ms % 1000) * 1000; //微秒
        
        timeval.ByReference tv = new timeval.ByReference();
        timezone.ByReference tz = new  timezone.ByReference();
        cLibraryInstance.gettimeofday(tv, tz);
        
        tv.tv_sec = new NativeLong(s);
        tv.tv_usec = new NativeLong(us);
        cLibraryInstance.settimeofday(tv, tz);
    }

}


 

6. 工廠類
 

import com.sun.jna.Platform;

public class NativeFactory {
    
    public static JNative newNative(){
        if(Platform.isWindows()){
            return new WindowsImpl();
        }
        
        return new LinuxImpl();
    }

}

 

注意新的Structure 要求實現 getFielOrder 方法,只需將結構內的字段名稱 以字符串list的方式返回即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章