para - ¿Cómo puedo configurar la hora del sistema en Java?
obtener fecha actual java netbeans (7)
¿Es posible cambiar la hora del sistema en Java?
Debería ejecutarse bajo Windows y Linux. Lo he intentado con la clase Runtime
pero hay un problema con los permisos.
Este es mi código:
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);
La salida de cmd
es:
date -s "06/01/2011 17:59:01"
Pero la hora del sistema es la misma que antes.
Fijaré la hora porque estoy escribiendo un NTP-Client y allí obtengo la hora de un NTP-Server y lo configuraré.
Hay casos en los que el proceso no se ejecuta con derechos de administrador, pero todavía tiene los permisos para configurar la hora del sistema. Es posible usar Java Native Access para cambiar la hora del sistema y tener todas las fuentes requeridas en Java (más simple en comparación con 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);
}
}
Java no tiene una API para hacer esto.
La mayoría de los comandos del sistema para hacerlo requieren derechos de administrador, por lo que Runtime
no puede ayudar a menos que ejecute todo el proceso como administrador / root o use runas
/ sudo
.
Dependiendo de lo que necesite, puede reemplazar System.currentTimeMillis()
. Hay dos enfoques para esto:
Reemplace todas las llamadas a
System.currentTimeMillis()
con una llamada a su propio método estático que puede reemplazar:public class SysTime { public static SysTime INSTANCE = new SysTime(); public long now() { return System.currentTimeMillis(); } }
Para las pruebas, puede sobrescribir INSTANCE con algo que devuelve otras veces. Agregue más métodos para crear
Date
y objetos similares.Si no todo el código está bajo su control, instale un
ClassLoader
que devuelva una implementación diferente para elSystem
. Esto es más simple de lo que piensas:@Override public Class<?> loadClass( String name, boolean resolve ) { if ( "java.lang.System".equals( name ) ) { return SystemWithDifferentTime.class; } return super.loadClass( name, resolve ); }
Puede utilizar JNI
para configurar la hora del sistema. Esto funcionaría en Windows. Necesitas saber JNI
y C
Esta es la función JNI, el prototipo será generado por la utilidad javah
JNIEXPORT void JNICALL Java_TimeSetter_setSystemTime
(JNIEnv *env, jobject obj, jshort hour, jshort minutes) {
SYSTEMTIME st;
GetLocalTime(&st);
st.wHour = hour;
st.wMinute = minutes;
SetLocalTime(&st);
}
El contenedor de Java JNI sería
class TimeSetter {
public native void setSystemTime( short hour, short minutes);
static {
System.loadLibrary("TimeSetter");
}
}
Y finalmente, para usarlo.
public class JNITimeSetter {
public static void main(String[] args) {
short hour = 8;
short minutes = 30;
// Set the system at 8h 30m
TimeSetter ts = new TimeSetter();
ts.setSystemTime(hour, minutes);
}
}
Solo puede configurar la hora del sistema ejecutando una herramienta de línea de comandos como root o Adminstrator. El comando es diferente, pero primero puede verificar el sistema operativo y ejecutar el comando apropiado para ese sistema operativo.
Una forma sería usando comandos nativos.
Para Windows, se requieren dos comandos (fecha y hora):
Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy
Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss
Para Linux, un solo comando maneja la fecha y la hora:
Runtime.getRuntime().exec("date -s " + strDateTimeToSet); // MMddhhmm[[yy]yy]
package com.test;
public class Exec {
public static void main(String[] args) {
try {
String[] cmd = {"/bin/bash","-c","echo yourPassword | sudo -S date --set=''2017-05-13 21:59:10''"};
Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
e.printStackTrace();
}
}
}
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);
}
}
}
Ejecute este código bajo el modelo de administrador de Windows.