概要
サーバーから取得した時刻数値(UnixTime)をC#のDateTime型に変換する時どうしてますか?
数か所ならともかく、何か所もあったらどうします?ユーティリティメソッド作る?
型キャスト演算子オーバーロードしたこんな方法はどうでしょうか。
変換専用クラス
変換を簡単に書けるようにこのようなクラスを用意してみました。
using System;
/// <summary>
/// Unixのエポック秒とDateTimeを変換するための構造体
/// </summary>
public struct UnixTime
{
private readonly DateTime _dateTime;
private static readonly DateTime UnixEpochBase = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public UnixTime(uint unixEpochDate)
{
_dateTime = UnixEpochBase.AddSeconds(unixEpochDate).ToLocalTime();
}
/// <summary>
/// UnixTime型からDateTime型に変換する。
/// </summary>
/// <param name="from">基準となるUnixTime</param>
/// <returns>DateTime</returns>
public static implicit operator DateTime(UnixTime from)
{
return from._dateTime;
}
}
2018/11/12: コメントでご指摘いただいたので class から struct に変更しました。
2018/11/13: 同じくコメントでのアドバイスにより、コンストラクタで変換してDateTimeを保持するようにしました。
使い方
時刻数値を引数にしてUnixTimeオブジェクトを作り、代入するだけ。
public class Hoge
{
private DateTime dateTime;
public void SetTime(uint epocSeconds)
{
dateTime = new UnixTime(epocSeconds);
}
}
解説
public static implicit operator DateTime(UnixTime from)
というのは演算子オーバーロードの一つで、この場合UnixTime型からDateTime型への暗黙的な型変換を定義するものです。
つまり、dateTime = new UnixTime(epocSeconds);
と書くと自動的に上記の型変換メソッドが呼ばれるわけです。
ちなみに暗黙的型変換に対して明示的型変換というのもあります。
キーワードimplicitの代わりにexplicitを使います。そのようにして演算子オーバーロードを定義すると、dateTime = (DateTime)new UnixTime(epocSeconds);
のように明示的に型キャストを指示する必要があります。