Groovy で日付・時刻を扱う方法について

はじめに

Groovy で日付/時刻を扱う方法は以下。

  1. Java 7 以前からある java.util.Calendar / java.util.Date を利用する
  2. Java 8 で追加された Date/Time API を利用する

上記の2種類の方法について、簡単に使い方をまとめる。

現在の日時を取得する

Java 7 以前

Date を使う場合

def date = new Date()

取得した現在日時を操作する場合 Calendar を利用する。

def cal = Calendar.instance

Java 8以降

import java.time.LocalDateTime

def ldt = LocalDateTime.now()

現在の日時を文字に変換する

Java 7 以前

import java.text.SimpleDateFormat

def date = new Date()
def format = new SimpleDateFormat('yyyy/MM/dd HH:mm:ss.SSS')
println format.format(date)

Java 8以降

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

def ldt = LocalDateTime.now()
def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.SSS')
println ldt.format(formatter)

LocalDateTime の精度はナノ秒なので、書式を yyyy/MM/dd HH:mm:ss.nnnnnnnnn とすることで、ナノ秒まで表示できる。

ただし、Windows 10 では LocalDateTime.now() の精度はミリ秒までとなっている。

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

def ldt = LocalDateTime.now()
def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.nnnnnnnnn')
println ldt.format(formatter)

日時の文字列から Date / LocalDateTime のインスタンスに変換する

Java 7 以前

import java.text.SimpleDateFormat

def str = '2017/10/01 12:34:56.123'
def format = new SimpleDateFormat('yyyy/MM/dd HH:mm:ss.SSS')
def date = format.parse(str)

assert format.format(date) == str

Java 8以降

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

def str = '2017/10/01 12:34:56.123'
def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.SSS')
def ldt = LocalDateTime.parse(str, formatter)

assert ldt.format(formatter) == str

日時から 00時00分00秒000ミリ秒 の日付を取得する。

Java 7 以前

import java.text.SimpleDateFormat

def cal = Calendar.instance
cal.set(Calendar.HOUR_OF_DAY, 0)
cal.set(Calendar.MINUTE, 0)
cal.set(Calendar.SECOND, 0)
cal.set(Calendar.MILLISECOND, 0)
def date = cal.time

def format = new SimpleDateFormat('yyyy/MM/dd HH:mm:ss.SSS')
println format.format(date)

Java 8以降

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit

def now = LocalDateTime.now()
def ldt = date.truncatedTo(ChronoUnit.DAYS)

def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.SSS')
println ldt.format(formatter)

そもそも Java 8 では LocalDate という日付だけのクラスがあるので、LocalDate を使う。

import java.time.LocalDate
import java.time.format.DateTimeFormatter

def ld = LocalDate.now()

def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd')
println ld.format(formatter)

日時クラスとして利用したい場合

import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter

def ld = LocalDate.now()
def ldt = LocalDateTime.of(date, LocalTime.MIDNIGHT)

def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.SSS')
println ldt.format(formatter)

こちらでもよい。

import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter

def localDate = LocalDate.now()
def localDateTime = localDate.atTime(LocalTime.MIDNIGHT)

def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.SSS')
println localDateTime.format(formatter)

日時の演算をする。

現在の日時の10日後を計算する場合のサンプル。

Java 7 以前

import java.text.SimpleDateFormat

def cal = Calendar.instance
cal.add(Calendar.DAY_OF_MONTH, 10)
def date = cal.time

def format = new SimpleDateFormat('yyyy/MM/dd HH:mm:ss.SSS')
println format.format(date)

Java 8 以降

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

def now = LocalDateTime.now()
def ldt = now.plusDays(10)

def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.SSS')
println ldt.format(formatter)

演算で利用するメソッドは以下。すべて新しいインスタンスを返す。

メソッド説明
minusYears年を減算する
minusMonths月を減算する
minusDays日を減算する
minusHours時を減算する
minusMinutes分を減算する
minusSeconds秒を減算する
minusNanosナノ秒を減算する
plusYears年を加算する
plusMonths月を加算する
plusDays日を加算する
plusHours時を加算する
plusMinutes分を加算する
plusSeconds秒を加算する
plusNanosナノ秒を加算する
withYear年を変更する
withMonth月を変更する
withDayOfMonth日を変更する
withHour時を変更する
withMinute分を変更する
withSecond秒を変更する
withNanoナノ秒を変更する

