Werken met datums in een script of programma is steeds een uitdaging. Zo gebruikt elke programmeertaal wel eigen bibliotheken om met datums en tijden te werken. Daarenboven werkt elk besturingssysteem met een eigen referentiepunt (Zie Unix Epoch op Wikipedia). Bestaat er dan niet zoiets als een universele manier van werken met datums in programma's. De eenvoudigste manier van werken blijft bestaan uit het gebruik van datums en tijden in tekstvorm volgens de internationale standaarden. Je kunt deze notatie bekijken met de opdracht:
dany@pindabook:~> LC_ALL=C date -u
Sat May 16 08:04:16 UTC 2020
De omgevingsvariabele LC_ALL zorgt dat de datum volgens de US standaard in het Engels wordt weergegeven. De -u optie bij de date opdracht zorgt dat we de UTC tijd gebruiken. De UTC tijd heeft in de zomer bij ons een tijdsverschil van 2 uur. Maar het rekent gemakkelijker.
Wil je de datum van een bepaalde kalenderdag weergeven, kan je dit opvragen met een date optie:
dany@pindabook:~> date -u --date "march 18 2020"
wo 18 mrt 2020 0:00:00 UTC
Je merkt dat zonder de omgevingsvariabele LC_ALL de taal en datuminstellingen van uw systeem gebruikt worden. Riskant als uw script op een andere computersysteem wordt uitgevoerd. Wie liever met klassieke datumnotaties werkt, kan ook gebruik maken van:
dany@pindabook:~> date -u --date "2020-03-18"
wo 18 mrt 2020 0:00:00 UTC
Vanzelfsprekend kan je alle mogelijke date opties opzoeken in de man pagina van date:
dany@pindabook:~> man date
Man: alle passende pagina's vinden, niet alleen eerste (set MAN_POSIXLY_CORRECT to avoid this)
* date (1)
date (1p)
Man: Welke man-pagina wilt u zien?
Man:
Druk Enter om de manual met het sterretje te bekijken. De man pagina verlaat je met een druk op de q toets (Quit).
Handig, maar rekenen kan je met tekst niet. Zo wordt het moeilijk om bijvoorbeeld vandaag binnen veertien dagen aan te duiden. Daarvoor converteren we datums en tijden naar gehele getallen. Het geheel getal stelt in Linux (Unix) de tijd in seconden voor die verlopen is sedert 00:00:00 GMT op 1 januari 1970. Aangezien je een 32-bits geheel getal terugkrijgt, krijgen we vanaf 19 januari 2038 om 03:14:08 UTC een probleem (zie Softwareprobleem jaar 2038 op Wikipedia). Als je echter met tekstnotaties werkt, zoals hier beschreven, heb je daar weinig last van. De systemen zullen tegen dan reeds lang aangepast zijn en bijvoorbeeld 64-bits gehele getallen gebruiken. De omzetting van datum naar geheel getal kan je ook met de date opdracht uitvoeren:
dany@pindabook:~>date -u +%s
1589619994 dany@pindabook:~>date -u --date "2020-03-18" +%s
1584489600
Deze waarde kan je in een variabele opslaan, om er later berekeningen mee uit te voeren:
dany@pindabook:~>vandaag=$(date -u +%s)
dany@pindabook:~>echo $vandaag
1589620199
Een dag bevat 24 uur, een uur bevat 60 minuten en een minuut 60 seconden, dan bevat een dag 24 x 60 * 60 = 86400 seconden. Morgen wordt dan:
dany@pindabook:~> morgen=$((vandaag + 86400))
Om de datum op middernacht af te ronden, gebruiken we de bewerking modulus (%, rest na deling):
dany@pindabook:~> morgen=$((morgen - (morgen % 86400)))
Wordt:
dany@pindabook:~> date -u --date @$morgen
zo 17 mei 2020 0:00:00 UTC
Het apestaartje zorgt dus voor de conversie van geheel getal (seconden) naar een datum in tekstvorm.
Het volgende script berekent op basis van een begindatum ($recevent) en tussentijd ($timebetween) de volgende afspraakdatum.
#!/bin/bash # Geef de Universele datum en tijd weer als een geheel getal now=$(date -u +%s) # We zijn enkel geïnteresseerd in de datum, een dag bevat 86400 seconden today=$((now - (now % 86400))) # Geef de Universele datum en tijd van 18 maart weer als een geheel getal recevent=$(date -u --date "2020-03-18" +%s) # Om de veertien dagen timebetween=$((14 * 86400)) echo " Vandaag: $(date -u --date @$today) ($today)" echo " Terugkerende afspraak: $(date -u --date @$recevent) ($recevent)" echo "Tijd tussen de afspraken: $((timebetween / 86400)) dagen" # Zoek naar de volgende afspraak while [ $recevent -lt $today ]; do recevent=$((recevent + timebetween)) done echo " Volgende afspraak: $(date -u --date @$recevent)"
Bij het uitvoeren van het script krijg je de volgende uitvoer:
dany@pindabook:~> sh afspraak.sh
Vandaag: za 16 mei 2020 0:00:00 UTC (1589587200)
Terugkerende afspraak: wo 18 mrt 2020 0:00:00 UTC (1584489600)
Tijd tussen de afspraken: 14 dagen
Volgende afspraak: wo 27 mei 2020 0:00:00 UTC
Iedereen heeft zijn eigen voorkeur wat betreft teksteditors. Sommigen gebruiken graag een grafische editor, anderen enkel terminal editors. Onder zowel de grafische als terminal editors heb je nog een zeer groot aanbod van editors. En een mens zoekt al snel iets dat standaard op verschillende systemen gebruikt kan worden. Zo gebruik ik standaard op de Raspberry Pi nano, maar openSUSE is eerder voorstander van joe. Hoewel nano standaard aanwezig is op elke openSUSE installatie, merk je al vlug dat deze niet optimaal geconfigureerd is. Zo ontbreekt het gebruik van kleuren. Dit los je snel op met de volgende opdracht:
dany@pindabook:~> echo 'include /usr/share/nano/*' >> ~/.nanorc
Let op de enkele aanhalingstekens, deze zijn echt wel noodzakelijk om het sterretje letterlijk als een sterretje in het nano configuratiebestand te krijgen. En dit wordt het resultaat: