Successivo: , Precedente: , Su: Funzioni predefinite   [Contenuti][Indice]


9.1.5 Funzioni per gestire marcature temporali

I programmi awk sono frequentemente usati per elaborare file di registro [file con estensione .log], che contengono l’informazione sulla data e l’ora (marcatura temporale) in cui un particolare record è stato registrato sul log. Molti programmi registrano questa informazione nel formato restituito dalla chiamata di sistema time(), la quale misura il numero di secondi trascorsi a partire da una certa data iniziale (Epoca). Nei sistemi aderenti allo standard POSIX, questo è il numero di secondi a partire dal primo gennaio 1970, ora di Greenwich (1970-01-01 00:00:00 UTC), senza includere i secondi intercalari.54 Tutti i sistemi noti aderenti allo standard POSIX gestiscono le marcature temporali da 0 fino a 231 - 1, il che è sufficiente per rappresentare date e ore fino a inizio 2038 (2038-01-19 03:14:07 UTC). Molti sistemi supportano una maggiore estensione di date, compresi dei valori negativi per rappresentare delle date anteriori all’Epoca.

Per facilitare l’elaborazione di tali file di registro, e per produrre dei rapporti utili, gawk prevede le seguenti funzioni per lavorare con le marcature temporali. Si tratta di estensioni gawk; non sono previste nello standard POSIX.55 Tuttavia, anche versioni recenti di mawk (vedi la sezione Altre implementazioni di awk liberamente disponibili) prevedono queste funzioni. I parametri opzionali sono racchiusi tra parentesi quadre ([ ]):

mktime(specifiche_data [, utc-flag ])

Trasforma specifiche_data in una marcatura temporale nello stesso formato restituito da systime(). È simile alla funzione omonima in ISO C. L’argomento, specifiche_data, è una stringa della forma "AAAA MM GG HH MM SS [DST]". La stringa consiste di sei o sette numeri che rappresentano, rispettivamente, l’anno in quattro cifre, il mese da 1 a 12, il giorno del mese da 1 a 31, l’ora del giorno da 0 a 23, il minuto da 0 a 59, il secondo da 0 a 60,56 e un’indicazione opzionale relativa all’ora legale.

I valori di questi numeri possono non essere negli intervalli specificati; per esempio, un’ora di -1 sta a indicare 1 ora prima di mezzanotte. Viene adottato il calendario gregoriano con l’origine posta all’anno zero, con l’anno 0 che viene prima dell’anno 1 e l’anno -1 che viene prima dell’anno 0. Se il flag utc-flag è specificato ed è diverso da zero e dalla stringa nulla, si suppone che l’ora sia quella del fuso orario UTC; altrimenti l’ora è considerata essere quella del fuso orario locale. Se l’indicatore DST dell’ora legale è positivo, si presuppone che l’ora sia quella legale; se è 0, l’ora considerata è quella di Greenwich (standard time); se invece è negativo (questo è il default), mktime() tenta di determinare se è in vigore l’ora legale o no, nel momento specificato.

Se specifiche_data non contiene elementi in numero sufficiente, o se la data e ora risultante sono fuori dall’intervallo previsto, mktime() restituisce -1.

strftime([formato [, data_e_ora [, utc] ] ])

Formatta la data e ora specificata da data_e_ora in base alle indicazioni contenute nella stringa formato e restituisce il risultato. È simile alla funzione omonima in ISO C. Se utc è presente ed è diverso da zero o dalla stringa nulla, il valore è formattato come UTC (Tempo Coordinato Universale, già noto come GMT o Tempo Medio di Greenwich). Altrimenti, il valore è formattato per il fuso orario locale. La stringa data_e_ora è nello stesso formato del valore restituito dalla funzione systime(). Se non si specifica l’argomento data_e_ora, gawk usa l’ora del giorno corrente per la formattazione. Omettendo l’argomento formato, strftime() usa il valore di PROCINFO["strftime"] come stringa di formattazione (vedi la sezione Variabili predefinite). Il valore di default della stringa è "%a %b %e %H:%M:%S %Z %Y". Questa stringa di formattazione produce lo stesso output del programma di utilità equivalente date. Si può assegnare un nuovo valore a PROCINFO["strftime"] per modificare la formattazione di default; si veda la lista che segue per le varie direttive di formattazione.

systime()

Restituisce l’ora corrente come numero di secondi a partire dall’Epoca del sistema. Sui sistemi aderenti allo standard POSIX, questo è il numero di secondi trascorsi a partire dal primo gennaio 1970, ora di Greenwich (1970-01-01 00:00:00 UTC), senza includere i secondi intercalari.

