lunes, 21 de septiembre de 2015

Fecha y hora en C++: struct tm vs time_t vs timeval

En C++ existen 3 tipos de datos para representar la fecha y hora. En este artículo vamos a ver las diferencias entre los tres tipos y cómo se realiza la conversión de uno a otros.

struct tm

Estructura que contiene la fecha y hora dividida en los siguientes campos:
  • tm_sec (int)
  • tm_min (int)
  • tm_hour (int)
  • tm_mday (int)
  • tm_mon (int)
  • tm_year (int)
  • tm_wday (int)
  • tm_yday (int)
  • tm_isdst (int)

time_t

Este tipo es realmente un alias del tipo int, ya que time_t almacena el número de segundos transcurridos desde el día 1 de enero de 1970 a las 00:00, lo que comúnmente se conoce como Epoch Unix.

struct timeval

Estructura que puede considerarse un tipo time_t ampliado (con más precisión), puesto que incluye los milisegundos de la hora. La estructura está formada por dos campos:
  • tv_sec (time_t), segundos transcurridos desde el epoch Unix.
  • tv_usec (unsigned int), microsegundos

Crear hora actual

/** time_t **/
time_t ahora_1 = time(0);

/** struct tm **/
struct tm *ahora_2 = localtime(&ahora_1);

/** struct timeval **/
struct timeval ahora_3;
gettimeofday(&ahora_3, NULL);

Conversión entre tipos 

/** struct tm --> time_t **/
struct tm origen;
time_t destino = mktime(&origen);

/** struct tm --> timeval **/
//Convertir a time_t y después a timeval

/** time_t --> struct tm **/
time_t origen;
struct tm *destino1 = localtime(&origen);
struct tm *destino2 = gmtime(&origen); // Igual que localtime pero en formato UTC

/** time_t --> timeval **/
time_t origen;
struct timeval destino;
destino.tv_sec = origen;
destino.tv_usec = 0;

/** struct timeval --> struct tm **/
// Convertir a time_t y después a struct tm

/** struct timeval --> time_t **/
struct timeval origen;
time_t destino = (time_t)origen.tvsec;

viernes, 27 de junio de 2014

Internet: Avisos de cookies

A continuación dejo un enlace a una serie de artículos muy interesantes sobre ese cartelito tan molesto que ahora aparece en la parte de arriba del navegador cuando entramos en la mayoría de las páginas web.

El blog de Paco Pérez Bes: Avisos de cookies I: la información por capas

miércoles, 7 de agosto de 2013

Activar el teclado numérico en Ubuntu 12.04

Después de instalar la versión 12.04 de Ubuntu, me he dado cuenta que el teclado numérico no funciona correctamente a pesar de que está activo (pulsando la tecla Bloq Num). Esto ocurre porque Ubuntu permite el control del ratón a través del teclado numérico. Por tanto, al desactivar esta opción, se recupera la funcionalidad original de estas teclas.

SOLUCIÓN

Vamos a la ventana Aplicaciones > System Tools > Configuración del sistema y en ella vemos la utilidad Acceso universal (en el subapartado Sistema).


Al abrirla, seleccionamos la pestaña "Apuntar y pulsar"y desmarcamos la opción "Controlar el puntero usando el teclado numérico".


Listo.

martes, 8 de enero de 2013

Gestión de logs en Java con log4j

La librería log4j nos permite gestionar los logs de una aplicación Java. Os recomiendo el tutorial Log4j para Creación de Eventos de Log.

Con log4j podemos "trocear" los ficheros de log cuando llegan a un tamaño máximo definido. El tutorial Log4j describe cómo se configura esta opción.

jueves, 15 de noviembre de 2012

Acceso a ficheros XML desde Java

Librería JAX (Java API for XML)


La librería JAX (Java Api for XML Processing) es una implementación del DOM para Java y nos permite manipular ficheros XML. Está incluída en la versión 1.4.2 y posteriores de Java.

Existe un artículo muy completo sobre la utilización de JAX en La Tasca de Xela.

lunes, 12 de noviembre de 2012

JDBC para Access sin DSN

Hasta ahora, para acceder a una base de datos Access desde Java había que crear un ODBC de la siguiente forma:
  1. Herramientas Administrativas > Administrador de Orígines de ODBC > Crear un nuevo Origen
  2. Desde el JDBC, escribir como URL el nombre del DSN.
Es muy incómodo tener que crear un ODBC nuevo en cada máquina que se instale nuestra aplicación Java, por lo que la solución es acceder a la base de datos de la siguiente forma (¡sin crear ODBC!):

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String accessDB = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\mi_proyecto\mi_bd.mdb";
Connection conn = DriverManager.getConnection(accessDB, "", "");


