PHP y el error al restar fechas después del cambio de hora

partimos de una funcion en PHP que resta dias

function restadias($fecha,$dias){
	list( $dia, $mes, $year ) = split( '/', $fecha );
	//teniendo la fecha tenemos que obtener el lunes y el viernes de esa semana.
	$f=mktime(0 , 0, 0, (int)$mes  , (int)$dia, (int)$year);
	$sumadias=60*60*24*($dias);
	$l=$f-$sumadias;
		$dia1=date('j',$l);
	if ($dia1<10){
		$d="0".$dia1;
	}else{
		$d=$dia1;
	}
	$mes1=date('n',$l);
	if ($mes1<10){
		$m="0".$mes1;
	}else{
		$m=$mes1;
	}
	$year1=date('Y',$l);
	$nf   = $d."/".$m."/".$year1;
	
	return $nf;
}

Si vemos la función, lo que hace es partir la fecha de texto dd/mm/aaaa y obtener el valor en segundos con mktime, luego los días que va a restar los multiplica por el número de segundos del día y hace la resta, el resultado lo formatea otra vez en formato dd/mm/aaaa

Así para el ejemplo:

echo restadias("03/03/2016",1);

El resultado es o debería de ser 02/03/2016

Pero para restadias("28/03/2016",1) cuando debería de darnos el día 27 nos devuelve un fatídico 26/03/2016.


1459123200 - 86400  = 1459036800

Y todo por el cambio de hora, como la función realiza el mktime pasando 0 en horas, minutos y segundos, al restar 86400 segundos según la funcion $dia1=date('j',$l)
Y lo vemos mejor viendo la hora:

date("H",$l);

Donde parte de las 0 y nos devuelve 23.

para solucionarlo, modificamos la función restadias por:

function restadias($fecha,$dias){
	list( $dia, $mes, $year ) = split( '/', $fecha );
	//teniendo la fecha tenemos que obtener el lunes y el viernes de esa semana.
	$f=mktime(12 , 0, 0, (int)$mes  , (int)$dia, (int)$year);
	$sumadias=60*60*24*($dias);
	$l=$f-$sumadias;
		$dia1=date('j',$l);
	if ($dia1<10){
		$d="0".$dia1;
	}else{
		$d=$dia1;
	}
	$mes1=date('n',$l);
	if ($mes1<10){
		$m="0".$mes1;
	}else{
		$m=$mes1;
	}
	$year1=date('Y',$l);
	$nf   = $d."/".$m."/".$year1;
	
	return $nf;
}

Donde hemos puesto como hora las 12, asi nos evitamos el problema del cambio de hora, de 2 a 3 de la mañana.

Permitir conexiones no seguras

Cuando intentamos conectar con un servidor mediante https y el certificado no es “reconocido” nos da un error.

 

Para permitir todo tipo de conexiones seguras podemos crear una función

