Je rencontre des problèmes pour convertir la date du Apr 9 2017 3:45:00:000AM
en 2017-04-09 03:45:00
Voici ce que j'ai essayé.
use DateTime::Format::Strptime; my $strp = DateTime::Format::Strptime->new(pattern => '%h %d %Y %H:%M',); $start_date = $strp->parse_datetime('Apr 9 2017 3:45:00:000AM');
imprime 2017-04-09T03:45:00
et non 2017-04-09 03:45:00
. Essayer d'obtenir une horloge de 24 heures, donc lorsque je passe AM
à PM
la même heure s'imprime.
3 Réponses :
Le code suivant montre comment la sortie souhaitée peut être obtenue sans aucun module
use strict; use warnings; use feature 'say'; use DateTime::Format::DateParse; my($date, $dt); $date = 'Apr 9 2017 3:45:00:000AM'; $date =~ s/:(\d{3}[AP]M)/.$1/; $dt = DateTime::Format::DateParse->parse_datetime( $date ); $date = $dt; $date =~ s/T/ /; say $date;
Code Perl avec l'aide du module
use strict; use warnings; use feature 'say'; my $date = 'Apr 9 2017 3:45:00:000AM'; my @fields = qw/month mday year hour min sec usec/; my %months = ( Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12 ); my %parts; @parts{@fields} = split "[ :]+", $date; $parts{hour} += 12 if $parts{usec} =~ /PM/; $parts{month} = $months{ $parts{month} }; printf "%04d-%02d-%02d %02d:%02d:%02d\n", @parts{qw/year month mday hour min sec/};
Mettre à jour  Voir end pour un modèle strptime
pour analyser correctement le format de chaîne d'entrée affiché
Ce qui est montré travaux, â € et donc le DateTime :: Format :: strptime retourne constructeur un DateTime
objet. Mais quand un objet est simplement imprimé, on obtient la stringification qui est affichée.
Vous devez donc le formater pour l'impression comme vous le souhaitez. Une manière générale est avec strftime
my $strp = DateTime::Format::Strptime->new( pattern => '%h %d %Y %I:%M:%S%3N%p' );
où %F
et %T
sont des raccourcis, voir les modèles strftime
Ou combinez les ymd
base ymd
et hms
say $start_date->ymd('-') . ' ' . $start_date->hms(':');
Consultez la documentation et ajustez si / au besoin. Je n'ai pas compris certains détails.
- Cela ne fonctionne que par accident dans cet exemple exact, car le modèle donné à utiliser pour l'analyse dans new
est incorrect pour le format d'entrée affiché et est également incompatible avec les exigences énoncées
Le modèle affiché n'a pas de spécificateur de format pour les secondes, ni pour les millisecondes qui le suivent, ni pour le AM/PM
- tous attendus dans la chaîne d'entrée. Donc, en général, une entrée sous la forme indiquée ne peut pas être analysée correctement avec le modèle affiché
Le %H
correspond à 00-23
heure, donc pas à une horloge de 12 heures qui est indiquée comme prévu et qui est implicite par la présence d' AM
. (Il correspond toujours à un nombre de 12 heures, mais il ne le sera pas une fois que le spécificateur de format AM / PM manquant sera ajouté.)
Le modèle dans l'OP fonctionne et analyse correctement l'entrée donnée car 03:45...
se trouve être en AM, et le module utilise regex pour faire correspondre le modèle donné n'importe où dans la chaîne donnée (par défaut), donc %H:%M
correspond à 03:45
et le reste de la chaîne d'entrée n'a pas d'importance. Si nous activons strict
dans le constructeur, cela échouera. Consultez la documentation.
En supposant que l'entrée affichée est la bonne partie dont nous aurions besoin
say $start_date->strftime("%F %T");
Ici, %I
est pour une horloge de 12 heures (1-12), %S
ajouté pour les secondes et %3N
pour les millisecondes (voir la page dans la documentation pour les modèles, lié ci-dessus) et %p
pour AM / PM.
Le reste fonctionne alors tel quel, avec l'impression dans un format souhaité donné ci-dessus.
Il y a deux problèmes avec votre code. Tout d'abord, le modèle que vous utilisez pour analyser votre date n'est pas correct: %H
est utilisé pour une heure au format 24 heures. À la place, vous devez utiliser une combinaison de %i
(12 heures) et %p
( AM
/ PM
). Deuxièmement, pour imprimer un objet DateTime
, vous devez d'abord le formater (en utilisant ->strftime
ou ->ymd()
par exemple).
Les millisecondes de la date sont cependant un peu un problème car strptime
n'a pas d'option pour correspondre aux millisecondes. Je suggère de d'abord les supprimer de votre date, puis d'analyser la date avec strptime
:
use DateTime::Format::Strptime; my $date = 'Apr 9 2017 3:45:00:505PM'; # Removing milliseconds from date $date =~ s/:(\d{3})(?=AM|PM)//; my $milliseconds = $1; my $strp = DateTime::Format::Strptime->new(pattern => '%h %d %Y %I:%M:%S%p',); my $start_date = $strp->parse_datetime($date); # Taking into account the milliseconds that were removed earlier $start_date->add(seconds => 1) if $milliseconds > 500; say $start_date->strftime("%F %T");
Le code que vous avez fourni n'imprime rien. Vous mentionnez
AM
/PM
, mais votre exemple est avec3:45 AM
, ce qui signifie qu'il est identique au format 12 heures et 24 heures, ce qui rend votre question un peu floue. Pourriez-vous ajouter le code qui fait l'impression (il semble que vous venez d'ajouter unT
supplémentaire là-dedans ...), et utiliser3:45 PM
plutôt que3:45 AM
comme exemple s'il vous plaît?En outre, je suppose que la finale
:000
avantAM
en millisecondes; Est-ce correct? Si tel est le cas, seront-ils toujours000
ou peuvent-ils être un nombre arbitraire à 3 chiffres? (la réponse ne sera pas la même dans les deux cas)@Dada c'est mon code. C'est un copier-coller et il s'imprime J'ai oublié d'ajouter
my $start_date;
Mais le code est ce que j'utilise et il imprime2017-04-09T03:45:00
. Je ne sais donc pas pourquoi il n'imprime pas pour vous. oui le:000
est en millisecondes. Oui, j'ai utilisé AM mais si vous permutez AM à PM j'obtiens le même résultat. Ce que je pouvais espérer obtenir2017-04-09T15:45:00
pour PM. Ce que j'essaie de produire, c'est le2017-04-09 03:45:00
pour le matin et le2017-04-09 15:45:00
pour le PM.1 / Votre code ne contient aucune impression, ni aucune fonction qui imprime quoi que ce soit. Veuillez fournir votre code réel. 2 / Vous n'avez pas répondu à ma question concernant les millisecondes: sont-elles toujours 000 ou pas?
print "$start_date";
et non ils ne sont pas toujours 000.Alors ... vous ne vous souciez pas des millisecondes, ou les voulez-vous? Et vous voulez un format 24 heures, pas AM / PM, non? C'est ce que j'ai supposé dans ma réponse s'il vous plaît laissez-moi savoir si c'est faux
(Je veux dire que lorsque vous imprimez, vous ne voulez pas voir les millisecondes et voulez le format 24 heures? Voir modifier ma réponse et clarifier si nécessaire)