【C#】Microsoft.Recognizers.Text.DateTime を使って「明日」などの自然言語を元に日時を生成する方法

  • 2023年8月18日
  • C#

 プログラミングにおいて日時を操作する場面はよくあります。この際、人間が理解しやすい形式で日時をパースする必要がある場合には言語組み込みの機能だけでは対応難しいことが多いです。この記事では、C#でToday、今日のような自然言語を元に日時を生成する方法について説明します。

 Microsoft.Recognizers.Text.DateTime というライブラリがあります。これは文字列から特定の情報(数値、金額など)を認識して抽出するためのライブラリである Microsoft.Recognizers.Text の中の一つで日時を抽出するものです。これを使うことで自然言語で日時指定をできるようにします。

microsoft/Recognizers-Text: Microsoft.Recognizers.Text provides recognition and resolution of numbers, units, date/time, etc. in multiple languages (ZH, EN, FR, ES, PT, DE, IT, TR, HI, NL. Partial support for JA, KO, AR, SV). Packages available at: https://www.nuget.org/profiles/Recognizers.Text, https://www.npmjs.com/~recognizers.text

NuGet Gallery | Microsoft.Recognizers.Text.DateTime 1.8.8

 具体的な例は次です。

using Microsoft.Recognizers.Text;
using Microsoft.Recognizers.Text.DateTime;

namespace MyApp.Services
{
    /// <summary>
    /// 日時を扱うクラスです。
    /// </summary>
    public class DateTimeService
    {
        /// <summary>
        /// 日時をパースする。C#組み込みよりもずっと柔軟にパースする
        /// </summary>
        /// <param name="metaValue">パース対象</param>
        /// <returns>日時。もしパースできなければnull</returns>
        /// <summary>
        /// 日時をパースする。C#組み込みよりもずっと柔軟にパースする
        /// </summary>
        /// <param name="metaValue">パース対象</param>
        /// <returns>日時。もしパースできなければnull</returns>
        public static DateTime? StrToTime(string? metaValue)
        {
            // 日時文字列のパーサーを用意。本日などに対応させるため
            var cultures = new string[] { Culture.English, Culture.Japanese };
            foreach (var cul in cultures)
            {
                // 本日などの表現をパースするために、DateTimeRecognizerを使う
                var recognizer = new DateTimeRecognizer(cul);
                var results = recognizer.GetDateTimeModel().Parse(metaValue);
                // 本日などの表現が見つかった場合は、その日付を返す
                if (results.Count > 0 && results[0].Resolution["values"] is List<Dictionary<string, string>> values
                    && DateTime.TryParse(values[0]["value"], out DateTime metaDateTime))
                {
                    return metaDateTime;
                }
            }

            // 文字列を元にした日時が見つからなかった場合は null を返す
            return null;
        }
}

 これは例えば次の様に動作します。

using MyApp.Services;
using Xunit;

namespace MyApp.Tests
{
    public class DateTimeServiceTests
    {
        [Fact]
        public void StrToTimeTest()
        {
            // 以下のAsserすべてに合格します
            Assert.Equal(DateTime.Today, DateTimeService.StrToTime("Today"));
            Assert.Equal(DateTime.Today, DateTimeService.StrToTime("今日"));
            Assert.Equal(DateTime.Today.AddDays(1), DateTimeService.StrToTime("明日"));
            Assert.Equal(DateTime.Today.AddMonths(-3), DateTimeService.StrToTime("3か月前"));
        }
    }
}

 この様なコードにより自然言語による日時の指定を柔軟に取り扱うことが可能になります。例では English と Japanese 、つまり英語と日本語にのみ対応させましたが Microsoft.Recognizers.Text.DateTime はより多くの言語に対応しているため多言語対応も簡単です。

 Microsoft.Recognizers.Text.DateTime ライブラリを使用すると、C#で自然言語を元にした日時の解析が容易に行えます。これはユーザーから自然言語での入力も受け付けたい場合、ある時点からの相対的な日時を理解しやすく記述したい場合などで役に立ちます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG