はじめに
機械学習の勉強を始めたVBAユーザです。
備忘録としてPython・R・VBAの文法を比較しながらまとめています。
今回は、日時(日付と時刻)の操作についてまとめます。
目次
日時操作
日時を表すデータ型
日付
Python
Pythonでは、標準ライブラリにあるdatetime
モジュールを使います。
https://docs.python.org/ja/3/tutorial/stdlib.html#dates-and-times
https://docs.python.org/ja/3/library/datetime.html
https://note.nkmk.me/date-and-time/
日付はdatetime
のdate
オブジェクトです。
import datetime
d = datetime.date(2004, 3, 21)
print(d)
# 2004-03-21
print(type(d))
# <class 'datetime.date'>
R
Rでは、日時型処理パッケージのlubridateを使うと便利です。
https://lubridate.tidyverse.org/
https://rawgit.com/rstudio/cheatsheets/main/lubridate.pdf
Rでは日付はDate型です。Date型は、1970年1月1日を基準とする日数(1970年1月1日が0日目、2000年1月23日は10979日目)の数値に"Date"のclass属性を与えて日付型としています。中身は数値("double")なので、class属性をはがすと単なる数値(1970年1月1日を基準とする日数)に戻ります。
参考:Rの属性についてはこちらの記事を参照。
library(lubridate)
d <- ymd("2004/3/21")
d <- as_date("2004/3/21")
d <- as.Date("2004/3/21", "%Y/%m/%d")
d
# [1] "2000-01-23"
class(d)
# [1] "Date"
mode(d)
# [1] "numeric"
typeof(d)
# [1] "double"
str(d)
# Date[1:1], format: "2000-01-23"
attributes(d)
# $class
# [1] "Date"
#
as.numeric(d)
# [1] 12498
unclass(d)
# [1] 12498
attributes(d) <- NULL
d
# [1] 12498
d <- 12498
as_date(d)
# [1] "2004-03-21"
d <- 12498
attributes(d) <- list(class="Date")
d
# [1] "2004-03-21"
d <- 12498
attr(d, "class") <- "Date"
d
# [1] "2004-03-21"
as_date(d)
# [1] "2004-03-21"
VBA
VBAでは日時はDate型です。VBAのDate型は、1900年1月1日を基準とする日数(1900年1月1日が1日目、2000年1月23日は36548日目)の数値(シリアル値)で表します。整数部分で日付、小数部分で時刻を表します。
#
で囲むとDate型になります。
Dim d As Variant
d = #3/21/2004#
Debug.Print d
' 2004/03/21
Debug.Print TypeName(d)
' Date
d = CDate("2004/3/21")
Debug.Print d
' 2004/03/21
Debug.Print TypeName(d)
' Date
Debug.Print CLng(d)
' 38067
Debug.Print CDate(38067)
' 2004/03/21
時刻
Python
Pythonでは時刻はdatetime
のtime
オブジェクトです。
t = datetime.time(12, 34, 56)
print(t)
# 12:34:56
print(type(t))
# <class 'datetime.time'>
R
Rでは時刻は0:00:00を基準とする秒数(0:00:00が0秒目、12:34:56は45296秒目)の数値にclass属性を与えて時刻型としています。中身は数値("double")なので、class属性をはがすと単なる数値(0:00:00を基準とする秒数)に戻ります。
t <- hms::as_hms("12:34:56")
t
# 12:34:56
class(t)
# [1] "hms" "difftime"
mode(t)
# [1] "numeric"
typeof(t)
# [1] "double"
str(t)
# 'hms' num 12:34:56
# - attr(*, "units")= chr "secs"
attributes(t)
# $units
# [1] "secs"
#
# $class
# [1] "hms" "difftime"
#
as.numeric(t)
# [1] 45296
unclass(t)
# [1] 45296
# attr(,"units")
# [1] "secs"
attributes(t) <- NULL
t
# [1] 45296
12*60*60+34*60+56
# [1] 45296
t <- 45296
attributes(t) <- list(class=c("hms", "difftime"))
t
# 12:34:56
t <- 45296
attr(t, "class") <- c("hms", "difftime")
t
# 12:34:56
hms::as_hms(t)
# 12:34:56
VBA
VBAでは日時はDate型です。VBAのDate型は、1900年1月1日を基準とする日数(1900年1月1日が1日目、2000年1月23日は36548日目)の数値(シリアル値)で表します。小数部分が時刻を表します。
#
で囲むとDate型になります。
Dim t As Variant
t = #12:34:56 PM#
Debug.Print t
' 12:34:56
Debug.Print TypeName(t)
' Date
t = CDate("12:34:56")
Debug.Print t
' 12:34:56
Debug.Print TypeName(t)
' Date
Debug.Print CDbl(t)
' 0.524259259259259
Debug.Print 12 / 24 + 34 / 24 / 60 + 56 / 24 / 60 / 60
' 0.524259259259259
Debug.Print CDate(0.524259259259259)
' 12:34:56
日時
Python
Pythonでは日時はdatetime
のdatetime
オブジェクトです。
dt = datetime.datetime(2004, 3, 21, 12, 34, 56)
print(dt)
# 2004-03-21 12:34:56
print(type(dt))
# <class 'datetime.datetime'>
R
Rでは日時は1970年1月1日0:00:00を基準とする秒数(1970年1月1日0:00:00が0秒目、2000年1月23日12:34:56は948630896秒目)の数値にclass属性を与えて時刻型としています。中身は数値("double")なので、class属性をはがすと単なる数値(1970年1月1日0:00:00を基準とする秒数)に戻ります。
dt <- ymd_hms("2004/3/21 12:34:56")
dt
# [1] "2004-03-21 12:34:56 UTC"
class(dt)
# [1] "POSIXct" "POSIXt"
mode(dt)
# [1] "numeric"
typeof(dt)
# [1] "double"
str(dt)
# POSIXct[1:1], format: "2004-03-21 12:34:56"
attributes(dt)
# $class
# [1] "POSIXct" "POSIXt"
#
# $tzone
# [1] "UTC"
#
as.numeric(dt)
# [1] 1079872496
unclass(dt)
# [1] 1079872496
# attr(,"tzone")
# [1] "UTC"
attributes(dt) <- NULL
dt
# [1] 1079872496
12498*24*60*60 + 45296
# [1] 1079872496
dt <- 1079872496
attributes(dt) <- list(class=c("POSIXct", "POSIXt"))
dt
# [1] "2004-03-21 21:34:56 JST"
dt <- 1079872496
attr(dt, "class") <- c("POSIXct", "POSIXt")
dt
# [1] "2004-03-21 21:34:56 JST"
as_datetime(dt)
# [1] "2004-03-21 21:34:56 JST"
VBA
VBAでは日時はDate型です。VBAのDate型は、1900年1月1日を基準とする日数(1900年1月1日が1日目、2000年1月23日は36548日目)の数値(シリアル値)で表します。整数部分で日付、小数部分で時刻を表します。
#
で囲むとDate型になります。
Dim dt As Variant
dt = #3/21/2004 12:34:56 PM#
Debug.Print dt
' 2004/03/21 12:34:56
Debug.Print TypeName(dt)
' Date
dt = CDate("2004/3/21 12:34:56")
Debug.Print dt
' 2004/03/21 12:34:56
Debug.Print TypeName(dt)
' Date
Debug.Print CDbl(dt)
' 38067.5242592593
Debug.Print CDate(38067.5242592593)
' 2004/03/21 12:34:56
注意)なお、エクセルでは、歴史的な経緯(Lotusとの互換性)から、本来は閏年ではない1900年を閏年として扱っているため、VBAのシリアル値と1日ずれます(補足参照)。
現在の日時
Python
print(datetime.date.today())
# 2022-04-03
print(datetime.datetime.now().time())
# 01:23:45.678901
print(datetime.datetime.now())
# 2022-04-03 01:23:45.678901
# timeモジュール
import time
print(time.time())
# 1648464319.4195054
print(type(time.time()))
# <class 'float'>
# 現在のUNIX時間(エポック秒)をfloat型で取得
# UNIX時間(エポック秒)は協定世界時 (UTC) での1970年1月1日午前0時0分0秒からの経過秒数
参考: https://note.nkmk.me/python-unix-time-datetime/
R
now()
# [1] "2022-04-03 01:23:45 UTC"
today()
# [1] "2022-04-03"
VBA
Debug.Print Now
' 2022/04/03 1:23:45
Debug.Print Date
' 2022/04/03
Debug.Print Time
' 2022/04/03 1:23:45
日時型の変換
日付型⇒シリアル値
Python
dt = datetime.datetime(2004, 3, 21, 12, 34, 56)
print(dt)
# 2004-03-21 12:34:56
print(type(dt))
# <class 'datetime.datetime'>
print(dt.timestamp())
# 1079872496.0
R
d <- ymd("2004/3/21")
d <- as_date("2004/3/21")
d <- as.Date("2004/3/21", "%Y/%m/%d")
d
# [1] "2000-01-23"
class(d)
# [1] "Date"
mode(d)
# [1] "numeric"
typeof(d)
# [1] "double"
str(d)
# Date[1:1], format: "2000-01-23"
attributes(d)
# $class
# [1] "Date"
#
as.numeric(d)
# [1] 12498
unclass(d)
# [1] 12498
attributes(d) <- NULL
d
# [1] 12498
t <- hms::as_hms("12:34:56")
t
# 12:34:56
class(t)
# [1] "hms" "difftime"
mode(t)
# [1] "numeric"
typeof(t)
# [1] "double"
str(t)
# 'hms' num 12:34:56
# - attr(*, "units")= chr "secs"
attributes(t)
# $units
# [1] "secs"
#
# $class
# [1] "hms" "difftime"
#
as.numeric(t)
# [1] 45296
unclass(t)
# [1] 45296
# attr(,"units")
# [1] "secs"
attributes(t) <- NULL
t
# [1] 45296
12*60*60+34*60+56
# [1] 45296
dt <- ymd_hms("2004/3/21 12:34:56")
dt
# [1] "2004-03-21 12:34:56 UTC"
class(dt)
# [1] "POSIXct" "POSIXt"
mode(dt)
# [1] "numeric"
typeof(dt)
# [1] "double"
str(dt)
# POSIXct[1:1], format: "2004-03-21 12:34:56"
attributes(dt)
# $class
# [1] "POSIXct" "POSIXt"
#
# $tzone
# [1] "UTC"
#
as.numeric(dt)
# [1] 1079872496
unclass(dt)
# [1] 1079872496
# attr(,"tzone")
# [1] "UTC"
attributes(dt) <- NULL
dt
# [1] 1079872496
12498*24*60*60 + 45296
# [1] 1079872496
VBA
Dim d As Variant
d = #1/23/2000#
Debug.Print d, TypeName(d)
' 2000/01/23 Date
d = CDate("2000/1/23")
Debug.Print d, TypeName(d)
' 2000/01/23 Date
Debug.Print CLng(d)
' 36548
Dim t As Variant
t = #12:34:56 PM#
Debug.Print t, TypeName(t)
' 12:34:56 Date
t = CDate("12:34:56")
Debug.Print t, TypeName(t)
' 12:34:56 Date
Debug.Print CDbl(t)
' 0.524259259259259
Debug.Print 12 / 24 + 34 / 24 / 60 + 56 / 24 / 60 / 60
' 0.524259259259259
Dim dt As Variant
dt = #1/23/2000 12:34:56 PM#
Debug.Print dt, TypeName(dt)
' 2000/01/23 12:34:56 Date
dt = CDate("2000/1/23 12:34:56")
Debug.Print dt, TypeName(dt)
' 2000/01/23 12:34:56 Date
Debug.Print CDbl(dt)
' 36548.5242592593
シリアル値⇒日時型
Python
print(datetime.datetime.fromtimestamp(1079872496.0))
# 2004-03-21 12:34:56
R
d <- 12498
as_date(d)
# [1] "2004-03-21"
d <- 12498
attributes(d) <- list(class="Date")
d
# [1] "2004-03-21"
d <- 12498
attr(d, "class") <- "Date"
d
# [1] "2004-03-21"
as_date(d)
# [1] "2004-03-21"
t <- 45296
attributes(t) <- list(class=c("hms", "difftime"))
t
# 12:34:56
t <- 45296
attr(t, "class") <- c("hms", "difftime")
t
# 12:34:56
hms::as_hms(t)
# 12:34:56
dt <- 1079872496
attributes(dt) <- list(class=c("POSIXct", "POSIXt"))
dt
# [1] "2004-03-21 21:34:56 JST"
dt <- 1079872496
attr(dt, "class") <- c("POSIXct", "POSIXt")
dt
# [1] "2004-03-21 21:34:56 JST"
as_datetime(dt)
# [1] "2004-03-21 21:34:56 JST"
VBA
Debug.Print CDate(36548)
' 2000/01/23
Debug.Print CDate(0.524259259259259)
' 12:34:56
Debug.Print CDate(36548.5242592593)
' 2000/01/23 12:34:56
文字列型⇒日時型
Python
print(datetime.datetime.strptime('2004/3/21', '%Y/%m/%d').date())
# 2004-03-21
print(datetime.datetime.strptime('12:34:56', '%H:%M:%S').time())
# 12:34:56
print(datetime.datetime.strptime('2004/3/21 12:34:56', '%Y/%m/%d %H:%M:%S'))
# 2004-03-21 12:34:56
print(datetime.datetime.strptime('2004年3月21日 12時34分56秒',
'%Y年%m月%d日 %H時%M分%S秒'))
# 2004-03-21 12:34:56
# ISOフォーマット(ISO 8601形式)の文字列
print(datetime.date.fromisoformat('2004-03-21'))
# 2004-03-21
print(datetime.time.fromisoformat('12:34:56'))
# 12:34:56
print(datetime.datetime.fromisoformat('2004-03-21T12:34:56'))
# 2004-03-21 12:34:56
書式化コードについて
https://docs.python.org/ja/3/library/time.html#time.strftime
https://docs.python.org/ja/3/library/datetime.html#strftime-strptime-behavior
https://note.nkmk.me/python-datetime-usage/
主な書式化コード
%d : 0埋めした10進数で表記した月中の日にち
%m : 0埋めした10進数で表記した月
%y : 0埋めした10進数で表記した西暦の下2桁
%Y : 0埋めした10進数で表記した西暦4桁
%H : 0埋めした10進数で表記した時 (24時間表記)
%I : 0埋めした10進数で表記した時 (12時間表記)
%M : 0埋めした10進数で表記した分
%S : 0埋めした10進数で表記した秒
%f : 0埋めした10進数で表記したマイクロ秒(6桁)
%A : ロケールの曜日名
%a : ロケールの曜日名(短縮形)
%B : ロケールの月名
%b : ロケールの月名(短縮形)
%j : 0埋めした10進数で表記した年中の日にち(正月が'001')
%U : 0埋めした10進数で表記した年中の週番号(週の始まりは日曜日)
%W : 0埋めした10進数で表記した年中の週番号(週の始まりは月曜日)
R
as_date("2004/3/21")
# [1] "2004-03-21"
as.Date("2004/3/21", "%Y/%m/%d") # baseパッケージ
# [1] "2004-03-21"
ymd("2004/3/21")
ymd("2004/03/21")
ymd("2004-03-21")
ymd("2004 3 21")
ymd("2004,3,21")
ymd("20040321")
ymd("2004年3月21日")
# [1] "2004-03-21"
ydm("2004-21-03")
# [1] "2004-03-21"
mdy("03-21-2004")
# [1] "2004-03-21"
mdy("3, 21, 2004")
# [1] "2004-03-21"
dmy("21-03-2004")
# [1] "2004-03-21"
dmy("21 Mar 2004")
# [1] "2004-03-21"
dmy("21th of March 2004")
# [1] "2004-03-21"
ymd_hms("2004-03-21 12:34:56")
# [1] "2004-03-21 12:34:56 UTC"
ymd_hm("2004-03-21 12:34")
# [1] "2004-03-21 12:34:00 UTC"
ymd_hm("2004-03-21 12")
# [1] "2020-04-03 21:12:00 UTC"
ydm_hms("2004-21-03 12:34:56")
# [1] "2004-03-21 12:34:56 UTC"
mdy_hms("03-21-2004 12:34:56")
# [1] "2004-03-21 12:34:56 UTC"
dmy_hms("21 Mar 2004 12:34:56")
# [1] "2004-03-21 12:34:56 UTC"
hms::as_hms("12:34:56")
# 12:34:56
hms("12:34:56")
hms("12時34分56秒")
# [1] "12H 34M 56S"
as_datetime("2004/3/21 12:34:56")
as_datetime("2004年3月21日12時34分56秒")
# [1] "2004-03-21 12:34:56 UTC"
VBA
Debug.Print IsDate("2004/3/21 12:34:56")
' True
Debug.Print CDate("2004/3/21 12:34:56")
' 2004/03/21 12:34:56
Debug.Print DateValue("2004/3/21 12:34:56")
' 2004/03/28
Debug.Print TimeValue("2004/3/21 12:34:56")
' 12:34:56
Debug.Print IsDate("2004年3月28日 12時34分56秒")
' True
Debug.Print DateValue("2004年3月28日 12時34分56秒")
' 2004/03/28
Debug.Print TimeValue("2004年3月28日 12時34分56秒")
' 12:34:56
Debug.Print IsDate("平成16年3月28日 12時34分56秒")
' True
Debug.Print DateValue("平成16年3月28日 12時34分56秒")
' 2004/03/28
Debug.Print TimeValue("平成16年3月28日 12時34分56秒")
' 12:34:56
Dim d As Date
d = "2004/3/21 12:34:56" ' 日付型に変換して代入
Debug.Print d
' 2004/03/21 12:34:56
d = "2004/3/21"
Debug.Print d
' 2004/03/21
d = "12:34:56"
Debug.Print d
' 12:34:56
日時型⇒文字列型
Python
d = datetime.date(2004, 3, 21)
print(d.strftime('%Y/%m/%d'))
print('{0:%Y/%m/%d}'.format(d))
# 2004/03/21
t = datetime.time(12, 34, 56)
print(t.strftime('%H:%M:%S'))
print('{0:%H:%M:%S}'.format(t))
# 12:34:56
dt = datetime.datetime(2004, 3, 21, 12, 34, 56)
print(dt.strftime('%Y/%m/%d %H:%M:%S'))
print('{0:%Y/%m/%d %H:%M:%S}'.format(dt))
# 2004/03/21 12:34:56
print(dt.strftime('%Y年%m月%d日 %H時%M分%S秒'))
# 2004年03月21日 12時34分56秒
# ISOフォーマット(ISO 8601形式)の文字列
print(d.isoformat())
# 2004-03-21
print(t.isoformat())
# 12:34:56
print(dt.isoformat())
# 2004-03-21T12:34:56
print(dt.isoformat().replace('-', '/').replace('T', ' ')) # replace()で置換
# 2004/03/21 12:34:56
# UNIX時刻を文字列表現に変換
import time
print(time.ctime(1079872496.0))
# Sun Mar 21 12:34:56 2004
R
strftime(d, format="%Y/%m/%d") # strftimeはbaseの関数
# [1] "2004/03/21"
strftime(d, format="%Y-%m-%d")
# [1] "2004-03-21"
strftime(d, format="%Y%m%d")
# [1] "20040321"
strftime(t, format="%H:%M:%S")
# [1] "12:34:56"
strftime(t, format="%H時%M分%S秒")
# [1] "12時34分56秒"
strftime(dt, format="%Y/%m/%d %H:%M:%S")
# [1] "2004/03/21 21:34:56"
strftime(dt, format="%Y-%m-%d %H:%M:%S")
# [1] "2004-03-21 21:34:56"
strftime(dt, format="%Y年%m月%d日 %H時%M分%S秒")
# [1] "2004年03月21日 21時34分56秒"
VBA
Dim dt As Date
dt = DateSerial(2004, 3, 21) + TimeSerial(12, 34, 56)
Debug.Print dt
' 2004/03/21 12:34:56
Debug.Print Format(dt, "yyyy/mm/dd hh:nn:ss")
' 2004/03/21 12:34:56
Debug.Print Format(dt, "yyyy/mm/dd hh:nn:ss am/pm")
' 2004/03/21 12:34:56 pm
Debug.Print Format(dt, "yyyy/mm/dd hh:nn:ss")
' 2004/03/21 12:34:56
Debug.Print Format(dt, "yyyy/mm/dd hh:nn:ss am/pm")
' 2004/03/21 12:34:56 pm
Debug.Print Format(dt, "ggge/mm/dd hh:nn:ss aaaa")
' 平成16/03/21 12:34:56 日曜日
Debug.Print Format(dt, "ge/mm/dd hh:nn:ss am/pm aaa")
' H16/03/21 12:34:56 pm 日
Debug.Print Format(dt, "ggge/mm/dd hh:nn:ss dddd")
' 平成16/03/21 12:34:56 Sunday
Debug.Print Format(dt, "ge/mm/dd hh:nn:ss am/pm ddd")
' H16/03/21 12:34:56 pm Sun
日時の要素⇒日時型
日時の要素(年・月・日・時・分・秒の数値)から日時型を作ります。
Python
d = datetime.date(2004, 3, 21)
print(d)
# 2004-03-21
t = datetime.time(12, 34, 56)
print(t)
# 12:34:56
t = datetime.time(12, 34, 56, 700000)
print(t)
# 12:34:56.700000
dt = datetime.datetime(2004, 3, 21, 12, 34, 56)
print(dt)
# 2004-03-21 12:34:56
dt = datetime.datetime(2004, 3, 21, 12, 34, 56, 700000)
print(dt)
# 2004-03-21 12:34:56.700000
R
make_datetime(2004,3,21,12,34,56)
# [1] "2004-03-21 12:34:56 UTC"
make_date(2004,3,21)
# [1] "2004-03-21"
VBA
Debug.Print DateSerial(2004, 3, 21)
' 2004/03/21
Debug.Print TimeSerial(12, 34, 56)
' 12:34:56
Debug.Print DateSerial(2004, 3, 21) + TimeSerial(12, 34, 56)
' 2004/03/21 12:34:56
日時型⇒日時の要素
日時型から日時の要素(年・月・日・時・分・秒の数値)を取り出します。
Python
dt = datetime.datetime(2004, 3, 21, 12, 34, 56)
print(dt)
# 2004-03-21 12:34:56
print(dt.year)
# 2004
print(dt.month)
# 3
print(dt.day)
# 21
print(dt.hour)
# 12
print(dt.minute)
# 34
print(dt.second)
# 56
print(dt.microsecond) # マイクロ秒
# 0
print(dt.timestamp()) # UNIX時間
# 1079872496.0
R
dt <- ymd_hms("2004/3/21 12:34:56")
dt
# [1] "2004-03-21 12:34:56 UTC"
year(dt)
# [1] 2004
month(dt)
# [1] 3
day(dt)
# [1] 21
hour(dt)
# [1] 12
minute(dt)
# [1] 34
second(dt)
# [1] 56
VBA
Dim dt As Date
dt = CDate("2004/3/21 12:34:56")
Debug.Print dt
' 2004/03/21 12:34:56
Debug.Print Year(dt)
' 2004
Debug.Print Month(dt)
' 3
Debug.Print Day(dt)
' 21
Debug.Print Hour(dt)
' 12
Debug.Print Minute(dt)
' 34
Debug.Print Second(dt)
' 56
日時型⇒その他の情報
Python
print(dt.weekday())
# 6
# 返り値は月曜0から日曜6までの整数値
import calendar
print(calendar.weekday(dt.year, dt.month, dt.day))
# 6
# 返り値は月曜0から日曜6までの整数値
print(dt.strftime('%A'))
# Sunday
print(dt.strftime('%a'))
# Sun
print(dt.strftime('%B'))
# March
print(dt.strftime('%b'))
# Mar
print(dt.strftime('%j'))
# 081
print(dt.strftime('%U'))
# 12
print(dt.strftime('%W'))
# 11
R
date(dt)
# [1] "2004-03-21"
as_date(dt)
# [1] "2004-03-21"
month(dt, label = TRUE)
# [1] 3
# Levels: 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < 11 < 12
month(dt, label = TRUE, abbr = FALSE)
# [1] 3月
# Levels: 1月 < 2月 < 3月 < 4月 < 5月 < 6月 < 7月 < 8月 < 9月 < 10月 < 11月 < 12月
wday(dt)
# [1] 1
wday(d, label = TRUE)
wday(d, label = TRUE, abbr = TRUE)
# [1] 土
# Levels: 日 < 月 < 火 < 水 < 木 < 金 < 土
wday(d, label = TRUE, abbr = FALSE)
# [1] 日曜日
# Levels: 日曜日 < 月曜日 < 火曜日 < 水曜日 < 木曜日 < 金曜日 < 土曜日
wday(dt, week_start = 1)
# [1] 7
# week_start : 1 means Monday, 7 means Sunday (default).
wday(dt, label = TRUE, week_start = 1)
# [1] 日
# Levels: 月 < 火 < 水 < 木 < 金 < 土 < 日
# baseの関数
d <- ymd("2004/3/21")
weekdays(d)
# [1] "日曜日"
months(d)
# [1] "3月"
quarters(d)
# [1] "Q1"
julian(d)
# [1] 12498
# attr(,"origin")
# [1] "1970-01-01"
yday(dt) # day of year
# [1] 81
# 31+29+21
qday(dt) # day of quarter
# [1] 81
mday(dt) # day of month
# [1] 21
wday(dt) # day of week
# [1] 1
wday(d, label = TRUE)
# [1] 土
# Levels: 日 < 月 < 火 < 水 < 木 < 金 < 土
week(dt)
# [1] 12
# the number of complete seven day periods that have occurred
# between the date and January 1st, plus one.
quarter(dt)
# [1] 1
quarter(dt, with_year = TRUE)
# [1] 2004.1
quarter(dt, with_year = TRUE, fiscal_start = 4)
# [1] 2004.4
semester(dt)
# [1] 1
semester(dt, with_year = TRUE)
# [1] 2004.1
leap_year(dt)
# [1] TRUE
am(dt)
# [1] FALSE
pm(dt)
# [1] TRUE
tz(dt)
# [1] "UTC"
with_tz(dt, "America/Chicago")
# [1] "2004-03-21 06:34:56 CST"
force_tz(dt, "America/Chicago")
# [1] "2004-03-21 12:34:56 CST"
VBA
Debug.Print Weekday(dt)
' 1
Debug.Print WeekdayName(Weekday(dt))
' 日曜日
Debug.Print Weekday(dt, vbMonday)
' 7
Debug.Print WeekdayName(1), WeekdayName(1, False), WeekdayName(1, True)
' 日曜日 日曜日 日
Debug.Print WeekdayName(1, , vbSunday), WeekdayName(1, , vbMonday)
' 日曜日 月曜日
Debug.Print DatePart("y", dt) '何日目(年間通算日)
' 81
Debug.Print DatePart("d", dt) '何日目(月の中で)
' 21
Debug.Print DatePart("w", dt, vbSunday) '何日目(週日)
' 1
Debug.Print DatePart("w", dt, vbMonday) '何日目(週日)
' 7
Debug.Print DatePart("ww", dt) '何週目
' 13
Debug.Print DatePart("ww", dt, , vbFirstJan1)
' 13
Debug.Print DatePart("ww", dt, , vbFirstFourDays)
' 12
Debug.Print DatePart("ww", dt, , vbFirstFullWeek)
' 12
'引数firstweekofyear
'定数 値 説明
'vbFirstJan1 1 1月1日が含まれる週から開始(デフォルト)
'vbFirstFourDays 2 4日以上が含まれる最初の週が年の第1週目
'vbFirstFullWeek 3 1週間全体が含まれる最初の週がその年の第1週目
'引数firstdayofweek
'定数 値 説明
'vbUseSystem 0
'vbSunday 1 日曜日(デフォルト)
'vbMonday 2 月曜
'vbTuesday 3 火曜
'vbWednesday 4 水曜
'vbThursday 5 木曜
'vbFriday 6 金曜
'vbSaturday 7 土曜
日時の計算
日時の加算
Python
dt = datetime.datetime(2004, 3, 21, 12, 34, 56)
print(dt)
# 2004-03-21 12:34:56
print(dt + datetime.timedelta(weeks=1))
# 2004-03-28 12:34:56
print(dt + datetime.timedelta(weeks=-1))
print(dt - datetime.timedelta(weeks=1))
# 2004-03-14 12:34:56
print(dt + datetime.timedelta(days=1))
# 2004-03-22 12:34:56
print(dt + datetime.timedelta(days=-1))
print(dt - datetime.timedelta(days=1))
# 2004-03-20 12:34:56
print(dt + datetime.timedelta(hours=1))
# 2004-03-21 13:34:56
print(dt + datetime.timedelta(hours=-1))
print(dt - datetime.timedelta(hours=1))
# 2004-03-21 11:34:56
print(dt + datetime.timedelta(minutes=1))
# 2004-03-21 12:35:56
print(dt + datetime.timedelta(minutes=-1))
print(dt - datetime.timedelta(minutes=1))
# 2004-03-21 12:33:56
print(dt + datetime.timedelta(seconds=1))
# 2004-03-21 12:34:57
print(dt + datetime.timedelta(seconds=-1))
print(dt - datetime.timedelta(seconds=1))
# 2004-03-21 12:34:55
R
dt <- make_datetime(2004,3,21,12,34,56)
dt
# [1] "2004-03-21 12:34:56 UTC"
dt + 1
# [1] "2004-03-21 12:34:57 UTC"
dt + years(1)
# [1] "2005-03-21 12:34:56 UTC"
dt + years(-1)
dt - years(1)
# [1] "2003-03-21 12:34:56 UTC"
dt + months(1)
# [1] "2004-04-21 12:34:56 UTC"
dt + months(-1)
dt - months(1)
# [1] "2004-02-21 12:34:56 UTC"
dt + weeks(1)
# [1] "2004-03-28 12:34:56 UTC"
dt + weeks(-1)
dt - weeks(1)
# [1] "2004-03-14 12:34:56 UTC"
dt + days(1)
# [1] "2004-03-22 12:34:56 UTC"
dt + days(-1)
dt - days(1)
# [1] "2004-03-20 12:34:56 UTC"
dt + hours(1)
# [1] "2004-03-21 13:34:56 UTC"
dt + hours(-1)
dt - hours(1)
# [1] "2004-03-21 11:34:56 UTC"
dt + minutes(1)
# [1] "2004-03-21 12:35:56 UTC"
dt + minutes(-1)
dt - minutes(1)
# [1] "2004-03-21 12:33:56 UTC"
dt + seconds(1)
# [1] "2004-03-21 12:34:57 UTC"
dt + seconds(-1)
dt - seconds(1)
# [1] "2004-03-21 12:34:55 UTC"
d <- make_date(2004,3,21)
d
# [1] "2004-03-21"
d + 1
# [1] "2004-03-22"
d + years(1)
# [1] "2005-03-21"
d + years(-1)
d - years(1)
# [1] "2003-03-21"
d + months(1)
# [1] "2004-04-21"
d + months(-1)
d - months(1)
# [1] "2004-02-21"
d + weeks(1)
# [1] "2004-03-28"
d + weeks(-1)
d - weeks(1)
# [1] "2004-03-14"
d + days(1)
# [1] "2004-03-22"
d + days(-1)
d - days(1)
# [1] "2004-03-20"
VBA
Dim dt As Date
dt = DateSerial(2004, 3, 21) + TimeSerial(12, 34, 56)
Debug.Print dt
' 2004/03/21 12:34:56
Debug.Print dt + 1, dt - 1
' 2004/03/22 12:34:56 2004/03/20 12:34:56
Debug.Print dt + 1 / 24
' 2004/03/21 13:34:56
Debug.Print dt + 1 / 24 / 60
' 2004/03/21 12:35:56
Debug.Print dt + 1 / 24 / 60 / 60
' 2004/03/21 12:34:57
Debug.Print DateAdd("yyyy", 1, dt), DateAdd("yyyy", -1, dt) '年
' 2005/03/21 12:34:56 2003/03/21 12:34:56
Debug.Print DateAdd("q", 1, dt), DateAdd("q", -1, dt) '四半期
' 2004/06/21 12:34:56 2003/12/21 12:34:56
Debug.Print DateAdd("m", 1, dt), DateAdd("m", -1, dt) '月
' 2004/04/21 12:34:56 2004/02/21 12:34:56
Debug.Print DateAdd("d", 1, dt), DateAdd("d", -1, dt) '日
' 2004/03/22 12:34:56 2004/03/20 12:34:56
Debug.Print DateAdd("ww", 1, dt), DateAdd("ww", -1, dt) '週
' 2004/03/28 12:34:56 2004/03/14 12:34:56
Debug.Print DateAdd("h", 1, dt), DateAdd("h", -1, dt) '時間
' 2004/03/21 13:34:56 2004/03/21 11:34:56
Debug.Print DateAdd("n", 1, dt), DateAdd("n", -1, dt) '分
' 2004/03/21 12:35:56 2004/03/21 12:33:56
Debug.Print DateAdd("s", 1, dt), DateAdd("s", -1, dt) '秒
' 2004/03/21 12:34:57 2004/03/21 12:34:55
日時の差
Python
d1 = datetime.date(2004, 3, 21)
d2 = datetime.date(2003, 3, 21)
print(d1 - d2)
# 366 days, 0:00:00
print(type(d1 - d2))
# <class 'datetime.timedelta'>
print((d1 - d2).days)
# 366
print((d1 - d2).seconds)
# 0
print((d1 - d2).microseconds)
# 0
print((d1 - d2).total_seconds())
# 31622400.0
R
dt1 <- make_date(2004, 3, 21)
dt1
# [1] "2004-03-21"
dt2 <- make_date(2003, 3, 21)
dt2
# [1] "2003-03-21"
dt1 - dt2
# Time difference of 405 days
interval(dt1, dt2)
# [1] 2004-03-21 UTC--2003-02-10 UTC
dt1 %--% dt2
# [1] 2004-03-21 UTC--2003-02-10 UTC
class(dt1 %--% dt2)
# [1] "Interval"
# attr(,"package")
# [1] "lubridate"
interval(dt2, dt1) / years(1)
# [1] 1
interval(dt2, dt1) / days(1)
# [1] 366
int_length(interval(dt2, dt1))
# [1] 31622400
31622400 / 24 / 60 / 60
# [1] 366
VBA
Dim dt1 As Date
Dim dt2 As Date
dt1 = DateSerial(2004, 3, 21)
dt2 = DateSerial(2003, 3, 21)
Debug.Print dt1, dt2
' 2004/03/21 2003/03/21
Debug.Print dt1 - dt2
' 366
Debug.Print dt2 - dt1
' -366
日時の大小関係
Python
print(d1 > d2)
# True
print(d1 >= d2)
# True
print(d1 == d2)
# False
print(d1 <= d2)
# False
print(d1 < d2)
# False
R
dt1 <- make_date(2004, 3, 21)
dt1
# [1] "2004-03-21"
dt2 <- make_date(2003, 3, 21)
dt2
# [1] "2003-03-21"
dt1 > dt2
# [1] TRUE
dt1 >= dt2
# [1] TRUE
dt1 == dt2
# [1] FALSE
dt1 < dt2
# [1] FALSE
dt1 <= dt2
# [1] FALSE
VBA
Debug.Print dt1 > dt2
' True
Debug.Print dt1 >= dt2
' True
Debug.Print dt1 = dt2
' False
Debug.Print dt1 < dt2
' False
Debug.Print dt1 <= dt2
' False
日時の丸め処理
Python
R
round_date(dt, unit = "day")
# [1] "2004-03-22 UTC"
floor_date(dt, unit = "minute")
# [1] "2004-03-21 12:34:00 UTC"
ceiling_date(dt, unit = "month")
# [1] "2004-04-01 UTC"
# Valid units are second, minute, hour, day, week, month, bimonth,
# quarter, season, halfyear and year.
VBA
日時型のデータ列
補足
エクセルでは、歴史的な経緯(Lotusとの互換性)から、本来は閏年ではない1900年を閏年として扱っているため、VBAのシリアル値と1日ずれます。
Microsoft
Excel 1900 年がうるう年と誤って想定される
Excel incorrectly assumes that the year 1900 is a leap year
1900 年と 1904 年の日付システムの違Excel
年がうるう年かどうかを判断する方法
Lotus 1-2-3 が最初にリリースされた時、プログラムは、実際にはうるう年ではないにもかかわらず、1900 年はうるう年であると仮定しました。 これにより、プログラムはうるう年の処理が容易になり、Lotus 1-2-3 のほとんどすべての日付計算に害を及ぼしました。
Microsoft Multiplan と Microsoft Excelリリース時には、1900 年がうるう年であるとも見なされました。 この前提により、Microsoft Multiplan と Microsoft Excel は Lotus 1-2-3 で使用されるのと同じシリアル日付システムを使用し、Lotus 1-2-3 との互換性を向上しました。
エクセルの学校
ExcelPedia シリアル値
シリアル値 (tp0049)
『シリアル値について』
1900年は本来閏年ではないが、「エクセルでは」閏年として扱っている。このため、1900年1月1日から起算した場合、1900年3月1日以後の日付連番は実際の日数よりも 1 大きい数値となる。これに対し、Excel VBA? では、平年扱いとなっており、ユーザー定義関数(UDF)?を作成して計算する場合には、この点を考慮して設計する必要がある。
## Excel is said to use 1900-01-01 as day 1 (Windows default) or
## 1904-01-01 as day 0 (Mac default), but this is complicated by Excel
## incorrectly treating 1900 as a leap year.
## So for dates (post-1901) from Windows Excel
as.Date(35981, origin = "1899-12-30") # 1998-07-05
## and Mac Excel
as.Date(34519, origin = "1904-01-01") # 1998-07-05
## (these values come from http://support.microsoft.com/kb/214330)
まとめ
各言語のコード等を一覧にまとめます。比較のために、EXCELの数式も示しました。
データ型
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
日付 | date オブジェクト | "Date" クラス | Date型(整数部分) | Date型(整数部分) |
時刻 | time オブジェクト | "hms" "difftime" クラス | Date型(小数部分) | Date型(小数部分) |
日時 | datetime オブジェクト | "POSIXct" "POSIXt" クラス | Date型 | Date型 |
現在の日時
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
現在の日付 | datetime.date.today() | today() | Date | =TODAY() |
現在の時刻 | datetime.datetime.now(). time() |
Time | ||
現在の日時 | datetime.datetime.now() | now() | Now | =NOW() |
日付型⇒シリアル値
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
日付 | as.numeric(d) unclass(d) |
CLng(d) | ||
時刻 | as.numeric(t) unclass(t) |
CDbl(t) | ||
日時 | dt.timestamp() | as.numeric(dt) unclass(dt) |
CDbl(dt) |
シリアル値⇒日時型
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
日付 | as_date(d) | CDate(d) | =A1 | |
時刻 | hms::as_hms(t) | CDate(t) | =A1 | |
日時 | datetime.datetime. fromtimestamp(d) |
as_datetime(dt) | CDate(dt) | =A1 |
文字列型⇒日時型
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
日付 | datetime.datetime. strptime('s', '%Y/%m/%d').date() |
as_date(s) as.Date(s, "%Y/%m/%d") ymd(s) 等 |
CDate(s) DateValue(s) |
=DATEVALUE(A1) |
時刻 | datetime.datetime. strptime(s, '%H:%M:%S').time() |
hms::as_hms(s) | CDate(s) TimeValue(s) |
=TIMEVALUE(A1) |
日時 | datetime.datetime. strptime(s, '%Y/%m/%d %H:%M:%S') |
as_datetime(s) ymd_hms(s) 等 |
CDate(s) |
日時型⇒文字列型
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
日付 | d.strftime('%Y/%m/%d') '{0:%Y/%m/%d}'.format(d) |
strftime(d, format="%Y/%m/%d") | Format(d, "yyyy/mm/dd") | =TEXT(A1,"yyyy/mm/dd") |
時刻 | t.strftime('%H:%M:%S') '{0:%H:%M:%S}'.format(t) |
strftime(t, format="%H:%M:%S") | Format(t, "hh:nn:ss") | =TEXT(A1,"hh:nn:ss") |
日時 | dt.strftime('%Y/%m/%d %H:%M:%S') '{0:%Y/%m/%d %H:%M:%S}'.format(dt) |
strftime(dt, format="%Y/%m/%d %H:%M:%S") | Format(dt, "yyyy/mm/dd hh:nn:ss") | =TEXT(A1,"yyyy/mm/dd hh:nn:ss") |
日時の要素⇒日時型
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
日付 | datetime.date(2004, 3, 21) | make_date(2004, 3, 21) | DateSerial(2004, 3, 21) | =DATE(2004,3,21) |
時刻 | datetime.time(12, 34, 56) | TimeSerial(12, 34, 56) | =TIME(12,34,56) | |
日時 | datetime.datetime(2004, 3, 21, 12, 34, 56) | make_datetime(2004, 3, 21, 12, 34, 56) | DateSerial(2004, 3, 21) + TimeSerial(12, 34, 56) |
=DATE(2004,3,21) +TIME(12,34,56) |
日時型⇒日時の要素
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
年 | dt.year | year(dt) | Year(dt) | =YEAR(A1) |
月 | dt.month | month(dt) | Month(dt) | =MONTH(A1) |
日 | dt.day | day(dt) | Day(dt) | =DAY(A1) |
時 | dt.hour | hour(dt) | Hour(dt) | =HOUR(A1) |
分 | dt.minute | minute(dt) | Minute(dt) | =MINUTE(A1) |
秒 | dt.second | second(dt) | Second(dt) | =SECOND(A1) |
マイクロ秒 | dt.microsecond | |||
日付 | dt.date() | date(dt) as_date(dt) |
||
時刻 | dt.time() | |||
曜日 | dt.weekday() | wday(dt) wday(d, label = T) |
Weekday(dt) WeekdayName( Weekday(dt)) |
=WEEKDAY(A1) |
年の通算日 | yday(dt) | DatePart("y", dt) | ||
四半期の通算日 | qday(dt) | |||
月の通算日 =日 |
mday(dt) | DatePart("d", dt) | ||
週の通算日 =曜日 |
wday(dt) wday(d, label = T) |
DatePart("w", dt) | ||
年の通算週 =週 |
DatePart("ww", dt) | =WEEKNUM(A1) | ||
四半期 | quarter(dt) quarter(dt, with_year = T) |
|||
半期 | semester(dt) semester(dt, with_year = T) |
|||
閏年 | leap_year(dt) | |||
午前 | am(dt) | |||
午後 | pm(dt) | |||
タイムゾーン | tz(dt) | |||
タイムゾーン変更 | with_tz(dt, "America/Chicago") |
日時の加算
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
年 | dt + years(1) | DateAdd("yyyy", 1, dt) | ||
半期 | ||||
四半期 | DateAdd("q", 1, dt) | |||
月 | dt + months(1) | DateAdd("m", 1, dt) | =EDATE(A1,1) | |
週 | dt + datetime.timedelta(weeks=1) |
dt + weeks(1) | DateAdd("ww", 1, dt) | =A1+7 |
日 | dt + datetime.timedelta(days=1) |
dt + days(1) d + 1 |
DateAdd("d", 1, dt) dt + 1 |
=A1+1 |
時間 | dt + datetime.timedelta(hours=1) |
dt + hours(1) | DateAdd("h", 1, dt) dt + 1/24 |
=A1+1/24 |
分 | dt + datetime.timedelta(minutes=1) |
dt + minutes(1) | DateAdd("n", 1, dt) dt + 1/24/60 |
=A1+1/24/60 |
秒 | dt + datetime.timedelta(seconds=1) |
dt + seconds(1) dt + 1 |
DateAdd("s", 1, dt) dt + 1/24/60/60 |
=A1+1/24/60/60 |
日時の差
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
日付 | (d1 - d2).days | d1 - d2 interval(dt1, dt2) dt1 %--% dt2 |
d1 - d2 | =A1-A2 =DAYS(A2,A1) |
時刻 | (d1 - d2).seconds | d1 - d2 | =A1-A2 | |
日時 | (d1 - d2).total_seconds() | d1 - d2 | =A1-A2 |
日時の大小関係
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
> | d1 > d2 | dt1 > dt2 | dt1 > dt2 | =A1>A2 |
≧ | d1 >= d2 | dt1 >= dt2 | dt1 >= dt2 | =A1>=A2 |
= | dt1 == dt2 | dt1 == dt2 | dt1 = dt2 | =A1>A2 |
≦ | dt1 < dt2 | dt1 < dt2 | dt1 < dt2 | =A1<A2 |
< | dt1 <= dt2 | dt1 <= dt2 | dt1 <= dt2 | =A1<=A2 |
日時の丸め処理
Python (datetime) | R (lubridate) | VBA | EXCEL | |
---|---|---|---|---|
ラウンド | round_date(dt, unit = "day") | |||
天井 | ceiling_date(dt, unit = "month") | |||
床 | floor_date(dt, unit = "minute") |
参考
- Python
- https://docs.python.org/ja/3/tutorial/stdlib.html#dates-and-times
- https://docs.python.org/ja/3/library/datetime.html
- https://note.nkmk.me/date-and-time/
- https://note.nkmk.me/python-unix-time-datetime/
- https://docs.python.org/ja/3/library/time.html#time.strftime
- https://docs.python.org/ja/3/library/datetime.html#strftime-strptime-behavior
- https://note.nkmk.me/python-datetime-usage/
- R
- VBA
- Excel
- https://docs.microsoft.com/ja-jp/office/troubleshoot/excel/wrongly-assumes-1900-is-leap-year
- https://docs.microsoft.com/en-us/office/troubleshoot/excel/wrongly-assumes-1900-is-leap-year
- https://docs.microsoft.com/ja-JP/office/troubleshoot/excel/1900-and-1904-date-system
- https://docs.microsoft.com/ja-jp/office/troubleshoot/excel/determine-a-leap-year