Esta solución es válida para cualquier ODBC, no solo para Access. Para acceder a una hoja de cálculo Excel haríamos lo siguiente:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String hojaExcel = "jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=C:\mi_proyecto\hoja_excel.xls;" + "DriverID=22;READONLY=false";
Connection conn = DriverManager.getConnection(hojaExcel, "", "");


Información extraída de Apuntes de Java.

jueves, 7 de junio de 2012

Enlaces con las redes sociales en tu página web

Debido al gran auge de la web 2.0, hoy en día es imprescindible que nuestra página web cuente con un botón para poder compartir contenidos en las principales redes sociales. A continuación se describen de forma muy breve como implementar rápidamente los botones "share" de Facebook, Twitter y Google +1 en nuestra web. Para opciones avanzadas, consultar los enlaces correspondientes.

Facebook

https://developers.facebook.com/docs/share/


Este botón se ha implementado mediante la etiqueta <a>, especificando en su atributo share_url la dirección del sitio web que se quiere compartir:

<a href="" name="fb_share" share_url="http://raulbcneo.blogspot.com.es" type="icon">
<script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script>

Twitter

 https://twitter.com/about/resources/buttons#follow


El boton de twitter se crea insertando el código HTML que se genera con el asistente de creación de botones de Twitter que está en el enlace de arriba.

Google +1

http://www.google.com/webmasters/+1/button/


Google también dispone de un asistente para crear su botón Google +1. Puedes acceder a él a través del enlace anterior.

Información extraída de Desarrollo web.

lunes, 4 de junio de 2012

Backups incrementales con rsync


Vamos a ver un ejemplo de backup incremental con rsync, sincronizaremos el directorio /home/destino con el directorio /home/origen:

$ rsync -avvbP --delete --backup-dir=/home/BACKUP/$(date +%y-%m-%d_%H.%M) /home/origen/ /home/destino

La opción --delete indica que se deben eliminar de destino los ficheros que fueron eliminados de origen.
La opción --backup-dir indica que se deben copiar en el directorio /home/BACKUP/'fecha' los ficheros de destino que van a ser actualizados antes de sobreescribirlos con los nuevos cambios.

Supongamos que destino y origen estaban sincronizados con rsync antes de realizar cambios en origen. Si modificamos el fichero /home/origen/prueba.txt y ejecutamos el comando anterior, rsync guardará el fichero /home/destino/prueba.txt en /home/BACKUP/'fecha' y luego copiará prueba.txt de origen a destino.

Problemas al hacer rsync de un dispositivo EXT3 a un dispositivo FAT32

Extraído del blog de Juan Salvador Sánchez


Tratando de hacer un backup con rsync de una unidad en EXT3 a un disco duro USB en FAT32 he podido apreciar que en el backup siempre faltan archivos y que rsync siempre copia de nuevo todo el contenido incluso cuando no ha habido cambios.

La razón de todo esto está relacionada con el formato FAT32. Por un lado en FAT no es posible tener en el mismo directorio dos carpetas con el mismo nombre. Esto tampoco es posible en EXT3 pero al ser esta case sensitive te permite tener una carpeta "pruebas" y otra "PRUEBAS" en el mismo directorio. El resultado al tratar de copiar ambas carpetas al disco FAT32 es que la primera se copia correctamente pero la segunda es excluida de la copia. Optar por nombres distintos en las carpetas es la solución además de una práctica recomendada.

En cuanto a que rsync, siempre hace un volcado completo incluso cuando los archivos no han cambiado, se debe a que en FAT32 para almacenar la fecha en la que se ha modificado un archivo se dispone de una precisión máxima de solo 2 segundos. Esto hace que no coincida la fecha exacta de EXT3 con la fecha aproximada de FAT32, y dado que Rsync se basa en la comparación de estas fechas para determinar si el archivo ha sido modificado o no desde la última copia, decide volver a hacer el backup.

Para estos casos Rsync cuenta con dos soluciones. La primera por medio del parámetro --size-only, con el que solo considerará que deben copiarse de nuevo aquellos archivos que han cambiado su tamaño, pero no su fecha. Y la segunda y más recomendable por medio del parámetro --modify-window=1, que permite especificar un margen de tolerancia entre fechas, en este caso de 1 segundo.

En tal caso quedaría como sigue:

