具有LocalDate和LocalDateTime的Groovy的TimeCategory

时间:2016-03-29 20:26:14

标签: groovy java-8

是否有关于如何在java8 LocalDate和LocalDateTime中使用TimeCategory(或等效)的示例或参考?我发现的所有代码片段都引用了java.util.Date,我试图避免这种情况。

3 个答案:

答案 0 :(得分:3)

使用Java 8 LocalDate操作非常简单:

LocalDate.now().plusDays(2)

我不确定TimeCategory会让你获得什么?

你可以很简单地将它破解到metaDlass of LocalDate和LocalDatTime:

import groovy.time.*
import java.time.*

LocalDate.metaClass {
    plus { Duration d ->
        delegate.plusYears(d.years)
                .plusMonths(d.months)
                .plusDays(d.days)
    }
}

LocalDateTime.metaClass {
    plus { Duration d ->
        delegate.plusYears(d.years)
                .plusMonths(d.months)
                .plusDays(d.days)
                .plusHours(d.hours)
                .plusMinutes(d.minutes)
                .plusSeconds(d.seconds)
    }
}

use(TimeCategory) {
    LocalDateTime.now() + 4.days
}

答案 1 :(得分:2)

一个简单的例子是:

import groovy.time.TimeCategory
import java.time.LocalDate
import java.time.LocalDateTime

use( TimeCategory ) {
    println Date.parse('yyyy-MM-dd', LocalDate.now().toString()) + 4.hours
    println Date.parse("yyyy-MM-dd'T'hh:mm:ss", LocalDateTime.now().toString()) - 4.hours
}

答案 2 :(得分:2)

我也感到失望的是TimeCategory声明了自己的持续时间并且不是Java 8友好的。这促使我写了一些我自己的代码,我认为这与这个问题有关。它集中在ZonedDateTime而非LocalDateTime,因为我对使用它的TimeZone逻辑感兴趣。它不像groovy.time.TimeCategory类那样完整,并且只有我感兴趣的一些操作,所以请随意添加它。

没有进一步的麻烦:

import java.time.Duration
import java.time.ZoneOffset
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit

class TimeCategory {
    static getDays(Integer self) { Duration.ofDays self }
    static getHours(Integer self) { Duration.ofHours self }
    static getMillis(Integer self) { Duration.ofMillis self }
    static getMinutes(Integer self) { Duration.ofMinutes self }
    static getNanos(Integer self) { Duration.ofNanos self }
    static getSeconds(Integer self) { Duration.ofSeconds self }
    static getWeeks(Integer self) { Duration.ofDays self * 7 }
    static getDay(Integer self) { Duration.ofDays self }
    static getHour(Integer self) { Duration.ofHours self }
    static getMilli(Integer self) { Duration.ofMillis self }
    static getMinute(Integer self) { Duration.ofMinutes self }
    static getNano(Integer self) { Duration.ofNanos self }
    static getSecond(Integer self) { Duration.ofSeconds self }
    static getWeek(Integer self) { Duration.ofDays self * 7 }
    static ZonedDateTime getAgo(Duration self) { ZonedDateTime.now() - self }
    static ZonedDateTime getUtc(ZonedDateTime self) { self.withZoneSameInstant(ZoneOffset.UTC) }
    static ZonedDateTime getLocal(ZonedDateTime self) { self.withZoneSameInstant(ZoneOffset.systemDefault()) }
    static ZonedDateTime getNow() { ZonedDateTime.now() }
    static Duration minus(ZonedDateTime self, ZonedDateTime other) { Duration.between(self, other) }
    static BigInteger getTotalNanos(Duration self) { self.seconds.toBigInteger() * 10 ** 9 + self.nano }
    static String toString(ZonedDateTime self, String pattern) { self.format(DateTimeFormatter.ofPattern(pattern)) }
    static Duration mod(Duration self, Duration other) {
        def (long seconds, int nanos) = (self.totalNanos % other.totalNanos).divideAndRemainder(10g.pow(9))
        Duration.ofSeconds(seconds) + nanos.nanos
    }

    static load() {
        Integer.mixin(TimeCategory)
        ZonedDateTime.mixin(TimeCategory)
        Duration.mixin(TimeCategory)
    }
}

使用示例:

// I prefer putting this in a start-up location and pollute the namespace rather than use 
// `use() {...}`
TimeCategory.load()

// Construct readable java 8 durations
Duration d = 1.day + 2.hours + 3.minutes - 4.seconds

// Easily construct dates relative to now
ZonedDateTime yesterday = 1.day.ago

// Of course, you can still call "unsugared" functions like truncatedTo for rounding down
ZonedDateTime today = TimeCategory.now.truncatedTo(ChronoUnit.DAYS)

// Converting between local and utc doesn't change the underlying instant
assert 0.seconds == yesterday.utc - yesterday.local

// Modulo arithmetic.  Cool!
assert 1.minute % 17.seconds == 9.seconds

// Slightly cleaner date formatting
println "Today in strange format ${today.toString('dd/yy/MM')}"