次のような相対datetime
文字列があります。
- "5分前"
- 「10時間前」
- 「3日前」など
この質問datetime
の正反対のように、これを正確に変換するにはどうすればよいですか
このコードは動作するはずです:
string input = "10 days ago";
DateTime result = DateTime.MinValue;
int minutesMultiplier = 0;
if (input.Contains("minute"))
minutesMultiplier = 1;
else
if (input.Contains("hour"))
minutesMultiplier = 60;
else
if (input.Contains("day"))
minutesMultiplier = 1440;
else
throw new Exception("Couldn't parse time format");
string numberStr = input.Split(' ')[0];
int number;
if (int.TryParse(numberStr, out number))
result = DateTime.Now.AddMinutes(-number * minutesMultiplier);
間隔名 (分、時間、日など) の解析を行い、それらを乗算して分数を取得します。これは、後でメソッドを使用するためDateTime.Now.AddMinutes
です。TimeSpan
DateTime.Now.Add
「10時間15分前」など、複数の間隔名を含む文字列の大文字と小文字を処理するもう1つの例を次に示します。
// If there are mixed interval types in an input string
string input = "10 days and 10 hours ago";
// Parse out the intervals and numbers
var matches = Regex.Matches(input,
@"(?<number>\d+)\s(?<interval>(day)|(minute)|(hour))");
// Convert them to dictionary
var dic = matches
.Cast<Match>()
.ToDictionary(
key => key.Groups["interval"].Value,
o => int.Parse(o.Groups["number"].Value));
// Calculate the total number of minutes for each interval
DateTime result = DateTime.MinValue;
int totalMinutes = 0;
foreach (var keyValue in dic)
{
if (keyValue.Key.Contains("minute"))
totalMinutes += keyValue.Value;
else
if (keyValue.Key.Contains("hour"))
totalMinutes += keyValue.Value * 60;
else
if (keyValue.Key.Contains("day"))
totalMinutes += keyValue.Value * 1440;
else
throw new Exception("Unparsable time format");
}
result = DateTime.Now.AddMinutes(-totalMinutes);
そのためには、逆のことをしなければならなかったのと同じように、独自のルーチンを作成する必要があります。
基本的に、テキストを解析して、間隔 (つまり、分、時間、日など)、量、およびそれが過去か未来か (ago
またはを使用from
) を見つける必要があります。
この時点で、適切なTimeSpan
インスタンスを構築し、それを使用してDateTime.Now
その時間を取得するのに十分なデータが得られます。
上記が機能するためには、解析する文字列値が標準化されていることを確認する必要があります。
適切な方法は、相対値を値として保存し、それを(またはベースとして使用したいものTimeSpan
から)減算することです。DateTime.Now
DateTime
int.Parse
数値 (分数、時間数など) を整数値に変換し、それらを値にコピーするなどの方法を使用できTimeSpan
ます。正確な解析アルゴリズムは、文字列の実際の形式、つまり、そこに許可されている単語と、数値が表示される順序によって異なります。
質問に示されているように文字列がすでに分離されている場合は、正規表現を使用してそれらを分解してみることができます ( Regex
classを使用):
^(\d+)\s+([a-z]+)\s+ago$