Y's note

Web技術・プロダクトマネジメント・そして経営について

本ブログの更新を停止しており、今後は下記Noteに記載していきます。
https://note.com/yutakikuchi/

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

日付型の変換処理

Date/Timestamp変換のまとめ - Yuta.Kikuchiの日記 はてなブックマーク - Date/Timestamp変換のまとめ - Yuta.Kikuchiの日記
10言語のプログラミング言語に対してそこそこの知識を保有している@yutakikucです。いろんなプログラミング言語を使用していると文法を覚えるのは大変ですよね。PHP書いている途中からJavaScriptの文法を誤って書き始めたり... それぞれの言語の文法の違いを事細かく覚える事は無理に近いです。今日はそんな各種言語仕様の記述で難解なDateTime/TimeStampについて紹介したいと思います。扱うのはWeb系のメジャープログラミング言語SQL/C++/Java/JavaScript/Perl/PHP/Python/Rubyになります。Mysqlからデータを取り出した後や、WebAPIから取得したデータを表示用の日付フォーマットに変換する事があると思うのでそこで利用できる知識になるかと思います。そもそもDateTime型/TimeStamp型って何だよっていう人もいるかと思うので簡単にまとめると以下のようになります。※ここでのTimeStampはUnixTimeを表現しています。

意味
DateTime YYYY-MM-DD HH:mm:SSで表現する時刻Format 2013-05-31 20:33:20
TimeStamp 1970/1/1からの秒数で上限は2037年まで 1370000000

変換重要処理早見表

言語 DateTime取得 TimeStamp取得 DateTime変換 => TimeStamp TimeStamp => DateTime変換
Mysql NOW() UNIX_TIMESTAMP() UNIX_TIMESTAMP() FROM_UNIXTIME()
C++ time_t型, struct tm構造体, strftime(datetime, N, "%Y-%m-%d %H:%M:%S",tm ) time_t型, time(NULL) time_t型,struct tm構造体,strptime(datetime, "%Y-%m-%d %H:%M:%S", &tm ), mktime(&tm) time_t型,struct tm構造体, localtime(), strftime(datetime, N, "%Y-%m-%d %H:%M:%S",tm );
Java new Date(), new SimpleDateFormat("yyyy'-'MM'-'dd' 'HH':'mm':'ss"), sdf.format() new Date(), date.getTime() new Date(), new SimpleDateFormat("yyyy'-'MM'-'dd' 'HH':'mm':'ss"),sdf.parse(),date.getTime() new Date(), new SimpleDateFormat("yyyy'-'MM'-'dd' 'HH':'mm':'ss"), sdf.format()
JavaScript new Date(), getFullYear()等のメソッド parseInt( new Date() / 1000 ) Date.parse( datetime.replace( /-/g, '/') ) / 1000 new Date(timestamp*1000), getFullYear()等のメソッド
Perl strftime( "%Y-%m-%d %H:%M:%S" , localtime()) time Time::Local,DateTime::Format::Strptime,Time::Pieceモジュールを使う strftime( "%Y-%m-%d %H:%M:%S" , localtime($utime))
PHP date("Y-m-d H:i:s") / strftime("%Y-%m-%d %H:%M:%S") time() strtotime( $datetime ) date( "Y-m-d H:i:s", $utime ) / strftime("%Y-%m-%d %H:%M:%S", $utime )
Python datetime.now().strftime( '%Y-%m-%d %H:%M:%S' ) int(time()) int( time.mktime( datetime.strptime( dtime, "%Y-%m-%d %H:%M:%S" ).timetuple() ) ) datetime.fromtimestamp( utime )
Ruby Time.now.strftime "%Y-%m-%d %H:%M:%S" Time.now.to_i Time.parse(datetime).to_i Time.at(utime).strftime "%Y-%m-%d %H:%M:%S"

簡単にDateTime/TimeStamp処理ができるのはMysql,PHP,Rubyになると思います。Mysql,PHP,Rubyは一つの関数やメソッドの利用で処理できるのでコードの記述量が少なくて済みます。それとは反対に特にC++は構造体の変換がややこしい、Perlはデフォルトでstrptimeが使えなく必要なModuleの設定が大変であること、Pythonは記述が複雑で直感的では無いのでとても覚えられずメモの必要があります。

