質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.37%

  • C#

    9489questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • .NET Framework 4.0

    88questions

    Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

visual c#.NET ParseExactでのstring型→DateTime型の変換がうまくいかない

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 419

asus2

score 15

お世話になります。

2つのファイルの撮影日時、無ければファイル更新日時を比較する関数を作成していますが、
Shell32で撮影日時を取得できた場合に、【string型→DateTime型変換部分】で【エラーメッセージ】が出てしまい、うまくいきません。

撮影日時が無く、更新日時をstring型→DateTime型に変換した場合は問題ありませんでした。
fileX、fileY共に、"yyyy/MM/dd HH:mm"の形式でstring型の日時が取得できています。
(のように見えているだけかもしれませんが…。)

原因がわからずご助言いただけないでしょうか、よろしくお願いいたします。

【string型→DateTime型変換部分】

DateTime datetimeX = 
    DateTime.ParseExact(stringX, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
DateTime datetimeY = 
    DateTime.ParseExact(stringY, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);

【エラーメッセージ】

System.FormatException: '文字列は有効な DateTime ではありませんでした。'

【関数全ソース】

static int Compare(string fileX, string fileY)
{
    Shell32.Shell shell = new Shell32.Shell();

    Shell32.Folder objFolder_photX = shell.NameSpace(Path.GetDirectoryName(fileX));
    Shell32.FolderItem folderItem_photX = objFolder_photX.ParseName(Path.GetFileName(fileX));
    string stringX = objFolder_photX.GetDetailsOf(folderItem_photX, 12); //撮影日時

    Shell32.Folder objFolder_photY = shell.NameSpace(Path.GetDirectoryName(fileY));
    Shell32.FolderItem folderItem_photY = objFolder_photY.ParseName(Path.GetFileName(fileY));
    string stringY = objFolder_photY.GetDetailsOf(folderItem_photY, 12); //撮影日時

    if (stringX == "")
    {
        Shell32.Folder objFolder = shell.NameSpace(Path.GetDirectoryName(fileX));
        Shell32.FolderItem folderItem = objFolder.ParseName(Path.GetFileName(fileX));
        stringX = objFolder.GetDetailsOf(folderItem, 3); //更新日時
    }
    if(stringY == "")
    {
        Shell32.Folder objFolder = shell.NameSpace(Path.GetDirectoryName(fileY));
        Shell32.FolderItem folderItem = objFolder.ParseName(Path.GetFileName(fileY));
        stringY = objFolder.GetDetailsOf(folderItem, 3); //更新日時
    }

    DateTime datetimeX = 
        DateTime.ParseExact(stringX, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
    DateTime datetimeY =
        DateTime.ParseExact(stringY, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);

    return DateTime.Compare(datetimeX, datetimeY);
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

Shell32で取り出した値に不要な文字が含まれています。
デバッガでは正常に見えますが、ToCharArrayをすれば分かるかと思います。
その不要な文字を取り除けば、ParseExactは可能でした。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/10 18:16

    アドバイスいただいたとおりToCharArrayで分解後、
    正規表現でdatetimeでは使用しない文字列が入っていた場合は取り除くことで解決できました。

    キャンセル

+3

ParseExactは変換できない場合に例外が発生します。例外処理を入れたくなければTryParseExactを使えば可能です。

日時を表す文字列をDateTimeオブジェクトに変換する

ただ、画像の撮影日時であれば、shell32を使ってもいいのですが、Exif情報で取得したほうがいいと思います。

サンプルは、以下にあります。
画像のExif情報を取得する、設定する
デジカメ画像のExif情報を取得するには?

画像に撮影日時が含まれていない場合もあるので、2つ目のサンプルのほうがいいかもしれません。(2つ目の方はそのチェックもしている)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/10 18:17

    ご回答ありがとうございました。
    今回は余計な文字コードを取り除き解決しましたが、他でexifを使用する機能があるので
    参考にさせていただきます。

    キャンセル

+2

エラーメッセージのとおり、DateTime型には変換できない文字列なんでしょう。
そのstringXとstringYはどういう文字列なんでしょうか

VisualStudioを使ってるなら、その行にブレークポイントを設定すれば、そこで実行を止めて各変数の値を見れるはずですが

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/10 17:17

    >> VisualStudioを使ってるなら、その行にブレークポイントを設定すれば、そこで実行を止めて各変数の値を見れるはずですが
    「2018/11/29 16:48」や「‎2012/‎07/‎19 ‏‎10:47」はその方法で確認しました。

    キャンセル

  • 2018/12/10 17:29

    その日付をコピーして、サクラエディタで確認すると、月、日、時の前にU+200Eの文字が入ってますね
    そのせいで例外になったようです

    キャンセル

  • 2018/12/10 18:17

    ご回答ありがとうございました。
    アドバイスいただいたとおり余計な文字コードが混入していました。
    取り除き解決しました。

    キャンセル

+1

文字列の中に U+200E と U+200F が入っています。
双方向テキスト

これが失敗の原因です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/10 18:16

    ご回答ありがとうございました。
    U+200E と U+200F を取り除き無事に変換することができました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C#

    9489questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • .NET Framework 4.0

    88questions

    Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。