2
votes

Convertir le format de date de JJ.MM.AAAA en AAAA-MM-JJ

J'ai des dossiers sur le disque au format allemand: "01.05.2019", que je souhaite convertir au format anglais: "2019-05-01".

J'utilise PowerShell. Y a-t-il une fonction sophistiquée pour faire cela? Ou devrais-je récupérer toutes les sous-chaînes et les réorganiser?

Actuellement, je ne collecte que les chaînes:

$OrgDir = "P:\Fotos\Import"
$folders = Get-ChildItem $($OrgDir) -Directory 
foreach ($dir in $folders) {
    Write-Host "folder: " $dir
}


2 commentaires

[datetime] :: Parse ("01.05.2019"). ToString ('aaaa-MM-jj')


Prudent. Cela peut être interprété comme le 5 janvier ou le 1er mai selon le paramètre de culture par défaut.


3 Réponses :


4
votes

Utilisez [DateTime] :: ParseExact () pour éviter que l'analyseur de date ne mélange le mois et le jour:

Get-ChildItem $OrgDir -Directory | 
    ForEach-Object {
        $_ | Rename-Item -NewName (
            [DateTime]::ParseExact($_.Name, "dd.MM.yyyy", $null).ToString("yyyy-MM-dd")
        )
    }

Ce qui précède imprime les noms convertis. Cependant, pour renommer efficacement les fichiers, je recommande ceci:

$OrgDir = "P:\Fotos\Import"
$folders = Get-ChildItem $OrgDir -Directory
foreach ($dir in $folders) {
    Write-Host "folder: $([DateTime]::ParseExact($dir.Name, "dd.MM.yyyy", $null).ToString("yyyy-MM-dd"))"
}

Cette ligne de PowerShell renomme tous les répertoires à $ OrgDir au nouveau format de date, étant donné que tous les répertoires du dossier sont nommés de cette façon.

Référence


UPDATE:

Comme l'a souligné @Matt Johnson, $ null code> utilise la culture par défaut de votre système pour ParseExact (chaîne, format, culture) (ainsi que ToString (format, culture) ). Cela peut ou non causer des problèmes en fonction du paramètre de culture actuel de votre système.

Pour vous assurer que ces paramètres n'interfèrent pas avec cette fonction, utilisez [System.Globalization.CultureInfo] :: InvariantCulture pour les paramètres de culture dans ParseExact () et ToString().


1 commentaires

Pour info, $ null utilisera la culture actuelle. Si la culture actuelle n'utilise pas le système de calendrier grégorien, la valeur pourrait être interprétée de manière incorrecte (par exemple, ar-SA est par défaut HijriCalendar ). Passer [System.Globalization.CultureInfo] :: InvariantCulture est plus sûr. (Idem avec le deuxième paramètre de la méthode ToString ). Bien sûr, si le script ne s'exécute jamais sur une machine avec de tels paramètres, cela n'a pas d'importance.



2
votes

Matt Johnson fournit des indications importantes dans ses commentaires:

Pour écrire un code robuste qui fonctionne indépendamment de la culture en vigueur , spécifiez le contexte culturel explicitement , les deux lorsque:

  • analyse des chaînes en tant qu'instances [datetime]

  • mise en forme des instances [datetime] sous forme de chaînes

Par conséquent, utilisez ce qui suit dans votre cas:

PS> [datetime]::Parse('01.05.2019', [cultureinfo] 'de-DE').
      ToString('yyyy-MM-dd', [cultureinfo]::InvariantCulture)
2019-05-01
  • Étant donné que 01.05.2019 est une date courte valide (jour en premier) en allemand, aucune analyse personnalisée n'est nécessaire, uniquement de-DE (allemand / Allemagne) comme contexte culturel.

  • .ToString ('aaaa-MM-jj', [cultureinfo] :: InvariantCulture) spécifie une chaîne de format de sortie explicite; [cultureinfo] :: InvariantCulture - la culture invariante (basée sur l'anglais américain) - car le contexte culturel garantit que la date est interprétée en fonction du calendrier grégorien.

Notez que dans PowerShell casts (par exemple, [datetime] '01 .05.2019 ') et interpolation de chaîne (par exemple , "$ (get-date)" ) toujours utiliser la culture invariante - en appelant [datetime] :: Parse () et .ToString () sans argument de culture explicite (fournisseur de format) utilise la culture actuelle .


0 commentaires

0
votes

Enfin, cela a fait l'affaire pour moi:

PS> [datetime]::Parse('01.05.2019', [cultureinfo] 'de-DE').
      ToString('yyyy-MM-dd', [cultureinfo]::InvariantCulture)

Toutes les autres solutions se sont terminées par:

Get-Date: impossible de lier le paramètre "Date". Impossible de convertir la valeur "15.12.2019" en type "System.DateTime". Erreur: "La chaîne n'a pas été reconnue comme une date / heure valide."

Merci beaucoup mklement0.


0 commentaires