21

Javaでシステム時刻を変更することは可能ですか?

Windows および Linux で実行する必要があります。クラスで試してみましRuntimeたが、権限に問題があります。

これは私のコードです:

String cmd="date -s \""+datetime.format(ntp_obj.getDest_Time())+"\"";
try {
    Runtime.getRuntime().exec(cmd);
} catch (IOException e1) {
// TODO Auto-generated catch block
  e1.printStackTrace();
}
System.out.println(cmd);

の出力cmdは次のとおりです。

date -s "06/01/2011 17:59:01"

ただし、システム時間は以前と同じです。

私はNTPクライアントを書いているので、時間を設定します。そこでNTPサーバーから時間を取得して設定します。

4

9 に答える 9

26

Java には、これを行うための API がありません。

それを行うためのほとんどのシステムコマンドには管理者権限が必要であるためRuntime、プロセス全体を管理者/ルートとして実行するか、runas/を使用しない限り役に立ちませんsudo

必要に応じて、交換できますSystem.currentTimeMillis()。これには 2 つのアプローチがあります。

  1. へのすべてSystem.currentTimeMillis()の呼び出しを、置換可能な独自の静的メソッドへの呼び出しに置き換えます。

    public class SysTime {
        public static SysTime INSTANCE = new SysTime();
    
        public long now() {
            return System.currentTimeMillis();
        }
    }
    

    テストの場合、INSTANCE を別のときに返すもので上書きできます。Dateおよび同様のオブジェクトを作成するためのメソッドをさらに追加します。

  2. すべてのコードが制御下にない場合はClassLoader、 の別の実装を返す をインストールしてくださいSystem。これはあなたが思っているよりも簡単です:

    @Override
    public Class<?> loadClass( String name, boolean resolve ) {
        if ( "java.lang.System".equals( name ) ) {
            return SystemWithDifferentTime.class;
        }
    
        return super.loadClass( name, resolve );
    }
    
于 2011-06-01T15:46:15.527 に答える
24

1 つの方法は、ネイティブ コマンドを使用することです。

Windows の場合、2 つのコマンド (日付と時刻) が必要です。

Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy
Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss

Linux の場合、1 つのコマンドで日付と時刻の両方を処理できます。

Runtime.getRuntime().exec("date -s " + strDateTimeToSet); // MMddhhmm[[yy]yy]

9年ぶりの更新

これは、システムの時刻を設定する代わりにjava.util.Clock、現在の時刻を取得し、時刻を偽造するために必要な場所にモック実装を提供するための良い方法ではありません。

于 2011-06-01T15:40:56.290 に答える
4

root または管理者としてコマンド ライン ツールを実行することによってのみ、システム時刻を設定できます。コマンドは異なりますが、最初に OS を確認し、その OS に適したコマンドを実行できます。

于 2011-06-01T15:41:54.717 に答える
2

プロセスが管理者権限で実行されない場合がありますが、システム時刻を設定する権限はまだあります。Java Native Accessを使用してシステム時刻を変更し、必要なすべてのソースを Java に含めることができます (JNI に比べて簡単です)。

package github.jna;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinBase.SYSTEMTIME;
import com.sun.jna.win32.StdCallLibrary;

/**
 * Provides access to the Windows SetSystemTime native API call.
 * This class is based on examples found in
 * <a href="https://github.com/twall/jna/blob/master/www/GettingStarted.md">JNA Getting Started</a>
 */
public class WindowsSetSystemTime {

    /**
     * Kernel32 DLL Interface.
     * kernel32.dll uses the __stdcall calling convention (check the function 
     * declaration for "WINAPI" or "PASCAL"), so extend StdCallLibrary
     * Most C libraries will just extend com.sun.jna.Library,
     */
    public interface Kernel32 extends StdCallLibrary {

        boolean SetLocalTime(SYSTEMTIME st);

        Kernel32 instance = (Kernel32) Native.loadLibrary("kernel32.dll", Kernel32.class);

    }

    public boolean SetLocalTime(SYSTEMTIME st) {
        return Kernel32.instance.SetLocalTime(st);
    }

    public boolean SetLocalTime(short wYear, short wMonth, short wDay, short wHour, short wMinute, short wSecond) {
        SYSTEMTIME st = new SYSTEMTIME();
        st.wYear = wYear;
        st.wMonth = wMonth;
        st.wDay = wDay;
        st.wHour = wHour;
        st.wMinute = wMinute;
        st.wSecond = wSecond;
        return SetLocalTime(st);
    }       
}
于 2015-08-07T07:15:39.443 に答える
0
package myTestProject;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class LocalTimeChangeTest {

    private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) {
        try {
            String value = "2014-12-12 00:26:14";
            Date date = dateFormat.parse(value);
            value = dateFormat.format(date);
            final Process dateProcess = Runtime.getRuntime().exec("cmd /c date "+value.substring(0, value.lastIndexOf(' ')));
            dateProcess.waitFor();
            dateProcess.exitValue();
            final Process timeProcess = Runtime.getRuntime().exec("cmd /c time "+value.substring(value.lastIndexOf(' ')+1));
            timeProcess.waitFor();
            timeProcess.exitValue();
        } catch (Exception exception) {
            throw new RuntimeException(exception);
        }
    }
}

Windows 管理者モデルでこのコードを実行します。

于 2014-11-20T09:20:09.840 に答える