La funzione systime() consente di confrontare una marcatura temporale in un file di registro con la data e ora correnti. In particolare, è facile determinare quanto tempo prima un particolare record è stato registrato. È anche possibile produrre record di registro usando il formato “secondi a partire dall’Epoca”.

La funzione mktime() consente di convertire una rappresentazione in forma testuale di una data e ora in una marcatura temporale. Questo semplifica i confronti prima/dopo tra differenti date e ore, in particolare quando si abbia a che fare con date e ore provenienti da una fonte esterna, come un file di registro.

La funzione strftime() permette di trasformare facilmente una marcatura temporale in un’informazione intelligibile. È analoga come tipo alla funzione sprintf() (vedi la sezione Funzioni di manipolazione di stringhe), nel senso che copia letteralmente ciò che non è una specifica di formato nella stringa che viene restituita, mentre sostituisce i valori di data e ora a seconda delle specifiche di formato contenute nella stringa formato.

Per strftime() lo standard 1999 ISO C57 consente le seguenti specifiche di formattazione delle date:

%a

Il nome abbreviato del giorno della settimana nella lingua locale.

%A

Il nome completo del giorno della settimana nella lingua locale.

%b

Il nome abbreviato del mese dell’anno nella lingua locale.

%B

Il nome completo del mese dell’anno nella lingua locale.

%c

Il formato “appropriato” della rappresentazione della data e ora nella lingua locale. (Questo è ‘%A %B %d %T %Y’ per la localizzazione "C".)

%C

La parte che designa il secolo nell’anno corrente. Si ottiene dividendo per 100 l’anno, e troncando verso il basso all’intero più vicino.

%d

Il giorno del mese come numero decimale (01–31).

%D

Equivale a specificare ‘%m/%d/%y’.

%e

Il giorno del mese, preceduto da uno spazio se di tratta di una cifra sola.

%F

Equivale a specificare ‘%Y-%m-%d’. Questo è il formato ISO 8601 della data.

%g

L’anno (ultime due cifre) ricavato prendendo il resto della divisione per 100 dell’anno a cui appartiene la settimana, secondo ISO 8601, come numero decimale (00–99). Per esempio, il primo gennaio 2012, fa parte della settimana 53 del 2011. Quindi, l’anno relativo al numero di settimana ISO di quella data è 2011 (ossia 11), anche se la data in sé è nel 2012. Analogamente, il 31 dicembre 2012, è nella prima settimana del 2013. Quindi, l’anno relativo al numero di settimana ISO di quella data è 2013 (ossia 13), anche se la data in sé è nel 2012.

%G

L’anno intero relativo al numero di settimana ISO, come numero decimale.

%h

Equivalente a ‘%b’.

%H

L’ora (in un orologio a 24 ore) come numero decimale (00–23).

%I

L’ora (in un orologio a 12 ore) come numero decimale (01–12).

%j

Il giorno dell’anno come numero decimale (001–366).

%m

Il mese come numero decimale (01–12).

%M

Il minuto come numero decimale (00–59).

%n

Un carattere di ritorno a capo (ASCII LF).

%p

L’equivalente nella lingua locale delle designazioni AM/PM (mattino/pomerigggio) associate a un orologio a 12 ore.

%r

L’ora locale nel formato a 12 ore. (Questo è ‘%I:%M:%S %p’ nella localizzazione "C".)

%R

Equivalente a specificare ‘%H:%M’.

%S

Il secondo come numero decimale (00–60).

%t

Un carattere di tabulazione [TAB].

%T

Equivalente a specificare ‘%H:%M:%S’.

%u

Il numero del giorno della settimana come numero decimale (1–7). Lunedì è il giorno numero 1.

%U

Il numero di settimana dell’anno (con la prima domenica dell’anno presa come primo giorno della prima settimana) come numero decimale (00–53).

%V

Il numero di settimana dell’anno (con il primo lunedì dell’anno preso come primo giorno della prima settimana) come numero decimale (01–53). Il metodo per determinare il numero di settimana è quello specificato dallo standard ISO 8601. (In pratica: se la settimana che contiene il primo gennaio ha quattro o più giorni nel nuovo anno, allora è la settimana numero uno; altrimenti è l’ultima settimana [52 o 53] dell’anno precedente, e la settimana successiva è la settimana numero uno.)

%w

Il giorno della settimana come numero decimale (0–6). Domenica è il giorno zero.

%W

Il numero di settimana dell’anno (con il primo lunedì come primo giorno della settimana numero uno) come numero decimale (00–53).

