日付処理
日付型・日付文字列型・UnixTime整数型 相互変換
日付のイテレート
データが年月日別に管理され、その中から期間を指定して分析を行いたいことはよくある。
期間を文字列で指定すると、1日ずつ順番に日付を返すジェネレータがあると便利。
主な使い方
(例)
入力: 20150101-20150331,20150701,20150801
出力: 20150101, 20150102, 20150103, ..., 20150331, 20150701, 20150801
Python
from datetime import datetime
from dateutil.relativedelta import relativedelta
# 日単位でのイテレート ------------------------------------
# 補助関数
def _generate_between_date(start_date_str, stop_date_str):
start_date = datetime.strptime(start_date_str, '%Y%m%d')
stop_date = datetime.strptime(stop_date_str, '%Y%m%d')
while start_date <= stop_date:
yield start_date.strftime('%Y%m%d')
start_date += relativedelta(days=1)
# こちらを使う
def date_sequence_generator(dates_str):
for date_str in dates_str.split(','):
if '-' in date_str:
for date in _generate_between_date(*date_str.split('-')):
yield date
else:
yield date_str
# 月単位でのイテレート -----------------------------------
def _generate_between_month(start_month_str, stop_month_str):
start_month = datetime.strptime(start_month_str, '%Y%m')
stop_month = datetime.strptime(stop_month_str, '%Y%m')
while start_month <= stop_month:
yield start_month.strftime('%Y%m')
start_month += relativedelta(months=1)
def month_sequence_generator(months_str):
for month_str in months_str.split(','):
if '-' in month_str:
for month in _generate_between_month(*month_str.split('-')):
yield month
else:
yield month_str
PHP
use DateTime;
class DateIterator
{
function iterateDate($target_dates)
{
$comma_explodeds = explode(',', $target_dates);
foreach ($comma_explodeds as $cma) {
$hyphen_explodeds = explode('-', $cma);
if (count($hyphen_explodeds) === 1) {
yield $cma;
} elseif (count($hyphen_explodeds) === 2) {
$d = DateTime::createFromFormat(
'Ymd', $hyphen_explodeds[0]);
$t = DateTime::createFromFormat(
'Ymd', $hyphen_explodeds[1]);
if ($d === false || $t === false) {
throw new \UnexpectedValueException(
'iterateDate parse date');
}
while ($d <= $t) {
yield $d->format('Ymd');
$d->modify('+1 day');
}
} else {
throw new \UnexpectedValueException(
'iterateDate hyphen');
}
}
}
}
Kotlin
KotlinではGeneratorの機能がまだexperimentalなので、Listを返すようにする。
また、Java8より導入されたLocalDateTimeを利用する。
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.format.ResolverStyle
fun String.iterateDate(): List<String> {
val formatter = DateTimeFormatter.ofPattern("uuuuMMdd").withResolverStyle(ResolverStyle.STRICT)
val dateList = mutableListOf<String>()
this.split(',').forEach {
val hyphenSplit = it.split('-')
when (hyphenSplit.size) {
1 -> {
// パースできるかだけ確認
LocalDate.parse(hyphenSplit[0], formatter)
dateList += hyphenSplit[0]
}
2 -> {
var curDate = LocalDate.parse(hyphenSplit[0], formatter)
val tgtDate = LocalDate.parse(hyphenSplit[1], formatter)
while (curDate <= tgtDate) {
dateList += curDate.format(formatter)
curDate = curDate.plusDays(1)
}
}
else -> {
throw IllegalArgumentException("Can't iterate date: %s".format(it))
}
}
}
return dateList
}