Archiv pro rubriku: Programování

Převod UTF8 sekvencí v hexadecimálním tvaru pomocí PERLu

Ufff, už jsem dlouho, fakt dlouho, nenapsal žádný příspěvek. Takže třebas nějaký užitečný příkaz:

cat input.txt | perl -pe 's/\\x([0-9a-fA-F]{2})/chr hex $1/eg' > output.txt

Soubor input.txt obsahoval data, kde byly české znaky reprezentovány sekvencemi v hexadecimálním kódu:

\xc4\x8dt4 sport

Výše uvedený příkaz převede text z input na české znaky:

čt4 sport

Poznámka — PostgreSQL dump a import

Dump DB

pg_dump -U postgres --inserts -O databasename > database.sql

nebo:

pg_dump databasename -U username -W -h 127.0.0.1 -f ./database.sql

Založení DB

psql -U postgres
CREATE ROLE username LOGIN PASSWORD 'passw' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
CREATE DATABASE databasename WITH OWNER = user ENCODING = 'UTF8' LC_COLLATE = 'Czech, Czech Republic' LC_CTYPE = 'Czech, Czech Republic' CONNECTION LIMIT = -1;

Import DB

cat database.sql | psql -U postgres -d database

Windows:

type database.sql | psql -U postgres -d database

nebo

psql -d databasename -U username -h 127.0.0.1 -f database.sql

Problém s rozdílem dvou datumů v javě

Rozdíl mezi dvěma daty se dá v Javě snadno vypočítat tak, že obě data převedeme na číslo v milisekundách (od 1.1.1970 00:00) a poté tyto dvě hodnoty odečteme a výsledek podělíme hodnotou, která reprezentuje den v milisekundách.

Taková myšlenka zapsaná v Javě by mohla vypadat nějak takto:

long DEN_V_MS = (24 * 60 * 60 * 1000L);
Date d1 = ... // napriklad 1.3.2008 00:00
Date d2 = ... // napriklad 1.5.2008 00:00
long vysledek = (d2.getTime() - d1.getTime())/DEN_V_MS;

Řešení se zdá býti primitivní, jednoduché, průhledné a jednoznačné. Ovšem problém nastane tehdy, pokud jedno z datumů je v období zimního času a druhé v období letního času. Jde o to, že Java automaticky odčítá (při přepočtu na milisekundovou reprezentaci) hodinu u druhého data, které je v onom „letním období“. Pak rozdíl dvou těchto dat bude o hodinu kratší. Jelikož se převod na celé dny provádí pomocí celočíselného dělení, vyjde pak rozdíl těchto dvou dat o den méně.

Jedno z řešení tohoto problému:

long DEN_V_MS = (24 * 60 * 60 * 1000L);
long HODINA_V_MS = (60 * 60 * 1000L);
Date d1 = ... // napriklad 1.3.2008 00:00
Date d2 = ... // napriklad 1.5.2008 00:00
long vysledek = (d2.getTime() - d1.getTime() + HODINA_V_MS)/DEN_V_MS;

Principem je přičíst onu Javou odečtenou hodinu při přesunu na letní čas. Můžete namítnout, že odečítám-li dvě data ze stejného období (letního nebo zimního), bude pak výsledek o tu hodinu větší. Ovšem jelikož chceme celé dny, případná hodina navíc se díky celočíselnému dělení (/DEN_V_MS) osekne.

Někdy i jednoduché a trapné chyby dokážou zkušeného programátora pěkně potrápit (chyby typu opomenutý středník a podobně). I problém chybějícího dne v rozdílu byl podobného ražení.