$ rsync -avvbP --modify-window=1 --delete --backup-dir=/media/USB/BACKUP/$(date +%y-%m-%d_%H.%M) /home/origen/ /media/USB/destino
En estos casos se recomienda que el disco duro USB esté en formato EXT3, con lo que no solo no hará falta nada de todo esto sino que además el backup mantendrá intactos los permisos.

viernes, 27 de enero de 2012

Pegar texto sin formato en Word

Todos conocemos cómo funciona el copy-paste para copiar y pegar información de una aplicación a otra. En este caso, os enseño un truco para pegar texto sin formato en Word de forma rápida, sin tener que pulsar en Edición > Pegado especial... > Texto sin formato > Aceptar.

Se puede activar una opción, para que, cuando copiemos un texto, en su parte inferior derecha aparezca un botón de menú con varias opciones de texto, entre ellas la de Conservar solo texto (equivalente a pegar texto sin formato).

Para activar esta opción, nos vamos al menú Herramientas > Opciones en Word, activamos la pestaña Edición y activamos la casilla Mostrar botones de la opciones de pegar. Aceptamos y desde este momento aparecerá el botón.
Información obtenida de la web Jóvenes Informáticos.

miércoles, 23 de noviembre de 2011

Shell Bash: Descomponer una ruta en directorios, nombre de archivo y extensión

El siguiente script (shell Bash) descompone una ruta en directorios, nombre de archivo y extensión.

#!/bin/bash