Mysqlのお話

現在時刻のDateTime取得

NOW()を使います。

mysql> SELECT NOW() AS DATETIME;
+---------------------+
| DATETIME            |
+---------------------+
| 2013-06-15 19:36:53 |
+---------------------+
1 row in set (0.00 sec)
現在時刻のTimeStamp取得

UNIX_TIMESTAMP()を使います。

mysql> SELECT UNIX_TIMESTAMP() AS TIMESTAMP;
+------------+
| TIMESTAMP  |
+------------+
| 1371292653 |
+------------+
1 row in set (0.00 sec)
DateTime => TimeStamp変換

UNIX_TIMESTAMP()にDATETIMEを指定します。

mysql> SELECT UNIX_TIMESTAMP('2013-06-15 19:37:33') AS TIMESTAMP;
+------------+
| TIMESTAMP  |
+------------+
| 1371292653 |
+------------+
1 row in set (0.00 sec)
TimeStamp => DateTime変換

FROM_UNIXTIME()にTIMESTAMPを指定します。

mysql> SELECT FROM_UNIXTIME(1371292653) AS DATETIME;
+---------------------+
| DATETIME            |
+---------------------+
| 2013-06-15 19:37:33 |
+---------------------+
1 row in set (0.01 sec)
Mysqlのまとめ
  • MysqlのDateTime/TimeStamp処理は標準の関数で完結するので楽。
  • 現在時刻をDateTimeで取得するにはNOW()を使用する。
  • 現在時刻をTimeStampで取得するにはUNIX_TIMESTAMP()を使用する。
  • TimeStampをDateTimeに変換するにはFROM_UNIXTIME()にTimeStampを指定する。
  • DateTimeをTimeStampに変換するにはUNIX_TIMESTAMP()にDateTimeを指定する。

C++のお話

現在時刻のDateTime取得

time_t型とstruct tm*を使用します。localtime関数がtm構造体を返してくれます。

#include <iostream>
#include <time.h>
#define N 20
using namespace std;
int main() {
   time_t timer;
   struct tm* tm;
   char datetime[N];
   timer = time(NULL);
   tm = localtime(&timer);
   strftime(datetime, N, "%Y-%m-%d %H:%M:%S",tm );
   cout << "DATETIME = " << datetime << endl;
   return 0;
}
// 結果
// DATETIME = 2013-06-15 10:45:33
現在時刻のTimeStamp取得

time_t型とtime関数を使用します。

#include <iostream>
#include <time.h>
using namespace std;
int main() {
   time_t epoch_time;
   epoch_time = time(NULL);
   cout << "TIMESTAMP = " << epoch_time << endl;
   return 0;
}
// 結果
// TIMESTAMP = 1371256675
DateTime => TimeStamp変換

const char型の文字列として定義されているDateTimeをTimeStamp型に変換します。一度const charからtm構造体に変換し、mktime関数でtm構造体をTimeStamp型に変換します。

#include <iostream>
#include <time.h>
#define N 20
using namespace std;
int main() {
   time_t timer;
   struct tm tm;
   const char* datetime = "2013-06-15 12:00:00";
   if( strptime(datetime, "%Y-%m-%d %H:%M:%S", &tm ) != NULL ) {
      cout << "TIMESTAMP = " << mktime(&tm) << endl;
   }
   return 0;
}
// 結果
// DATETIME = 1371265200
TimeStamp => DateTime変換

最初に掲載したDateTimeの取得と似ていて、int型をtime_tに変換した値をlocaltime関数に入れてtmの構造体を作成しています。

