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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

.NET Framework 4.0

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

Q&A

解決済

4回答

3633閲覧

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

asus2

総合スコア22

C#

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

.NET Framework 4.0

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

0グッド

0クリップ

投稿2018/12/10 07:55

編集2018/12/10 07:57

お世話になります。

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

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

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

【string型→DateTime型変換部分】

c#

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

【エラーメッセージ】

c#

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

【関数全ソース】

c#

1 2static int Compare(string fileX, string fileY) 3{ 4 Shell32.Shell shell = new Shell32.Shell(); 5 6 Shell32.Folder objFolder_photX = shell.NameSpace(Path.GetDirectoryName(fileX)); 7 Shell32.FolderItem folderItem_photX = objFolder_photX.ParseName(Path.GetFileName(fileX)); 8 string stringX = objFolder_photX.GetDetailsOf(folderItem_photX, 12); //撮影日時 9 10 Shell32.Folder objFolder_photY = shell.NameSpace(Path.GetDirectoryName(fileY)); 11 Shell32.FolderItem folderItem_photY = objFolder_photY.ParseName(Path.GetFileName(fileY)); 12 string stringY = objFolder_photY.GetDetailsOf(folderItem_photY, 12); //撮影日時 13 14 if (stringX == "") 15 { 16 Shell32.Folder objFolder = shell.NameSpace(Path.GetDirectoryName(fileX)); 17 Shell32.FolderItem folderItem = objFolder.ParseName(Path.GetFileName(fileX)); 18 stringX = objFolder.GetDetailsOf(folderItem, 3); //更新日時 19 } 20 if(stringY == "") 21 { 22 Shell32.Folder objFolder = shell.NameSpace(Path.GetDirectoryName(fileY)); 23 Shell32.FolderItem folderItem = objFolder.ParseName(Path.GetFileName(fileY)); 24 stringY = objFolder.GetDetailsOf(folderItem, 3); //更新日時 25 } 26 27 DateTime datetimeX = 28 DateTime.ParseExact(stringX, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None); 29 DateTime datetimeY = 30 DateTime.ParseExact(stringY, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None); 31 32 return DateTime.Compare(datetimeX, datetimeY); 33}

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

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

投稿2018/12/10 08:27

編集2018/12/10 08:41
YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asus2

2018/12/10 09:16

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

0

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

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

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

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

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

投稿2018/12/10 08:22

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asus2

2018/12/10 09:17

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

0

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

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

投稿2018/12/10 08:05

編集2018/12/10 08:08
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asus2

2018/12/10 08:07

fileX、fileY共に、"yyyy/MM/dd HH:mm"の形式でstring型の日時が取得できています。 「2018/11/29 16:48」や「‎2012/‎07/‎19 ‏‎10:47」です。 上記の組み合わせだと、「‎2012/‎07/‎19 ‏‎10:47」のみが変換できません。
asus2

2018/12/10 08:09

「‎2012/‎07/‎19 ‏‎10:47」は下記のソースでfileYから取得しました。 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); //撮影日時
asus2

2018/12/10 08:17

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

2018/12/10 08:29

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

2018/12/10 09:17

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

0

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

これが失敗の原因です。

投稿2018/12/10 08:41

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asus2

2018/12/10 09:16

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問