# Script para descomponer una ruta completa a un archivo o
# directorio, obteniendo
el nombre de archivo y extensión (si
# existen) y ruta hasta los mismos


for RutaCompleta in $1
do
# Comenzamos extrayendo la parte derecha desde el ultimo caracter
# "/", es decir, el archivo

NombreArchivo="${RutaCompleta##*/}"

# Longitud de la ruta es el total de caracteres menos el largo del
# nombre de archivo

LargoRuta="${#RutaCompleta} - ${#NombreArchivo}"

# Extraemos la ruta desde el caracter 0 hasta el caracter final de
# largo de ruta

RutaSola="${RutaCompleta:0:$LargoRuta}"

# Lo siguiente es extraer nombre de archivo
NombreSolo="${NombreArchivo%.[^.]*}"
# Extension se obtiene eliminando del nombre completo el nombre mas
# el punto

Extension="${NombreArchivo:${#NombreSolo} + 1}"

# Las 2 lineas anteriores fallan si no hay extension por lo que es
# necesario comprobar que no
se de el caso de que haya extension
# pero no nombre ya que en ese caso la ext seria el nombre

if [[ -z "$NombreSolo" && -n "$Extension" ]]; then
NombreSolo=".$Extension"
Extension=""
fi
done
# Este es el resultado del script
echo
echo "Este es el resultado del script:"
echo
echo La ruta completa es:
echo $RutaCompleta
echo
echo "Ruta.........: \"$RutaSola\""
echo "Nombre.......: \"$NombreSolo\""
echo "Extension....: \"$Extension\""
echo

Este código ha sido extraído de la web Archivos Log

martes, 22 de noviembre de 2011

Escribir bloques de código en Blogger

Para poder escribir bloques de código fuente legibles en una entrada de Blogger, hay que cambiar el estilo de la etiqueta HTML "code".

En la configuración del blog, hay que ir a la pestaña Plantilla > Edición de HTML. A continuación, se busca la etiqueta "</b:skin>" y justo encima se escribe el código CSS siguiente:

code {background:#EEEEEE; font-family: Trebuchet MS; display:block; border:1px solid #999999; padding:10px;}

Checksum XOR

El cálculo de checksum mediante XOR de una trama de datos es un método muy común para comprobar que no ha habido errores de transferencia por la red.

El código Java para calcular el checksum XOR de un String es el siguiente:

String mensaje = "MI MENSAJE";

// Preparar campo CC (XOR de los caracteres del mensaje)
int checkSum = 0;

for (i = 0; i < mensaje.length(); i++) {
checkSum ^= mensaje.charAt(i);
}

String CC = Integer.toHexString(checkSum); // CC es el checksum


Podéis utilizar la calculadora MTK NMEA para obtener online el checksum de una cadena de caractéres.

Vuelva usted mañana

Un artículo de Larra que está muy de actualidad, a pesar de haber sido escrito hace casi dos siglos (muy fuerte, y es que la sociedad no evoluciona...).
Gran persona debió de ser el primero que llamó pecado mortal a la pereza; nosotros, que ya en uno de nuestros artículos anteriores estuvimos más serios de lo que nunca nos habíamos propuesto, no entraremos ahora en largas y profundas investigaciones acerca de la historia de este pecado, por más que conozcamos que hay pecados que pican en historia, y que la historia de los pecados sería un tanto cuanto divertida. Convengamos solamente en que esta institución ha cerrado y cerrará las puertas del cielo a más de un cristiano.

Estas reflexiones hacía yo casualmente no hace muchos días, cuando se presentó en mi casa un extranjero de estos que, en buena o en mala parte, han de tener siempre de nuestro país una idea exagerada e hiperbólica, de estos que, o creen que los hombres aquí son todavía los espléndidos, francos, generosos y caballerescos seres de hace dos siglos, o que son aún las tribus nómadas del otro lado del Atlante: en el primer caso vienen imaginando que nuestro carácter se conserva intacto como nuestra ruina; en el segundo vienen temblando por esos caminos, y pregunta si son los ladrones que los han de despojar los individuos de algún cuerpo de guardia establecido precisamente para defenderlos de los azares de un camino, comunes a todos los países.

Verdad es que nuestro país no es de aquellos que se conocen a primera ni a segunda vista, y si no temiéramos que nos llamasen atrevidos, lo compararíamos de buena gana a esos juegos de manos sorprendentes e inescrutables para el que ignora su artificio, que estribando en una grandísima bagatela, suelen después de sabidos dejar asombrado de su poca perspicacia al mismo que se devanó los sesos por buscarles causas extrañas. Muchas veces la falta de una causa determinante en las cosas nos hace creer que debe de haberlas profundas para mantenerlas al abrigo de nuestra penetración. Tal es el orgullo del hombre, que más quiere declarar en alta voz que las cosas son incomprensibles cuando no las comprende él, que confesar que el ignorarlas puede depender de su torpeza.

Esto no obstante, como quiera que entre nosotros mismos se hallen muchos en esta ignorancia de los verdaderos resortes que nos mueven, no tendremos derecho para extrañar que los extranjeros no los puedan tan fácilmente penetrar.

Un extranjero de estos fue el que se presentó en mi casa, provisto de competentes cartas de recomendación para mi persona. Asuntos intrincados de familia, reclamaciones futuras, y aun proyectos vastos concebidos en París de invertir aquí sus cuantiosos caudales en tal cual especulación industrial o mercantil, eran los motivos que a nuestra patria le conducían.

Acostumbrado a la actividad en que viven nuestros vecinos, me aseguró formalmente que pensaba permanecer aquí muy poco tiempo, sobre todo si no encontraba pronto objeto seguro en que invertir su capital. Pareciome el extranjero digno de alguna consideración, trabé presto amistad con él, y lleno de lástima traté de persuadirle a que se volviese a su casa cuanto antes, siempre que seriamente trajese otro fin que no fuese el de pasearse. Admirole la proposición, y fue preciso explicarme más claro.

-Mirad -le dije-, monsieur Sans-délai -que así se llamaba-; vos venís decidido a pasar quince días, y a solventar en ellos vuestros asuntos.

-Ciertamente -me contestó-. Quince días, y es mucho. Mañana por la mañana buscamos un genealogista para mis asuntos de familia; por la tarde revuelve sus libros, busca mis ascendientes, y por la noche ya sé quién soy. En cuanto a mis reclamaciones, pasado mañana las presento fundadas en los datos que aquél me dé, legalizadas en debida forma; y como será una cosa clara y de justicia innegable (pues sólo en este caso haré valer mis derechos), al tercer día se juzga el caso y soy dueño de lo mío. En cuanto a mis especulaciones, en que pienso invertir mis caudales, al cuarto día ya habré presentado mis proposiciones. Serán buenas o malas, y admitidas o desechadas en el acto, y son cinco días; en el sexto, séptimo y octavo, veo lo que hay que ver en Madrid; descanso el noveno; el décimo tomo mi asiento en la diligencia, si no me conviene estar más tiempo aquí, y me vuelvo a mi casa; aún me sobran de los quince cinco días.

Al llegar aquí monsieur Sans-délai traté de reprimir una carcajada que me andaba retozando ya hacía rato en el cuerpo, y si mi educación logró sofocar mi inoportuna jovialidad, no fue bastante a impedir que se asomase a mis labios una suave sonrisa de asombro y de lástima que sus planes ejecutivos me sacaban al rostro mal de mi grado.

-Permitidme, monsieur Sans-délai -le dije entre socarrón y formal-, permitidme que os convide a comer para el día en que llevéis quince meses de estancia en Madrid.

[...]


El resto del artículo lo podéis encontrar en

http://bib.cervantesvirtual.com/FichaObra.html?Ref=7656&portal=51