#include <iostream>
#include <time.h>
#define N 20
using namespace std;
int main() {
   unsigned int timestamp = 1371265200;
   time_t timer;
   struct tm* tm;
   char datetime[N];
   timer = (time_t)timestamp;
   tm = localtime(&timer);
   strftime(datetime, N, "%Y-%m-%d %H:%M:%S",tm );
   cout << "DATETIME = " << datetime << endl;  
   return 0;
}
// 結果
// DATETIME = 2013-06-15 12:00:00
C++での変換まとめ
  • C++のDateTime/TimeStamp処理はtime_t型とstruct tmの変換を利用するのでやや表現が複雑になる。
  • time_t型はTimeStamp/UnixTimeを表現する構造体。
  • struct tmは年月日,時間をそれぞれのメンバ変数に格納する構造体。
  • localtime関数はtime_t型をtm構造体に変換する。
  • strftimeはtm構造体を任意の文字列に変換する。
  • strptimeは任意の文字列をtm構造体に変換する。

Javaのお話

※2013/07/20修正 : ななしさんから指摘頂いた時間のFormatをhh→HHに修正。

現在時刻のDateTime取得

Date型をSimpleDateFormatClassを使って特定のFormat文字列に変換します。

import java.util.*;
import java.text.*;
class DateTime {
   public static void main(String[] args) {
      Date date = new Date();
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy'-'MM'-'dd' 'HH':'mm':'ss");
      System.out.println("DATETIME = " + sdf.format(date));
   }
}
// 結果
// DATETIME = 2013-06-15 01:43:58
現在時刻のTimeStamp取得

Date型からmillisecをgetTimeメソッドで取得し1000で割ります。

import java.util.*;
class TimeStamp {
   public static void main(String[] args) {
      Date date = new Date();
      System.out.println("TIMESTAMP = " + date.getTime()/1000);
   }
}
// 結果
// TIMESTAMP = 1371271256
DateTime => TimeStamp変換

String文字列のDateTimeをSimpleDateFormatを利用してDate型に変換してTimeStampを出力します。

import java.util.*;
import java.text.*;
class TimeStamp {
   public static void main(String[] args) {
      try {
         String datetime = "2013-06-15 01:43:58";
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy'-'MM'-'dd' 'HH':'mm':'ss");
         Date date = sdf.parse( datetime );
         System.out.println("TIMESTAMP = " + date.getTime()/1000);
      } catch(ParseException e) {
         e.printStackTrace();
      }
   }
}
// 結果
// TIMESTAMP = 1371228238
TimeStamp => DateTime変換

DateObjectを生成する際にlong型のtimestampを引数に入れてSimpleDateFormatでDateTime型に変換します。

import java.util.*;
import java.text.*;
class DateTime {
   public static void main(String[] args) {
      long timestamp = 1371271256;
      Date date = new Date(timestamp * 1000);
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy'-'MM'-'dd' 'HH':'mm':'ss");
      System.out.println("DATETIME = " + sdf.format(date));
   }
}
// 結果
// DATETIME = 2013-06-15 01:40:56
Javaのまとめ
  • 日付の処理はDateクラスを使う。
  • 現在時刻のDateTime型はSimpleDateFormatクラスによりTimeStamp型から特定のFormatに従って変換する。
  • 現在時刻のTimeStamp型はDateクラスのgetTimeメソッドでmillisecを取得し1000で割る。
  • 文字列型からDate型への変換はSimpleDateFormatクラスのparseメソッドを利用する。
  • long型のTimeStampをDate型に変換するにはDateインスタンスを生成する時の引数にlong型を指定する。

JavaScriptのお話

※結果の取得にはSpiderMonkeyを利用しています。

現在時刻のDateTime取得

new Date()したインスタンスからgetメソッドにより各種値を取得します。

var date_format = function(num) {
    return ( num < 10 ) ? '0' + num  : num;
};
var d = new Date();
print( "DATETIME = " + d.getFullYear() + '-' + date_format( d.getMonth() + 1 ) + '-' + 
       date_format( d.getDate() )+ ' ' + date_format( d.getHours() ) + ':' +
       date_format( d.getMinutes() ) + ':' + date_format( d.getSeconds() ) );
// 結果
// DATETIME = 2013-06-15 01:40:56
現在時刻のTimeStamp取得

new Date()した値を1000で割ってparseIntします。

print( "TIMESTAMP = " + parseInt( new Date() / 1000 ) );
// 結果
// TIMESTAMP = 1371228238
DateTime => TimeStamp変換