private static void trustAllHosts() {
		// Create a trust manager that does not validate certificate chains
		X509TrustManager tm = new X509TrustManager() {
			
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return new java.security.cert.X509Certificate[] {};
			}
			@Override
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				// TODO Auto-generated method stub
				
			}
			@Override
			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				// TODO Auto-generated method stub
				
			}
		} ;
		TrustManager[] trustAllCerts = new TrustManager[] {tm};

		// Install the all-trusting trust manager
		try {
			SSLContext sc = SSLContext.getInstance("TLS");
			sc.init(null, trustAllCerts, new java.security.SecureRandom());
			HttpsURLConnection
					.setDefaultSSLSocketFactory(sc.getSocketFactory());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

Y llamar a la función antes de realizar la conexión:

HttpTransportSE androidHttpTransport= null;
		try {
			String conexion = url;
			trustAllHosts(); // poner aqui la llamada 
			androidHttpTransport = new HttpTransportSE(conexion);
			androidHttpTransport.debug = true;
			androidHttpTransport.call(METHOD, envelope,headerList);
			res=androidHttpTransport.responseDump;
			res=datoGateway(res);
		}catch (Exception e){
			Log.e("Error",e.toString());
			
		}

Cortar un texto para mandarlo por SMS sin cortar palabras (JAVA)

Vamos a preparar una funcion java que nos trocea un texto en multiples SMS sin cortar palabras y añadiendo al final un contador de mensajes.

previamente lo habiamos visto en PHP

function List ArrayTextoSMS(String textoMensaje){
List mensajes = new ArrayList();
if (textoMensaje.length()>160){
			//partimos los mensajes en 
			 String[] palabras = textoMensaje.split(" ");
			 String frase="";
			 String fraseadd="";
			 for (String p : palabras){
				 fraseadd=frase+" "+p;
				 if (fraseadd.length()>150){
					 mensajes.add(frase);
					 frase=p;
				 }else{
					 frase=frase+" "+p;
				 }
			 }
			 if (!frase.equals("")){
				 mensajes.add(frase);
			 }
			 int numfrases=mensajes.size();
			 //añadimos un contador
			 if (numfrases>1){
				 for (int i=0;i<numfrases;i++){
					 int j=i+1;
					 mensajes.set(i, mensajes.get(i)+" ("+j+"/"+numfrases+")");
				 }
			 }
			 
		}else{
			mensajes.add(textoMensaje);
		}
return mensajes;
}

Cortar un texto para mandarlo por SMS sin cortar palabras

Vamos a preparar un script que nos trocea un texto en multiples SMS sin cortar palabras y añadiendo al final un contador de mensajes.

function ArrayTextosSMS($texto){
		$frases=array();
		$palabras=explode(" ",$texto);
		$frase="";
		$numpalabras=count($palabras);
		foreach($palabras as $palabra){
			$fraseadd=$frase." ".$palabra;
			if (strlen($fraseadd)>150){
				array_push($frases,trim($frase));
				$frase=$palabra;
			}else{
				$frase=$frase." ".$palabra;
			}
		}
		if ($frase!=""){
			array_push($frases,trim($frase));
		}
		$numfrases=count($frases);
		//añadimos un contador
		if ($numfrases>1){
			for($i=0;$i<$numfrases;$i++){
					$j=$i+1;
				$frases[$i]=$frases[$i]." ($j/$numfrases)";
			}
		}
		return $frases;
		
	}

el ejemplo es:

$texto="Este es un texto muy largo que queremos mandar mediante SMS, para ello hemos creado un script que nos lo trocea en partes de 150 caracteres y ademas le añade un contador de numero de mensajes. Ahora hay que encontrar un proveedor que nos permita mandar los sms, a ser posible de manera gratuita, pero todavia no he dado con ello. Si algun dia lo encuentro, lo compartiré en este mismo hilo";

print_r(ArrayTextosSMS($texto));die;

Que nos da como resultado:

Array
(
    [0] => Este es un texto muy largo que queremos mandar mediante SMS, para ello hemos creado un script que nos lo trocea en partes de 150 caracteres y ademas (1/3)
    [1] => le añade un contador de numero de mensajes. Ahora hay que encontrar un proveedor que nos permita mandar los sms, a ser posible de manera gratuita, (2/3)
    [2] => pero todavía no he dado con ello. Si algún día lo encuentro, lo compartiré en este mismo hilo (3/3)
)

El código esta disponible tambien en JAVA

Usar verify.js para validar un formulario usando AJAX

El plugin verify.js nos permite validar un formulario rápidamente, pero funciona cuando se envía el formulario con el botón submit.

Si el formulario lo queremos utilizar mediante ajax no se dispara el evento.

campoobligatorio

Para ellos vamos a utilizar el evento beforeSubmit

Habilitar conexiones HTTPs en IOS9 con certificados viejos

En ios9 me encuentro con que las conexiones https que utilizaba han dejado de funcionar

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)2015-12-14 10:07:25.497 app[24699:660001] Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7ff8f14a4080>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802,

Buscando por internet encuentro la siguiente información en pagina de soporte de Apple:

Exactly. iOS 9 forces connections that are using HTTPS to be TLS 1.2 to avoid recent vulnerabilities. In iOS 8 even unencrypted HTTP connections were supported, so that older versions of TLS didn’t make any problems either.

El problema entonces viene porque el certificado https no soporta TLS 1.2.
Hay que configurar la aplicación para que acepte conexiones con version del certificado anterior.

Para ellos en el fichero info.plist añadimos la siguiente entrada:

NSAppTransportSecurity 
    
  NSAllowsArbitraryLoads  
   
   
    
    

O de forma grafica:

Captura de pantalla 2015-12-14 a las 9.16.54

Gestor de descargas en raspberry pi

Instalamos la herramienta FATRAT [WEB]

sudo apt-get install fatrat

Una vez terminada la instalación habilitamos la interfaz web modificando el fichero de configuracion

sudo nano /usr/share/fatrat/data/defaults.conf

Y configuramos el puerto, la clave y habilitamos el parametro remote=true

Captura de pantalla 2015-12-12 a las 10.34.52

Una vez lo hemos configurado arrancamos el programa

fatrat -n 

Ahora nos podemos conectar con un navegador:
Captura de pantalla 2015-12-12 a las 10.30.35

Captura de pantalla 2015-12-12 a las 10.31.59