各言語でスニペットのまとめエントリ第2段は日時計算です。日時データは表現方法が様々なため、必要なデータ形式にデータを変換するのが覚えれなくてイライラしますね。そこで以下の3つの表現を相互に変換するスニペットを書きました。
- 日時オブジェクト
- フォーマットされた文字列
- unixタイムスタンプ(1970-01-01 00:00:00 UTC からの経過秒数)
python
pythonはdatetimeを使います。また日付計算はtimedeltaでオフセットを表現します。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
from datetime import datetime, timedelta
# obj, text, timestamp(time)の相互変換
format = '%Y-%m-%d %H:%M:%S'
orig = datetime(2009, 8, 10, 14, 53, 30)
text1 = orig.isoformat(' ') # obj => txt
date1 = datetime.strptime(text1, format) # txt => obj
time1 = time.mktime(date1.timetuple()) # obj => time
date2 = datetime.fromtimestamp(time1) # time => obj
time2 = time.mktime(time.strptime(text1, format)) # txt => time
text2 = datetime.fromtimestamp(time2).isoformat(' ') # time => txt (obj経由)
print orig
print date2
print text2
print time2
# 現在時刻
now = datetime.now()
print now
# 日時計算
one_hour_later = now + timedelta(hours = 1) # 1時間後
two_days_later = now + timedelta(days = 2) # 2日後
three_weeks_later = now + timedelta(weeks = 3) # 3週間後
print one_hour_later
print two_days_later
print three_weeks_later
perl
perlはDateTimeオブジェクト。DateTimeオブジェクトはかなり強力ですが、文字列フォーマットを扱えないのが残念です。ここでは日付文字列を扱うのにDateTime::Format::Strptimeを使ってみました。
#!/usr/bin/perl
use strict;
use warnings;
use Perl6::Say;
use DateTime;
use DateTime::Format::Strptime;
# obj, text, timestampの相互変換
my $format = '%Y-%m-%d %H:%M:%S';
my $parser = new DateTime::Format::Strptime(pattern => $format);
my $orig = DateTime->new(year => 2009, month => 8, day => 10,
hour => 14, minute => 53, second => 30);
my $text1 = $orig->strftime($format); # obj => txt
my $date1 = $parser->parse_datetime($text1); # txt => obj
my $time1 = $date1->epoch; # obj => time
my $date2 = DateTime->from_epoch(epoch => $time1); # time => obj
my $time2 = $parser->parse_datetime($text1)->epoch; # txt => time (obj経由)
my $text2 = DateTime->from_epoch(epoch => $time2)->strftime($format); # time => txt (obj経由)
say $orig;
say $date2;
say $time2;
say $text2;
# 現在時刻
my $now = DateTime->now;
say $now;
# 日時計算
my $one_hour_later = $now->add(hours => 1);
my $two_days_later = $now->add(days => 2);
my $three_weeks_later = $now->add(weeks => 3);
say $one_hour_later;
say $two_days_later;
say $three_weeks_later;
php
phpでの処理の特徴は、他の言語が中心に日付オブジェクトがあるのに対して、phpでは中心に日付文字列がある事ですね。文字列に対する各種処理が豊富にそろっています。あと関係ないですが、改行付きのprintがあればもっとすっきりするのにと思います。
#!/usr/bin/php
< ?php
# obj, text, timestamp(time)の相互変換
$format = 'Y-m-d H:i:s';
$orig = new DateTime('2009-08-10 14:53:30');
$text1 = $orig->format($format); # obj => txt
$date1 = new DateTime($text1); # txt => obj
$time1 = strtotime($date1->format($format)); # obj => time (txt経由)
$date2 = new DateTime(date($format, $time1)); # time => obj (txt経由)
list($y, $m, $d, $h, $mi, $s) = sscanf($text1, "%d-%d-%d %d:%d:%d");
$time2 = mktime($h, $mi, $s, $m, $d, $y); # text => time
$text2 = date($format, $time2); # time => text
echo $orig->format($format) . "\n";
echo $date2->format($format) . "\n";
echo $text2, "\n";
echo $time2, "\n";
# 現在時刻
$now = new DateTime();
echo $now->format($format) . "\n";
# 日時計算
$one_hour_later = clone $now;
$one_hour_later->modify('+1 hour'); # '+1 hour +2 day ...'
$two_days_later = clone $now;
$two_days_later->modify('+2 days');
$three_weeks_later = clone $now;
$three_weeks_later->modify('+3 weeks');
echo $one_hour_later->format($format) . "\n";
echo $two_days_later->format($format) . "\n";
echo $three_weeks_later->format($format) . "\n";
?>
as3
as3はDateオブジェクトを使用します。コンストラクタが強力でオブジェクトだろうが、文字列だろうが、タイムスタンプだろうが何でも取ります。一方で日付の計算をミリ秒単位に変換して行わないと行けないのが大変です。
package {
import flash.display.*;
public class DatetimeTest extends Sprite {
function DatetimeTest() {
// obj, text, timestamp(time)の相互変換
var orig:Date = new Date(2009, 8, 10, 14, 53, 30);
var text1:String = orig.toString(); // obj => txt
var date1:Date = new Date(text1); // txt => obj
var time1:Number = date1.getTime(); // obj => time
var date2:Date = new Date(time1); // time => obj
var time2:Number = (new Date(text1)).getTime(); // txt => time (obj経由)
var text2:String = (new Date(time2)).toString(); // time => txt (obj経由)
log(orig);
log(date2);
log(text2);
log(time2);
// 現在時刻
var now:Date = new Date();
log(now);
// 日時計算
var one_hour_later:Date = new Date(now);
one_hour_later.setTime(one_hour_later.getTime() + 60*60*1000); // 1時間後
var two_days_later:Date = new Date(now);
two_days_later.setTime(two_days_later.getTime() + 2*24*60*60*1000); // 2日後
var three_weeks_later:Date = new Date(now);
three_weeks_later.setTime(three_weeks_later.getTime() + 3*7*24*60*60*1000); // 3週間後
log(one_hour_later);
log(two_days_later);
log(three_weeks_later);
}
}
}
javascript
as3とjavascriptがこんなに似ているとは思いませんでした。
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
datetime test
まとめ
最近pythonを使い始めて肩入れしている気はしますが,pythonが一番綺麗です。timedeltaオブジェクトがあるのが素晴しいですね。どの言語でも、変換の中心になる形式があるので、その形式を押さえる事が重要そうですね。各言語とも特に不自由はありませんが、as3とjavascriptは日時計算が若干やりにくいので、やはりクライアントサイドは基本的にビューアとして考えるのがいいのかなと思いました。飛躍しましたか。そうですか。あとphpは一々惜しい印象。幾つかシンタックスシュガーを用意したら結構使い易くなるんじゃないかと思います。
おまけのMySQL
mysql> SELECT NOW();
+---------------------+
| 2009-08-06 12:08:55 |
+---------------------+
mysql> SELECT UNIX_TIMESTAMP(NOW());
+-----------------------+
| 1249528147 |
+-----------------------+
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(NOW()));
+--------------------------------------+
| 2009-08-06 12:09:31 |
+--------------------------------------+
覚えにくいんですが、UNIX_TIMESTAMPとFROM_UNIXTIMEを使えると結構便利だと思います。
1 thought on “pythonとperlとphpとas3とjavascriptで日時計算”