DATETIME型の"-"を"/"に置換して文字列をDate.parse関数に掛けて最終的に1000で割ります。

var datetime = "2013-06-15 01:40:56";
print( "TIMESTAMP = " + Date.parse( datetime.replace( /-/g, '/') ) / 1000 );
// 結果
// TIMESTAMP = 1371228056
TimeStamp => DateTime変換

TIMESTAMPを1000倍した値をnew Date()に渡し、インスタンスからgetメソッドで各種値を取得します。

var date_format = function(num) {
    return ( num < 10 ) ? '0' + num  : num;
};
var timestamp = 1371228056;
var d = new Date(timestamp*1000);
print( "DATETIME = " + d.getFullYear() + '-' + date_format( d.getMonth() + 1 ) + '-' + 
       date_format( d.getDate() )+ ' ' + date_format( d.getHours() ) + ':' +
       date_format( d.getMinutes() ) + ':' + date_format( d.getSeconds() ) );
// 結果
// DATETIME = 2013-06-15 01:40:56
JavaScriptのまとめ
  • JavaScriptのDateTime/TimeStampの処理にはDateオブジェクトを利用する。Dateオブジェクトの利用だけだが、値の導き方がやや複雑。
  • 現在時刻のDateTimeを取得するにはnew Date()により生成されたインスタンスのgetメソッドを使用する。
  • 現在時刻のTimeStampを取得するにはnew Date() / 1000した値をparseIntする。
  • DateTimeからTImeStampを取得するにはDateTimeの値の"/"を"-"に置換し、Date.parse関数に掛けて得られた値を1000で割る。
  • TimeStampからDateTimeを取得するにはTimeStampを1000倍した値をnew Date()に渡し、生成されたインスタンスからgetメソッドで各種値を取得する。

Perlのお話

現在時刻のDateTime取得

localtime関数で現在時刻のデータを取得し、strftimeでDateTime用のフォーマットに変換します。

#!/bin/env perl
use strict;
use warnings;
use POSIX qw(strftime);
my $date = strftime( "%Y-%m-%d %H:%M:%S" , localtime());
print "DATETIME = " . $date . "\n";
# 結果
# DATETIME = 2013-06-15 15:41:39
現在時刻のTimeStamp取得

TimeStampの取得は簡単でtimeを指定するだけです。

#!/bin/env perl
use strict;
use warnings;
print "TIMESTAMP = " . time . "\n";
# 結果
# TIMESTAMP = 1371278499
DateTime => TimeStamp変換

Perlには標準でstrptime関数が無いのでDateTime => TImeStampの変換に正規表現を使います。

#!/bin/env perl
#use DateTime;
#use POSIX qw(strftime);
use strict;
use warnings;
use Time::Local;
my($year, $month, $day, $hour, $minute, $second);
my $utime = "2013-06-15 15:41:39";
$utime =~ m{^\s*(\d{1,4})\W*0*(\d{1,2})\W*0*(\d{1,2})\W*0*
                 (\d{0,2})\W*0*(\d{0,2})\W*0*(\d{0,2})}x; 
$year = $1;  $month = $2;   $day = $3;
$hour = $4;  $minute = $5;  $second = $6;
$year = ($year<100 ? ($year<70 ? 2000+$year : 1900+$year) : $year);
print "TIMESTAMP = " . timelocal($second,$minute,$hour,$day,$month-1,$year) . "\n";
# 結果
# TIMESTAMP = 1371278499

strptimeを使ってもう少し奇麗に書きたい場合はDateTime::Format::Strptime、Time::PiecesをCPANからintallして使います。DateTimeモジュールのinstallは依存関係が多くとても大変なのでTime::Piecesを使うと良いと思います。

#!/bin/env perl
use strict;
use warnings;
use DateTime::Format::Strptime;
my $datetime = "2013-06-15 15:41:39";
my $strp = DateTime::Format::Strptime-> new( pattern => '%Y-%m-%d %H:%M:%S' );
print "TIMESTAMP = " . $strp->parse_datetime( $datetime )->epoch . "\n";
# 結果
# TIMESTAMP = 1371310899
#!/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $datetime = "2013-06-15 15:41:39";
my $strp = Time::Piece->strptime( $datetime, '%Y-%m-%d %H:%M:%S' );
print "TIMESTAMP = " . $strp->epoch . "\n";
# 結果
# TIMESTAMP = 1371310899
TimeStamp => DateTime変換

localtime関数で指定TimeStampの時刻を取得し、strftimeでDateTime用のフォーマットに変換します。

#!/bin/env perl
use strict;
use warnings;
use POSIX qw(strftime);
my $utime = 1371278499;
my $date = strftime( "%Y-%m-%d %H:%M:%S" , localtime($utime));
print "DATETIME = " . $date . "\n";
# 結果
# DATETIME = 2013-06-15 15:41:39
Perlのまとめ
  • 現在時刻のDateTimeを取得するにはPOSIXで定義されているstrftime()と標準で備わっているlocaltime()を利用する。
  • 現在時刻のTimeStampを取得するにはtimeを指定する。
  • DateTimeからTimeStampへの変換は3種類の方法がある。
    • 1.Perlにはstrptime関数が標準で備わっていないので、DateTime型を正規表現でparseしてyear,month,dayなどの各項目を切り出し、timelocal関数でTimeStampを取得する。
    • 2.DateTime::Format::Strptimeをinstallする。DateTime::Format::Strptimeをuseしてnewの際にDateTimeのFormatを指定する。DateTime::Format::Strptimeのparse_datetimeメソッドとepochプロパティを利用してTimeStampを取得する。※DateTimeはCPANからinstallするのが少し大変なのであまりお勧めはしない。
    • 3.Time::Pieceをinstallする。Time::PieceをuseしてstrptimeメソッドでDateTimeのFormatを指定する。strptimeメソッドで取得した値のepochプロパティを参照してTimeStampを取得する。
  • TimeStampからDateTimeを取得するにはPOSIXで定義されているstrftime()と標準で備わっているlocaltime()を利用する。

PHPのお話

現在時刻のDateTime取得

date/strftime関数で出力するDateTimeのFormatを指定します。

<?php
echo "DATETIME = " . date("Y-m-d H:i:s") . "\n";
echo "DATETIME = " . strftime("%Y-%m-%d %H:%M:%S") . "\n";
# 結果
# DATETIME = 2013-06-15 17:39:09
現在時刻のTimeStamp取得

time関数を使用します。

<?php
echo "TIMESTAMP = " . time() . "\n";
# 結果
# TIMESTAMP = 1371285686
DateTime => TimeStamp変換

strtotime関数を使用します。

<?php
$datetime = "2013-06-15 17:39:09";
echo "TIMESTAMP = " . strtotime( $datetime ) . "\n";
# 結果
# TIMESTAMP = 1371285549
TimeStamp => DateTime変換

date/strftime関数の第二引数にTimeStampを指定し、第一引数で出力するDateTimeのFormatを指定します。

<?php
$utime = 1371285549;
echo "DATETIME = " . date( "Y-m-d H:i:s", $utime ) . "\n";
echo "DATETIME = " . strftime("%Y-%m-%d %H:%M:%S", $utime ) . "\n";
# 結果
# DATETIME = 2013-06-15 17:39:09
PHPのまとめ
  • PHPのDateTIme/TimeStamp処理は標準関数でできるのでとても楽。
  • 現在時刻のDateTimeを取得するにはdate/strftime関数を使用する。
  • 現在時刻のTimeStampを取得するにはtime関数を使用する。
  • DateTimeからTimeStampを取得するにはstrtotime関数を使用する。
  • TimeStampからDateTimeを取得するにはdate/strftime関数を使用する。

Pythonのお話

現在時刻のDateTime取得

datetimeをimportしてstrftimeにてDateTimeのFormatを指定します。

#! /usr/bin/env python
# -*- coding:utf-8 -*-
from datetime import *
print "DATETIME = " + datetime.now().strftime( '%Y-%m-%d %H:%M:%S' )
# 結果
# DATETIME = 2013-06-15 17:56:56
現在時刻のTimeStamp取得

timeをimportしてint(time())でTimeStampを取得します。

#! /usr/bin/env python
# -*- coding:utf-8 -*-
from time import time
print "TIMESTAMP = " + str(int(time()))
# 結果
# TIMESTAMP = 1371286393
DateTime => TimeStamp変換

datetime/timeをimportしてdatetimeにてDateTime型のFormatを指定し、time.mktimeでTimeStampを取得します。

#! /usr/bin/env python
# -*- coding:utf-8 -*-
from datetime import *
import time
dtime = "2013-06-15 17:53:13"
print "TIMESTAMP = " + str( int( time.mktime( datetime.strptime( dtime, "%Y-%m-%d %H:%M:%S" ).timetuple() ) ) ) 
# 結果
# TIMESTAMP = 1371286393
TimeStamp => DateTime変換

datetimeをimportしてfromtimestamp関数でDateTimeに変換します。

# -*- coding:utf-8 -*-
from datetime import *
utime = 1371286393
print "DATETIME = " + str( datetime.fromtimestamp( utime ) ) 
# 結果
# DATETIME = 2013-06-15 17:53:13
Pythonのまとめ
  • Pythonはimportしたmoduleの組み合わせが複雑でDateTime/TimeStampの処理がやや複雑になる。
  • 現在時刻のDateTimeを取得するにはdatetimeをimportしてstrftimeメソッドでDateTimeのFormatを指定する。
  • 現在時刻のTimeStampを取得するにはtimeをimportしてtime関数のintを指定する。
  • DateTimeからTimeStampを取得するにはdatetime,timeをimportして指定したDateTimeのFormatをparseしてmktimeにてTimeStampに変換しintを指定する。
  • TimeStampからDateTimeを取得するにはdatetimeをimportしてfromtimestamp関数で変換する。

Rubyのお話

※2013/07/20修正:774さんから頂いたTime.parse()意外はrequire "time"が不要でした。

現在時刻のDateTime取得

timeをrequireしてstrftimeメソッドでDateTimeのFormatを指定します。

#!/bin/env ruby
# -*- encoding: utf-8 -*-
# require "time"
puts "DATETIME = " + ( Time.now.strftime "%Y-%m-%d %H:%M:%S" )
# 結果
# DATETIME = 2013-06-15 16:59:11
現在時刻のTimeStamp取得

timeをrequireしてnow.to_iメソッドでTimeStampを取得します。

#!/bin/env ruby
# -*- encoding: utf-8 -*-
# require "time"
puts "TIMESTAMP = " + Time.now.to_i.to_s
# 結果
# TIMESTAMP = 1371283340
DateTime => TimeStamp変換

timeをrequireしてparseメソッドで指定したDateTime型をto_iメソッドでTimeStamp型に変換します。

#!/bin/env ruby
# -*- encoding: utf-8 -*-
require "time"
datetime = "2013-06-15 16:59:11"
puts "TIMESTAMP = " + Time.parse(datetime).to_i.to_s
# 結果
# TIMESTAMP = 1371283151
TimeStamp => DateTime変換

timeをrequireしてatメソッドにTimeStamp型を渡し、strftimeで指定したDateTime型に変換します。

#!/bin/env ruby
# -*- encoding: utf-8 -*-
# require "time"
utime = 1371283340
puts "DATETIME = " + ( Time.at(utime).strftime "%Y-%m-%d %H:%M:%S" )
# 結果
# DATETIME = 2013-06-15 17:02:20
Rubyのまとめ
  • RubyはtimeのrequireだけでDateTime/TimeStampの処理が簡単に出来る。
  • 現在時刻のDateTimeはTimeのstrftimeで指定したFormatで取得する。
  • 現在時刻のTimeStampはTimeのto_iメソッドで取得する。
  • DateTimeからTimeStampを取得するにはTimeのparseメソッドに指定したDateTIme型をto_iメソッドでTimeStamp型に変換する。
  • TimeStampからDateTimeを取得するにはTimeのatメソッドに指定したTimeStamp型をstrftimeメソッドで指定したFormatのDateTimeに変換する。

プログラミング言語 Ruby

プログラミング言語 Ruby