Come trovo una data che è 3 giorni prima di una data data in Perl dove il formato è AAAA-MM-GG?Come trovo una data che è tre giorni prima di una data data in Perl?
risposta
Date::Calc
è il modulo campione qui:
use strict;
use warnings;
use Date::Calc qw(Add_Delta_YMD);
my $startDate = '2000-01-01';
my ($startYear, $startMonth, $startDay) = $startDate =~ m/(\d{4}-(\d{2})-\d{2})/;
# 1 year, 2 months, 3 days, after startDate
my $endDate = join('-', Add_Delta_YMD($startYear, $startMonth, $startDay, 1, 2, 3));
Il modulo ha un numero enorme di routine di conversione tempo, in particolare quelli che riguardano delta. DateTime
e Date::Manip
vale anche la pena di verificare.
Vedere perldoc POSIX
per la funzione mktime()
.
Ti aiuterà a convertire date e ore in un numero semplice, che è l'ora di Unix (il numero di secondi dal 1 ° gennaio 1970, credo). Quindi, basta sottrarre 3 (giorni) volte 24 (ore in un giorno) volte 60 (minuti in un'ora) volte 60 (secondi in un minuto) o 259200 secondi da quel numero e utilizzare localtime()
per convertire quel numero di secondi indietro a una rappresentazione di stringa.
Questa è probabilmente la soluzione migliore *, poiché gestirà automaticamente le modifiche di mese e anno. Qualsiasi altra soluzione probabilmente finirà per essere più complicata dopo il factoring nel verificare se abbiamo finito i giorni in un mese, o finito i mesi in un anno.
EDIT: * Al di fuori di guardare su CPAN
.
Date::Calc può essere utilizzato per i calcoli:
#!/usr/bin/perl
use strict;
use warnings;
use Date::Calc qw(Add_Delta_Days);
my ($yyyy, $mm, $dd) = (2009, 9, 2);
my @date = Add_Delta_Days($yyyy, $mm, $dd, -3);
print join('-', @date);
Ci sono così tante opzioni che è moderatamente imbarazzante. Dipende in parte da quali altri calcoli potresti aver bisogno in futuro, e se i tempi ei fusi orari saranno sempre un fattore, e cose simili.
Si potrebbe guardare in qualsiasi di questi
Date::Calc
Date::Manip
DateTime::*
- vedi anche datetime.perl.org (però che il sito non sembra essere la risposta on 2009-09-01T22: 30- 07:00)
per nominare solo tre (serie di) moduli. Suggerirei Date::Calc
o Date::Manip
per semplicità - ma se hai bisogno di essere fantasioso in futuro, i moduli DateTime
potrebbero essere migliori.
http://stackoverflow.com/revisions/bd3f965e-1edb-47b2-bbd0-b4149fd5af18/view-source –
@Brad: grazie per le correzioni sugli URL. –
La cosa bella di mktime
è che gestirà qualsiasi momento di offset. Usa gennaio = 0; e Anno 2009 = 109 in questo schema. Così, stampati mese - 1 e dell'anno - 1900.
use POSIX qw<mktime>;
my ($year, $month, $day) = split '-', $date;
my $three_day_prior = mktime(0, 0, 0, $day - 3, $month - 1, $year - 1900);
mktime
è utile per trovare l'ultimo giorno del mese pure. Vai al giorno 0 del mese successivo.
mktime(0, 0, 0, 0, $month, $year - 1900);
È possibile aggiornare la risposta per mostrare come convertire la stringa "2009-09-04" alla risposta "2009-09-01"; cioè, invece di usare 'today()', come si converte una data stringa nel formato interno? –
C: \> perl -MDate :: Semplice = data -e "data di stampa ('2009-09-04') - 3" 2009-09-01 –
DateTime è il modo canonico per trattare con le date in Perl moderno:
use DateTime;
my ($year, $month, $day) = split '-', '2009-09-01';
my $date = DateTime->new(year => $year, month => $month, day => $day);
$date->subtract(days => 3);
# $date is now three days earlier (2009-08-29T00:00:00)
Se avete intenzione di fare questo, ho suggerirei di usare un tempo a metà giornata come input per mktime, piuttosto che sec, min, hour = 0 per evitare qualsiasi possibilità di problema con l'ora legale, il balzo dei secondi ecc., quindi butta via il componente orario da locale – Cebjyre
Probabilmente è meglio usare Date :: Calc o comunque qualche altro modulo CPAN, semplicemente non ho la conoscenza del livello Guru di un vero maestro Perl. . –
Ciò non riuscirà in alcune situazioni. Tutti pensano che sia un problema semplice, ma non hanno mai veramente preso in considerazione ciò che serve per farlo bene. –