LoginSignup
5
4

More than 5 years have passed since last update.

D言語の時間の扱い

Last updated at Posted at 2016-10-01

D言語の時間の扱いがよくわからないのでメモ。
固定フレームレートのメインループを実装したかっただけなのだけど・・・

Time Points

時間軸の一点を指す。
4種類ある。

SysTime

hnsecs精度のSystemClock。Timezone付き

std.datetime.Clock.currTime();

現在時刻を取得するのはこれ。
https://dlang.org/phobos/std_datetime.html#.Clock.currTime

Date

日付。Timezone無し。

cast(std.datetime.Date)std.datetime.Clock.currTime

todayとか探していたら見つからなくて時間かかった。castだったとは。

TimeOfDay

00:00:00 - 23:59.59。Timezone無し

cast(std.datetime.TimeOfDay)std.datetime.Clock.currTime

DateTime

Date + TimeOfDay。Timezone無し

cast(std.datetime.DateTime)std.datetime.Clock.currTime

Duration

時間の長さの表現。
C#のTimeSpanにあたる。

dur関数で作れる。

std.datetime.dur!"hours"(17)

もしくはTimePointsの引き算で作れる。

std.datetime.TimeOfDay(17, 2)-std.datetime.TimeOfDay(16, 2)

特定の単位の数に変換するにはtotalを使う。

auto h=std.datetime.dur!"hours"(1);
auto m=h.total!"minutes";
writefln("%s: %s", typeid(m), m);

|| long: 60

以下の単位(unit)がある。

  • years
  • months
  • weeks
  • days
  • hours
  • minutes
  • seconds
  • msecs
  • usecs
  • hnsecs
  • nsecs

Time Intervals

TimePointsを起点にした時間のレンジ。
Durationは単純に長さだが、Time Intervalは時間軸の範囲を指す。
あまり使わなさそうである。

DurationとSysTimeの精度は100nsec

C#のTimeSpanのTickとかと同じ。
64bitで100nsecを保持すると
29,000 B.C.から29,000 A.Dを表現できるらしい。

time_t

unix time.

  auto t=std.datetime.Clock.currTime();
    printWithType(t);
    printWithType(t.toUnixTime);
    auto s=std.datetime.unixTimeToStdTime(t.toUnixTime);
    printWithType(std.datetime.SysTime(s));

|| std.datetime.SysTime: 2016-Oct-01 16:22:26.7489453
|| int: 1475306546 <- unix_time
|| std.datetime.SysTime: 2016-Oct-01 16:22:26

std.datetime.StopWatch

FPS待ちクラス

class FpsClock(int Target, int MarginMsecs = 5)
{
    import std.datetime;
    SysTime m_lastTime;

    static immutable Duration frameDuration=dur!"msecs"(1000/Target - MarginMsecs);

    this()
    {
        m_lastTime=Clock.currTime;
    }

        // loopの頭に呼ぶ
    Duration newFrame()
    {
        auto now=Clock.currTime;
        auto duration=now-m_lastTime;
        m_lastTime=now;
        return duration;
    }

        // loopの終わりで呼んで早すぎる場合にはsleepして待つ
    void waitNextFrame()
    {
        import core.thread;

        auto now=Clock.currTime;
        auto delta=now-m_lastTime;
        if(delta < frameDuration)
        {
            auto wait=frameDuration-delta;
            Thread.sleep(wait);
        }
    }
}

Clock.currTimeで実装してみた。
StopWatchの方が精度がよかったりするのだろうか。

auto fps=new FpsClock!30
while(loop)
{
    auto delta=fps.newFrame();

    // rendering...

    fps.waitNextFrame();
}

終わり

とりあえず

std.datetime.Clock.currTime

を押さえておけば他はドキュメントを見ればよい。

参考

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4