Hoe kan ik het parseren van data en zetten tijdzones in Perl?

Ik heb de localtime functie in Perl om de huidige datum en tijd, maar nodig om te verwerken in bestaande data. Ik heb een GMT datum in het volgende formaat: “20090103 12:00” ik zou graag om het te ontleden in een date object kan ik werken en dan zetten de GMT-tijd/datum in mijn huidige tijdzone is momenteel Eastern Standard Time. Dus ik zou graag om te zetten “20090103 12:00” naar “20090103 7:00” alle info over hoe dit te doen zou zeer gewaardeerd worden.

InformationsquelleAutor Jared | 2009-01-04



5 Replies
  1. 48

    Omdat de Perl gebouwd in datum behandeling interfaces zijn soort van onhandig en je de wind langs om een half dozijn variabelen, de betere manier is om een van beide Datum /tijd of Tijd::Per Stuk. Datum /tijd is de all-singing, all-dancing Perl object date, en je zult waarschijnlijk uiteindelijk wilt om het te gebruiken, maar de Tijd::Stuk eenvoudiger en perfect geschikt voor deze taak, heeft het voordeel van verzending met 5.10 en de techniek is in principe hetzelfde voor beide.

    Hier is het een eenvoudige en flexibele manier gebruik van de Tijd::per Stuk en strptime.

    #!/usr/bin/perl
    
    use 5.10.0;
    
    use strict;
    use warnings;
    
    use Time::Piece;
    
    # Read the date from the command line.
    my $date = shift;
    
    # Parse the date using strptime(), which uses strftime() formats.
    my $time = Time::Piece->strptime($date, "%Y%m%d %H:%M");
    
    # Here it is, parsed but still in GMT.
    say $time->datetime;
    
    # Create a localtime object for the same timestamp.
    $time = localtime($time->epoch);
    
    # And here it is localized.
    say $time->datetime;

    En hier is de door-de-hand manier, voor het contrast.

    Omdat de indeling is vastgesteld, is een reguliere expressie zal het prima doen, maar als de opmaak wijzigingen die u zult moeten tweaken van de regex.

    my($year, $mon, $day, $hour, $min) = 
        $date =~ /^(\d{4}) (\d{2}) (\d{2})\ (\d{2}):(\d{2})$/x;

    Vervolgens om te zetten in Unix epoch tijd (in seconden sinds 1 januari, 1970)

    use Time::Local;
    # Note that all the internal Perl date handling functions take month
    # from 0 and the year starting at 1900.  Blame C (or blame Larry for
    # parroting C).
    my $time = timegm(0, $min, $hour, $day, $mon - 1, $year - 1900);

    En vervolgens weer terug naar uw lokale tijd.

    (undef, $min, $hour, $day, $mon, $year) = localtime($time);
    
    my $local_date = sprintf "%d%02d%02d %02d:%02d\n",
        $year + 1900, $mon + 1, $day, $hour, $min;
    • Zelfs wanneer het rollen van een eigen, men kan use POSIX qw(strftime) op zowel Unix-als Windows-systemen van ten minste Perl 5.6.0 hoger. Dat maakt de uiteindelijke “roll-je-eigen” om de beide korter en meer houdbaar: my $local_date = strftime "%Y%m%d %H:%M\n", localtime($time);.
    • $tijd->localtime->tzoffset AFAICT geeft de offset voor de huidige tijd, niet in de gegeven tijd.
    • Ja, en dat is ok tenzij we willen zorgen te maken over de geschiedenis van de tijdzone verandert, wat ik zeker niet. DST belangrijk zou kunnen zijn.
    • Het lijkt DateTime module geen datum ontleden in zijn repertoire. Hier is een citaat van pod: This module does not parse dates! Instead, take a look at the various DateTime::Format::* modules on CPAN
    • Ja, dit is een onderdeel van het ontwerp. In plaats van de scheepvaart met een groot aantal formatteerders ze zijn plug-ins. Zie Formatteerders en Stringification in de documenten. Het nadeel is DateTime zelfs niet de meest eenvoudige opmaak uit de doos. De kop is er zijn een heleboel van de formatteerders.
    • Je miste de punt ysth was verhogen. Het heeft niets te maken met de historische veranderingen. ysth gewezen op de verschuiving is verschillend van verschillende data. In NYC, is het -5 voor de data in de winter en -4 voor data in de winter. Uw code op de verkeerde offset, omdat het gebruikt de verschuiving van de huidige datum in plaats van de verschuiving van de datum gewijzigd. Bewijs. Opgelost.
    • Opgelost. . .

  2. 21

    Hier is een voorbeeld, waarbij Datum /tijd en de strptime formaat module.

    use DateTime;
    use DateTime::Format::Strptime;
    
    my $val = "20090103 12:00";
    
    my $format = new DateTime::Format::Strptime(
                    pattern => '%Y%m%d %H:%M',
                    time_zone => 'GMT',
                    );
    
    my $date = $format->parse_datetime($val);
    
    print $date->strftime("%Y%m%d %H:%M %Z")."\n";
    
    $date->set_time_zone("America/New_York");  # or "local"
    
    print $date->strftime("%Y%m%d %H:%M %Z")."\n";
    
    $ perl dates.pl
    20090103 12:00 UTC
    20090103 07:00 EST


    Als u had willen ontleden localtime, hier is hoe je het zou doen 🙂

    use DateTime;
    
    my @time = (localtime);
    
    my $date = DateTime->new(year => $time[5]+1900, month => $time[4]+1,
                    day => $time[3], hour => $time[2], minute => $time[1],
                    second => $time[0], time_zone => "America/New_York");
    
    print $date->strftime("%F %r %Z")."\n";
    
    $date->set_time_zone("Europe/Prague");
    
    print $date->strftime("%F %r %Z")."\n";
    • En wat is er mis met deze?
    • Je mist het parseren van een onderdeel.
    • Oh, waar is. Ik heb per ongeluk dacht dat hij wilde gebruiken localtime uitgang.
  3. 5

    Dat is wat ik zou doen …

    #!/usr/bin/perl
    use Date::Parse;
    use POSIX;
    
    $orig = "20090103 12:00";
    
    print strftime("%Y%m%d %R", localtime(str2time($orig, 'GMT')));

    U kunt ook gebruik maken van Time::ParseDate en parsedate() in plaats van Date::Parse en str2time(). Merk op dat de de-facto standaard atm. lijkt DateTime (maar u misschien niet wilt gebruiken OO syntax gewoon om te zetten in een tijdstempel).

    • Dit is FTW.
  4. 4

    Maak uw keuze:

    Zijn er tig anderen, zonder twijfel, maar zij zijn waarschijnlijk de top kanshebbers.

    • Datum::Calc had heel wat activiteit in 2009.
    • Maar ik denk niet dat de activiteit had plaatsgevonden op 4 januari 2009, toen ik schreef dat commentaar. Het is echter goed om te weten dat het wordt onderhouden. Goede stabiele modules hoeft niet per se veel werk als Perl vordert.
  5. -2
    use strict;
    use warnings;
    my ($sec,$min,$hour,$day,$month,$year)=localtime();
    $year+=1900;
    $month+=1;
    $today_time = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$day,$month,$year,$hour,$min,$sec);
    print $today_time;
    • Deze code wordt alleen afgedrukt op de huidige lokale tijd. Het geeft geen antwoord op de vraag.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *