スポンサーリンク

誰もが一度は陥る日付処理。各種プログラミング言語におけるDateTime型/TimeStamp型の変換方法のまとめにC#が無いので追加

誰もが一度は陥る日付処理。各種プログラミング言語におけるDateTime型/TimeStamp型の変換方法のまとめ – Yuta.Kikuchiの日記.

例のごとくC#が無いので勝手に追加する。VBも基本一緒だ。

ついカッとなってやったが、後悔はしていない。

.NET Frameworkで日付、時刻を扱うのはDateTime型(クラス)だ。

現在時刻の取得

当然C#なら何も悩まない。悩む必要など無い。

Console.WriteLine("現在時刻");
var _now = DateTime.Now;
Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now);

現在時刻のTimeStamp取得

.Net Framewrokは当然UnixのTimeStampなんて知ったこっちゃ無いのでこれは変換が必要。
DateTime型は1970からとかケチくさいことは言わず西暦1年からのシリアル値を内部的に持つので、以下のように1970/1/1までの時刻値を求めて、現在時刻(UTC)との差分をとるように計算する。

//現在時刻からTimeStampを取得するよ
Console.WriteLine("現在時刻をタイムスタンプにする");
//1970/1/1からの経過時間をTicksプロパティを使い100ns単位で計算し、秒数に変換する。
uint _nowTimestamp = (uint)((DateTime.UtcNow.Ticks - DateTime.Parse("1970-01-01 00:00:00").Ticks)/10000000);
Console.WriteLine("TIMESTAMP = {0}", _nowTimestamp);

DateTime => TimeStamp変換

先ほどの逆になるが、秒数単位で足し込むためのメソッドが用意されているのでコードは楽な感じになる。

//TimeStampから時刻に戻すよ
Console.WriteLine("タイムスタンプを現在時刻に戻すよ");
var unixOriginTime = new DateTime(1970, 1, 1, 0, 0, 0);
var _now2 = unixOriginTime.AddSeconds(_nowTimestamp).ToLocalTime();
Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now2);

C#でのまとめ

そもそもUnixのTimeStampとかめんどくさい。WindowsならFILETIMEかVT_DateだろJK。ま、.NETのDateTimeはそのどっちでも無いけどな。
日付の文字列変換は、このサンプルのような固定変換じゃ無くて、よい子はユーザーロケールの設定使うようにしようね。
こんな事毎回書いているのはめんどくさいので、よい子はヘルパークラスのライブラリ作って、DateTime型の拡張クラスにしましょう。

異論は認める。

全体コード:
(ご要望によりDateTimeOffsetでのコードも追加 23:26)

using System;

namespace DateTimeSample
{
    class Program
    {
        static void Main(string[] args) {
            //現在時刻を取得するよ
            Console.WriteLine("現在時刻");
            var _now = DateTime.Now;
            Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now);

            //現在時刻からTimeStampを取得するよ
            Console.WriteLine("現在時刻をタイムスタンプにする");
            //1970/1/1からの経過時間をTicksプロパティを使い100ns単位で計算し、秒数に変換する。
            uint _nowTimestamp = (uint)((DateTime.UtcNow.Ticks - DateTime.Parse("1970-01-01 00:00:00").Ticks) / 10000000);
            Console.WriteLine("TIMESTAMP = {0}", _nowTimestamp);

            //TimeStampから時刻に戻すよ
            Console.WriteLine("タイムスタンプを現在時刻に戻すよ");
            var unixOriginTime = new DateTime(1970, 1, 1, 0, 0, 0);
            var _now2 = unixOriginTime.AddSeconds(_nowTimestamp).ToLocalTime();
            Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now2);

            //Console.Read();

            Console.WriteLine("nおまけご要望によりDateTimeOffsetを使ってみる(が、たいして変わらないよ)");

            Console.WriteLine("現在時刻");
            var _now3 = DateTimeOffset.Now;
            Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now);

            //現在時刻からTimeStampを取得するよ
            Console.WriteLine("現在時刻をタイムスタンプにする");
            //1970/1/1からの経過時間をTicksプロパティを使い100ns単位で計算し、秒数に変換する。
            uint _nowTimestamp2 = (uint)((DateTimeOffset.UtcNow.Ticks - DateTimeOffset.Parse("1970-01-01 00:00:00").Ticks) / 10000000);
            Console.WriteLine("TIMESTAMP = {0}", _nowTimestamp2);

            //TimeStampから時刻に戻すよ
            Console.WriteLine("タイムスタンプを現在時刻に戻すよ");
            var unixOriginTime2 = new DateTimeOffset(1970, 1, 1, 0, 0, 0, new TimeSpan(0)); //ここだけちょっと違う感じに。UTCなのでオフセット(時差)は0
            var _now4 = unixOriginTime2.AddSeconds(_nowTimestamp).ToLocalTime();
            Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now4);

            Console.Read();
        }
    }
}

.NET Framework 4.6以降 (2015/10/14追記)

.NET Framework 4.6以降ではDateTimeOffset型にUNIX時間との変換メソッドが追加されたので、特に悩む必要は無くなっている。

サンプルコード:

// これ以下は.NET 4.6からの方法
Console.WriteLine("\nおまけご要望によりDateTimeOffsetを使ってみる(.NET 4.6)");

Console.WriteLine("現在時刻");
var _now5 = DateTimeOffset.Now;
Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now);
//現在時刻からTimeStampを取得するよ
Console.WriteLine("現在時刻をタイムスタンプにする");
long _nowTimeStamp3 = _now5.ToUnixTimeSeconds();
Console.WriteLine("TIMESTAMP = {0}", _nowTimeStamp3);

//TimeStampから時刻に戻すよ
Console.WriteLine("タイムスタンプを現在時刻に戻すよ");
var _now6 = DateTimeOffset.FromUnixTimeSeconds(_nowTimeStamp3).ToLocalTime();
Console.WriteLine("DATETIME = {0:yyyy-MM-dd hh:mm:ss}", _now6);

全コードのGist

コメント

  1. 匿名 より:
タイトルとURLをコピーしました