%x

Il formato “appropriato” della rappresentazione della data nella lingua locale. (Questo è ‘%A %B %d %Y’ nella localizzazione "C".)

%X

Il formato “appropriato” della rappresentazione della data. (Questo è ‘%T’ nella localizzazione "C".)

%y

L’anno modulo 100 (le ultime due cifre) come numero decimale (00–99).

%Y

L’anno come numero decimale (p.es., 2015).

%z

La differenza di fuso orario [rispetto all’ora di Greenwich] in formato ‘+OOMM’ (p.es., il formato necessario per produrre intestazioni di data conformi agli standard RFC 822/RFC 1036).

%Z

Il nome o l’abbreviazione della zona di fuso orario (time zone); se il fuso orario non è determinabile, è impostata alla stringa nulla.

%Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH
%OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy

“notazioni alternative” di specifica in cui solo la seconda lettera (‘%c’, ‘%C’ e così via) è significativa.58 (Queste facilitano la compatibilità con il programma di utilità POSIX date.)

%%

Un singolo carattere ‘%’.

Se uno specificatore di conversione non è tra quelli elencati sopra, il comportamento è indefinito.59

Per sistemi che non aderiscono completamente agli standard gawk utilizza una copia di strftime() dalla libreria C di GNU. Sono disponibili tutte le specifiche di formato sopra elencate. Se la detta versione è usata per compilare gawk (vedi la sezione Installare gawk), sono disponibili anche le seguenti ulteriori specifiche di formato:

%k

L’ora (in un orologio a 24 ore) come numero decimale (0–23). I numeri di una sola cifra sono preceduti da uno spazio bianco.

%l

L’ora (in un orologio a 12 ore) come numero decimale (1–12). I numeri di una sola cifra sono preceduti da uno spazio bianco.

%s

L’ora espressa in numero di secondi a partire dall’Epoca.

In aggiunta a ciò, le notazioni alternative sono riconosciute, ma al loro posto sono usate quelle normali.

Il seguente esempio è un’implementazione awk del programma di utilità POSIX date. Normalmente, il programma di utilità date stampa la data e l’ora corrente nel formato ben noto. Tuttavia, se si specifica al comando un argomento che inizia con un ‘+’, date copia i caratteri che non sono specifiche di formato nello standard output e interpreta l’ora corrente secondo gli specificatori di formato contenuti nella stringa. Per esempio:

$ date '+Oggi è %A, %d %B %Y.'
-| Oggi è lunedì, 22 settembre 2014.

Ecco la versione gawk del programma di utilità date. È all’interno di uno script di shell per gestire l’opzione -u, che richiede che date sia eseguito come se il fuso orario fosse impostato a UTC:

#! /bin/sh
#
# date --- simula il comando POSIX 'date'

case $1 in
-u)  TZ=UTC0     # usare UTC
     export TZ
     shift ;;
esac

gawk 'BEGIN  {
    formato = PROCINFO["strftime"]
    codice_di_ritorno = 0

    if (ARGC > 2)
        codice_di_ritorno = 1
    else if (ARGC == 2) {
        formato = ARGV[1]
        if (formato ~ /^\+/)
            formato = substr(formato, 2)   # togli il + iniziale
    }
    print strftime(formato)
    exit codice_di_ritorno
}' "$@"

Note a piè di pagina

(54)

Vedi la sezione Glossario, in particolare le voci “Epoca” e “UTC.”

(55)

Il comando di utilità GNU date può fare anche molte delle cose qui descritte. Può essere preferibile usarlo per semplici operazioni relative a data e ora in semplici script della shell.

(56)

Occasionalmente ci sono dei minuti in un anno con un secondo intercalare, il che spiega perché i secondi possono arrivare fino a 60.

(57)

Sfortunatamente, non tutte le funzioni strftime() dei vari sistemi operativi ammettono tutte le conversioni qui elencate.

(58)

Se questo risulta incomprensibile, non è il caso di preoccuparsi; queste notazioni hanno lo scopo di facilitare la “internazionalizzazione” dei programmi. Altre funzionalità di internazionalizzazione sono descritte in Internazionalizzazione con gawk.

(59)

Questo è perché ISO C lascia indefinito il comportamento della versione C di strftime() e gawk usa la versione di sistema di strftime(), se disponibile. Tipicamente, lo specificatore di conversione "non previsto" non appare nella stringa risultante, o appare così come è scritto.


Successivo: , Precedente: , Su: Funzioni predefinite   [Contenuti][Indice]