java.sql.Timestamp を文字に変換する。

Java 7 以前

import java.sql.Timestamp
import java.text.SimpleDateFormat

def timestamp = Timestamp.valueOf('2017-10-01 12:34:56.012345678')
def format = new SimpleDateFormat('yyyy/MM/dd HH:mm:ss')
def str = format.format(timestamp) + '.' + Integer.toString(timestamp.nanos).padLeft(9, '0')

assert str == '2017/10/01 12:34:56.012345678'

Java 8以降

import java.sql.Timestamp
import java.time.format.DateTimeFormatter

def timestamp = Timestamp.valueOf('2017-10-01 12:34:56.012345678')
def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.nnnnnnnnn')
def str = timestamp.toLocalDateTime().format(formatter)

assert str == '2017/10/01 12:34:56.012345678'

ミリ秒から Date / LocalDateTime に変換する

Java 7 以前

import java.text.SimpleDateFormat

def millis = System.currentTimeMillis()
def date = new Date(millis)

def format = new SimpleDateFormat('yyyy/MM/dd HH:mm:ss.SSS')
println format.format(date)

Java 8 以降

import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter

def millis = System.currentTimeMillis()
def instant = Instant.ofEpochMilli(millis)
def ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())

def formatter = DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss.SSS')
println ldt.format(formatter)

DateLocalDateTime の変換

DateLocalDateTime の変換

import java.time.LocalDateTime
import java.time.ZoneId

def date = new Date()
def ldt1 = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())
def ldt2 = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()

DateLocalDateTime の変換

import java.time.LocalDateTime
import java.time.ZoneId

def ldt = LocalDateTime.now()
def zdt = ldt.atZone(ZoneId.systemDefault())
def date = Date.from(zdt.toInstant())

CalendarLocalDateTime の変換

CalendarLocalDateTime の変換

import java.time.LocalDateTime
import java.time.ZoneId

def cal = Calendar.instance
def instant = cal.toInstant()
def ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())

CalendarLocalDateTime の変換

import java.time.LocalDateTime
import java.time.ZoneId

def ldt = LocalDateTime.now()
def zdt = ldt.atZone(ZoneId.systemDefault())
def date = Date.from(zdt.toInstant())
def cal = Calendar.instance
cal.setTime(date)

DateLocalDate の変換

DateLocalDateの変換

import java.time.LocalDate
import java.time.ZoneId

def date = new Date()
def ld = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()

DateLocalDateの変換

import java.time.LocalDate
import java.time.ZoneId

def ld = LocalDate.now()
def zdt = ld.atStartOfDay(ZoneId.systemDefault())
def date = Date.from(zdt.toInstant())

CalendarLocalDate の変換

CalendarLocalDateの変換

import java.time.LocalDate
import java.time.ZoneId

def calendar = Calendar.instance
def localDate = calendar.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()

CalendarLocalDateの変換

import java.time.LocalDate
import java.time.ZoneId

def localDate = LocalDate.now()
def zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault())
def date = Date.from(zonedDateTime.toInstant())
def calendar = Calendar.instance
calendar.setTime(date)

java.sql.DateLocalDateの変換

java.sql.DateLocalDateの変換

import java.sql.Date

def date = new Date(new java.util.Date().time)
def localDate = date.toLocalDate()

java.sql.DateLocalDateの変換

import java.sql.Date
import java.time.LocalDate


def localDate = LocalDate.now()
def date = Date.valueOf(localDate)

java.sql.TimeLocaTimeの変換

java.sql.TimeLocalTimeの変換

import java.sql.Time

def time = new Time(new java.util.Date().time)
def localTime = time.toLocalTime()

java.sql.TimeLocalTimeの変換

import java.sql.Time
import java.time.LocalTime


def localTime = LocalTime.now()
def time = Time.valueOf(localTime)

java.sql.TimestampLocaDateTimeの変換

java.sql.TimestampLocaDateTimeの変換

import java.sql.Timestamp

def timestamp = new Timestamp(new java.util.Date().time)
timestamp.setNanos(1)
def localDateTime = timestamp.toLocalDateTime()

java.sql.TimestampLocaDateTimeの変換

import java.sql.Timestamp
import java.time.LocalDateTime


def localDateTime = LocalDateTime.now().withNano(1)
def timestamp = Timestamp.valueOf(localDateTime)

コメント