読者です 読者をやめる 読者になる 読者になる

伝説のツール「NotesPeek」をQtでリメイクする(その7・日時その1)

f:id:takahide-kondoh:20170509070312p:plain

Notesにおいて基本的なデータ型3つを挙げるとすると、テキスト型、日時型、数値型となるでしょう。また、それらの複数形「テキストリスト型」、「日時リスト型」、「数値リスト型」も存在します。その他に、@式で紹介した「バイナリ型」、整形可能な「リッチテキスト型」などもあります。

ここでは、その中の「日時型」を扱います。テキスト型はLMBCS文字列で紹介しました。数値型の実体は「double型」なので、あまり詳しく触れなくてもいいでしょう。

日時型は、Notes APIではTIMEDATE構造体で表します。C/C++ではtime_t型、構造体tmなどで表されていますが、直接の互換性はないようです。QtではQDateTime、QDate、QTimeなどで表します。今回は、TIMEDATEとQtの日時型との相互互換を可能にします。また、文字列との相互変換も紹介します。

まず、TIMEDATE構造体について見てみます。

#include <global.h>

typedef struct tagTIMEDATE {
    DWORD Innards[2];
} TIMEDATE;

TIMEDATEは独自のバイナリ形式を持っているため直接扱えません。必ずAPIを通して使います。

現在の日時を取得するには、OSCurrentTIMEDATEを使用します。

#include <ostime.h>

void LNPUBLIC OSCurrentTIMEDATE (TIMEDATE far *retTimeDate);

// ex)
TIMEDATE timeDate;
OSCurrentTIMEDATE(&timeDate);

TIMEDATEには「特殊な値」という3つの定数があります。最小値、最大値、ワイルドカードの3つです。これらを取得するには、TimeConstant関数を使います。

#include <misc.h>

#define TIMEDATE_MINIMUM     0
#define TIMEDATE_MAXIMUM     1
#define TIMEDATE_WILDCARD 2
void LNPUBLIC TimeConstant(WORD, TIMEDATE far *);

f:id:takahide-kondoh:20170510211450p:plain

TIMEDATE構造体の内容をテキストに変換するにはConvertTIMEDATEToText関数を使います。逆に、日時を表したテキストをTIMEDATEにするにはConvertTextToTIMEDATE関数を使います。

#include <misc.h>

STATUS LNPUBLIC ConvertTIMEDATEToText (
    const void far *IntlFormat,
    const TFMT far *TextFormat,
    const TIMEDATE far *InputTime,
    char far *retTextBuffer,
    WORD TextBufferLength,
    WORD far *retTextLength);

STATUS LNPUBLIC ConvertTextToTIMEDATE (
    const void far *IntlFormat,
    const TFMT far *TextFormat,
    char far * far *Text,
    WORD MaxLength,
    TIMEDATE far *retTIMEDATE);

「IntlFormat」は国際フォーマットといって、構造体INTLFORMATで表すフォーマットです。

#include <intl.h>

typedef struct {
    WORD Flags;    /* Flags (see above) */
    BYTE CurrencyDigits;
    BYTE Length;    /* Length of this structure */
    /* THIS MUST BE SET TO THE EXACT */
    /* SIZE OF THE STRUCTURE WHEN ITS */
    /* POINTER IS PASSED AS AN ARGUMENT */
    int TimeZone;
    char AMString[ISTRMAX];
    char PMString[ISTRMAX];
    char CurrencyString[ISTRMAX];
    char ThousandString[ISTRMAX];
    char DecimalString[ISTRMAX];
    char DateString[ISTRMAX];
    char TimeString[ISTRMAX];
    char YesterdayString[YTSTRMAX];
    char TodayString[YTSTRMAX];
    char TomorrowString[YTSTRMAX];
} INTLFORMAT;

デフォルト(日本語環境)では、INTLFORMAT型には以下のような値が入っています。

f:id:takahide-kondoh:20170510125825p:plain

文字列はLMBCS形式です。

「TextFormat」は日時フォーマットで、TFMT構造体で表します。TFMTでは@関数の@Text()で日時変換に使用するような選択肢がありますが、詳細は今回割愛します。IntlFormatもTextFormatも、デフォルトでよければ0(ヌルポインタ)を渡します。

日時のテキスト化に必要なバイト数はMAXALPHATIMEDATE定数を使うことができます。

ここまでの説明で、Notes APIの日時型であるTIMEDATE構造体に関する基本的なAPIを見ました。次回は、Notes APIが用意している日時変換のためのデータ型と関数を紹介します。