http://git-wip-us.apache.org/repos/asf/groovy/blob/718a820a/src/spec/doc/working-with-datetime-types.adoc ---------------------------------------------------------------------- diff --git a/src/spec/doc/working-with-datetime-types.adoc b/src/spec/doc/working-with-datetime-types.adoc deleted file mode 100644 index 6567154..0000000 --- a/src/spec/doc/working-with-datetime-types.adoc +++ /dev/null @@ -1,341 +0,0 @@ -////////////////////////////////////////// - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. - -////////////////////////////////////////// - -= Working with Date/Time types -:gdk: http://www.groovy-lang.org/gdk.html[Groovy development kit] -:java-util-list: http://docs.oracle.com/javase/8/docs/api/java/util/List.html[java.util.List] -:java-time-types: `java.time` types - -Groovy's syntax and extension methods within the {gdk} provide conveniences for using -the http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html[Date/Time API -introduced in Java 8]. This documentation refers to the data types defined by this API as -"JSR 310 types." - -== Formatting and parsing - -A common use case when working with date/time types is to convert them to Strings (formatting) -and from Strings (parsing). Groovy provides these additional formatting methods: - -[cols="1,1,1" options="header"] -|==== -| Method -| Description -| Example - -| `getDateString()` -| For `LocalDate` and `LocalDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_DATE[`DateTimeFormatter.ISO_LOCAL_DATE`] -| `2018-03-10` - -| -| For `OffsetDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_OFFSET_DATE[`DateTimeFormatter.ISO_OFFSET_DATE`] -| `2018-03-10+04:00` - -| -| For `ZonedDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_DATE[`DateTimeFormatter.ISO_LOCAL_DATE`] -and appends the `ZoneId` short name -| `2018-03-10EST` - -| `getDateTimeString()` -| For `LocalDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_DATE_TIME[`DateTimeFormatter.ISO_LOCAL_DATE_TIME`] -| `2018-03-10T20:30:45` - -| -| For `OffsetDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_OFFSET_DATE_TIME[`DateTimeFormatter.ISO_OFFSET_DATE_TIME`] -| `2018-03-10T20:30:45+04:00` - -| -| For `ZonedDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_DATE_TIME[`DateTimeFormatter.ISO_LOCAL_DATE_TIME`] -and appends the `ZoneId` short name -| `2018-03-10T20:30:45EST` - -| `getTimeString()` -| For `LocalTime` and `LocalDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_TIME[`DateTimeFormatter.ISO_LOCAL_TIME`] -| `20:30:45` - -| -| For `OffsetTime` and `OffsetDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_OFFSET_TIME[`DateTimeFormatter.ISO_OFFSET_TIME`] -formatter -| `20:30:45+04:00` - -| -| For `ZonedDateTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_TIME[`DateTimeFormatter.ISO_LOCAL_TIME`] -and appends the `ZoneId` short name -| `20:30:45EST` - -| `format(FormatStyle style)` -| For `LocalTime` and `OffsetTime`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ofLocalizedTime-java.time.format.FormatStyle-[`DateTimeFormatter.ofLocalizedTime(style)`] -| `4:30 AM` (with style `FormatStyle.SHORT`, e.g.) - -| -| For `LocalDate`, formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ofLocalizedDate-java.time.format.FormatStyle-[`DateTimeFormatter.ofLocalizedDate(style)`] -| `Saturday, March 10, 2018` (with style `FormatStyle.FULL`, e.g.) - -| -| For `LocalDateTime`, `OffsetDateTime`, and `ZonedDateTime` formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ofLocalizedDateTime-java.time.format.FormatStyle-[`DateTimeFormatter.ofLocalizedDateTime(style)`] -| `Mar 10, 2019 4:30:45 AM` (with style `FormatStyle.MEDIUM`, e.g.) - -| `format(String pattern)` -| Formats with -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ofPattern-java.lang.String-[`DateTimeFormatter.ofPattern(pattern)`] -| `03/10/2018` (with pattern `'MM/dd/yyyy', e.g.) -|==== - -For parsing, Groovy adds a static `parse` method to many of the JSR 310 types. The method -takes two arguments: the value to be formatted and the pattern to use. The pattern is -defined by the -https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html[`java.time.format.DateTimeFormatter` API]. -As an example: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=static_parsing,indent=0] -------------------------------------- - -Note that these `parse` methods have a different argument ordering than the static -`parse` method Groovy added to `java.util.Date`. -This was done to be consistent with the existing `parse` methods of the Date/Time API. - -== Manipulating date/time - -=== Addition and subtraction - -`Temporal` types have `plus` and `minus` methods for adding or subtracting a provided -`java.time.temporal.TemporalAmount` argument. Because Groovy maps the `+` and `-` operators -to single-argument methods of these names, a more natural expression syntax can be used to add and subtract. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=plus_minus_period,indent=0] -------------------------------------- - -Groovy provides additional `plus` and `minus` methods that accept an integer argument, -enabling the above to be rewritten more succinctly: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=localdate_plus_minus_integer,indent=0] -------------------------------------- - -The unit of these integers depends on the JSR 310 type operand. As evident above, -integers used with `ChronoLocalDate` types like `LocalDate` have a unit of -https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html#DAYShttp://days[days]. -Integers used with `Year` and `YearMonth` have a unit of -https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html#YEARS[years] and -https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html#MONTHS[months], respectively. -All other types have a unit of -https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html#SECONDS[seconds], -such as `LocalTime`, for instance: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=localtime_plus_minus_integer,indent=0] -------------------------------------- - -=== Multiplication and division - -The `*` operator can be used to multiply `Period` and `Duration` instances by an -integer value; the `/` operator can be used to divide `Duration` instances by an integer value. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=multiply_divide,indent=0] -------------------------------------- - -=== Incrementing and decrementing - -The `++` and `--` operators can be used increment and decrement date/time values by one unit. Since the JSR 310 types -are immutable, the operation will create a new instance with the incremented/decremented value and reassign it to the -reference. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=next_previous,indent=0] -------------------------------------- - -=== Negation - -The `Duration` and `Period` types represent a negative or positive length of time. -These can be negated with the unary `-` operator. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=duration_negation,indent=0] -------------------------------------- - -== Interacting with date/time values - -=== Property notation - -The -https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAccessor.html#getLong-java.time.temporal.TemporalField-[`getLong(TemporalField)`] -method of `TemporalAccessor` types (e.g. `LocalDate`, -`LocalTime`, `ZonedDateTime`, etc.) and the -https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAmount.html#get-java.time.temporal.TemporalUnit-[`get(TemporalUnit)`] -method of `TemporalAmount` types (namely `Period` and `Duration`), can be invoked with -Groovy's property notation. For example: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=property_notation,indent=0] -------------------------------------- - -=== Ranges, `upto`, and `downto` - -The JSR 310 types can be used with the <<core-operators.adoc#_range_operator,range operator>>. -The following example iterates between today and the `LocalDate` six days from now, -printing out the day of the week for each iteration. As both range bounds are inclusive, -this prints all seven days of the week. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=date_ranges,indent=0] -------------------------------------- - -The `upto` method will accomplish the same as the range in the above example. -The `upto` method iterates from the earlier start value (inclusive) to the later end value -(also inclusive), calling the closure with the incremented value once per iteration. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=date_upto_date,indent=0] -------------------------------------- - -The `downto` method iterates in the opposite direction, from a later start value -to an earlier end value. - -The unit of iteration for `upto`, `downto`, and ranges is the same as the unit for addition -and subtraction: `LocalDate` iterates by one day at a time, -`YearMonth` iterates by one month, `Year` by one year, and everything else by one second. -Both methods also support an optional a `TemporalUnit` argument to change the unit of -iteration. - -Consider the following example, where March 1st, 2018 is iterated up to March 2nd, 2018 -using an iteration unit of -https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html#MONTHS[months]. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=date_upto_date_by_months,indent=0] -------------------------------------- - -Since the start date is inclusive, the closure is called with date March 1st. The `upto` method -then increments the date by one month, yielding the date, April 1st. Because this date is _after_ the -specified end date of March 2nd, the iteration stops immediately, having only called the closure -once. This behavior is the same for the `downto` method except that the iteration will stop -as soon as the the value of `end` becomes earlier than the targeted end date. - -In short, when iterating with the `upto` or `downto` methods with a custom unit of iteration, -the current value of iteration will never exceed the end value. - -=== Combining date/time values - -The left-shift operator (`<<`) can be used to combine two JSR 310 types into an aggregate type. -For example, a `LocalDate` can be left-shifted into a `LocalTime` to produce a composite -`LocalDateTime` instance. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=leftshift_operator,indent=0] -------------------------------------- - -The left-shift operator is reflexive; the order of the operands does not matter. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=leftshift_operator_reflexive,indent=0] -------------------------------------- - -=== Creating periods and durations - -The right-shift operator (`>>`) produces a value representing the period or duration between the -operands. For `ChronoLocalDate`, `YearMonth`, and `Year`, the operator yields -a `Period` instance: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=rightshift_operator_period,indent=0] -------------------------------------- - -The operator produces a `Duration` for the time-aware JSR types: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=rightshift_operator_duration,indent=0] -------------------------------------- - -If the value on the left-hand side of the operator is earlier than the value on the right-hand -side, the result is positive. If the left-hand side is later than the right-hand side, the -result is negative: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=rightshift_operator_negative,indent=0] -------------------------------------- - -== Converting between legacy and JSR 310 types - -Despite the shortcomings of `Date`, `Calendar`, and `TimeZone` types in the `java.util` package -they are farily common in Java APIs (at least in those prior to Java 8). -To accommodate use of such APIs, Groovy provides methods for converting between the -JSR 310 types and legacy types. - -Most JSR types have been fitted with `toDate()` and `toCalendar()` methods for -converting to relatively equivalent `java.util.Date` and `java.util.Calendar` values. -Both `ZoneId` and `ZoneOffset` have been given a `toTimeZone()` method for converting to -`java.util.TimeZone`. - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=todate_tocalendar,indent=0] -------------------------------------- - -Note that when converting to a legacy type: - -* Nanosecond values are truncated to milliseconds. A `LocalTime`, for example, with a `ChronoUnit.NANOS` value -of 999,999,999 nanoseconds translates to 999 milliseconds. -* When converting the "local" types (`LocalDate`, `LocalTime`, and `LocalDateTime`), the time zone of the -returned `Date` or `Calendar` will be the system default. -* When converting a time-only type (`LocalTime` or `OffsetTime`), the year/month/day of the `Date` or `Calendar` is set -to the current date. -* When converting a date-only type (`LocalDate`), the time value of the `Date` or `Calendar` will be cleared, -i.e. `00:00:00.000`. -* When converting an `OffsetDateTime` to a `Calendar`, only the hours and minutes of the `ZoneOffset` convey -into the corresponding `TimeZone`. Fortunately, Zone Offsets with non-zero seconds are rare. - -Groovy has added a number of methods to `Date` and `Calendar` -for converting into the various JSR 310 types: - -[source,groovy] -------------------------------------- -include::{projectdir}/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy[tags=to_jsr310_types,indent=0] --------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/718a820a/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy ---------------------------------------------------------------------- diff --git a/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy b/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy deleted file mode 100644 index 99e7f8d..0000000 --- a/src/spec/test/gdk/WorkingWithDateTimeTypesTest.groovy +++ /dev/null @@ -1,222 +0,0 @@ -package gdk - -import java.time.* -import java.time.chrono.JapaneseDate -import java.time.temporal.ChronoField -import java.time.temporal.ChronoUnit - -class WorkingWithDateTimeTypesTest extends GroovyTestCase { - - void testParsing() { - // tag::static_parsing[] - def date = LocalDate.parse('Jun 3, 04','MMM d, yy') - assert date == LocalDate.of(2004, Month.JUNE, 3) - - def time = LocalTime.parse('4:45','H:mm') - assert time == LocalTime.of(4, 45, 0) - - def offsetTime = OffsetTime.parse('09:47:51-1234', 'HH:mm:ssZ') - assert offsetTime == OffsetTime.of(9, 47, 51, 0, ZoneOffset.ofHoursMinutes(-12, -34)) - - def dateTime = ZonedDateTime.parse('2017/07/11 9:47PM Pacific Standard Time', 'yyyy/MM/dd h:mma zzzz') - assert dateTime == ZonedDateTime.of( - LocalDate.of(2017, 7, 11), - LocalTime.of(21, 47, 0), - ZoneId.of('America/Los_Angeles') - ) - // end::static_parsing[] - } - - void testRange() { - // tag::date_ranges[] - def start = LocalDate.now() - def end = start + 6 // 6 days later - (start..end).each { date -> - println date.dayOfWeek - } - // end::date_ranges[] - } - - void testUptoDownto() { - // tag::date_upto_date[] - def start = LocalDate.now() - def end = start + 6 // 6 days later - start.upto(end) { date -> - println date.dayOfWeek - } - // end::date_upto_date[] - } - - void testUptoCustomUnit() { - // tag::date_upto_date_by_months[] - def start = LocalDate.of(2018, Month.MARCH, 2) - def end = start + 1 // 1 day later - - int iterationCount = 0 - start.upto(end, ChronoUnit.MONTHS) { date -> - println date - ++iterationCount - } - - assert iterationCount == 1 - // end::date_upto_date_by_months[] - } - - void testPlusMinusWithTemporalAmounts() { - // tag::plus_minus_period[] - def aprilFools = LocalDate.of(2018, Month.APRIL, 1) - - def nextAprilFools = aprilFools + Period.ofDays(365) // add 365 days - assert nextAprilFools.year == 2019 - - def idesOfMarch = aprilFools - Period.ofDays(17) // subtract 17 days - assert idesOfMarch.dayOfMonth == 15 - assert idesOfMarch.month == Month.MARCH - // end::plus_minus_period[] - } - - void testLocalDatePlusMinusInteger() { - def aprilFools = LocalDate.of(2018, Month.APRIL, 1) - - // tag::localdate_plus_minus_integer[] - def nextAprilFools = aprilFools + 365 // add 365 days - def idesOfMarch = aprilFools - 17 // subtract 17 days - // end::localdate_plus_minus_integer[] - - assert nextAprilFools.year == 2019 - assert idesOfMarch.dayOfMonth == 15 - assert idesOfMarch.month == Month.MARCH - } - - void testLocalTimePlusMinusInteger() { - // tag::localtime_plus_minus_integer[] - def mars = LocalTime.of(12, 34, 56) // 12:34:56 pm - - def thirtySecondsToMars = mars - 30 // go back 30 seconds - assert thirtySecondsToMars.second == 26 - // end::localtime_plus_minus_integer[] - } - - void testNextPrevious() { - // tag::next_previous[] - def year = Year.of(2000) - --year // decrement by one year - assert year.value == 1999 - - def offsetTime = OffsetTime.of(0, 0, 0, 0, ZoneOffset.UTC) // 00:00:00.000 UTC - offsetTime++ // increment by one second - assert offsetTime.second == 1 - // end::next_previous[] - } - - void testMultiplyDivide() { - // tag::multiply_divide[] - def period = Period.ofMonths(1) * 2 // a 1-month period times 2 - assert period.months == 2 - - def duration = Duration.ofSeconds(10) / 5// a 10-second duration divided by 5 - assert duration.seconds == 2 - // end::multiply_divide[] - } - - void testNegation() { - // tag::duration_negation[] - def duration = Duration.ofSeconds(-15) - def negated = -duration - assert negated.seconds == 15 - // end::duration_negation[] - } - - void testPropertyNotation() { - // tag::property_notation[] - def date = LocalDate.of(2018, Month.MARCH, 12) - assert date[ChronoField.YEAR] == 2018 - assert date[ChronoField.MONTH_OF_YEAR] == Month.MARCH.value - assert date[ChronoField.DAY_OF_MONTH] == 12 - assert date[ChronoField.DAY_OF_WEEK] == DayOfWeek.MONDAY.value - - def period = Period.ofYears(2).withMonths(4).withDays(6) - assert period[ChronoUnit.YEARS] == 2 - assert period[ChronoUnit.MONTHS] == 4 - assert period[ChronoUnit.DAYS] == 6 - // end::property_notation[] - } - - void testLeftShift() { - // tag::leftshift_operator[] - MonthDay monthDay = Month.JUNE << 3 // June 3rd - LocalDate date = monthDay << Year.of(2015) // 3-Jun-2015 - LocalDateTime dateTime = date << LocalTime.NOON // 3-Jun-2015 @ 12pm - OffsetDateTime offsetDateTime = dateTime << ZoneOffset.ofHours(-5) // 3-Jun-2015 @ 12pm UTC-5 - // end::leftshift_operator[] - // tag::leftshift_operator_reflexive[] - def year = Year.of(2000) - def month = Month.DECEMBER - - YearMonth a = year << month - YearMonth b = month << year - assert a == b - // end::leftshift_operator_reflexive[] - } - - void testRightShift() { - // tag::rightshift_operator_period[] - def newYears = LocalDate.of(2018, Month.JANUARY, 1) - def aprilFools = LocalDate.of(2018, Month.APRIL, 1) - - def period = newYears >> aprilFools - assert period instanceof Period - assert period.months == 3 - // end::rightshift_operator_period[] - - // tag::rightshift_operator_duration[] - def duration = LocalTime.NOON >> (LocalTime.NOON + 30) - assert duration instanceof Duration - assert duration.seconds == 30 - // end::rightshift_operator_duration[] - - // tag::rightshift_operator_negative[] - def decade = Year.of(2010) >> Year.of(2000) - assert decade.years == -10 - // end::rightshift_operator_negative[] - } - - void testToDateAndToCalendar() { - // tag::todate_tocalendar[] - // LocalDate to java.util.Date - def valentines = LocalDate.of(2018, Month.FEBRUARY, 14) - assert valentines.toDate().format('MMMM dd, yyyy') == 'February 14, 2018' - - // LocalTime to java.util.Date - def noon = LocalTime.of(12, 0, 0) - assert noon.toDate().format('HH:mm:ss') == '12:00:00' - - // ZoneId to java.util.TimeZone - def newYork = ZoneId.of('America/New_York') - assert newYork.toTimeZone() == TimeZone.getTimeZone('America/New_York') - - // ZonedDateTime to java.util.Calendar - def valAtNoonInNY = ZonedDateTime.of(valentines, noon, newYork) - assert valAtNoonInNY.toCalendar().getTimeZone().toZoneId() == newYork - // end::todate_tocalendar[] - } - - void testConvertToJSR310Types() { - // tag::to_jsr310_types[] - Date legacy = Date.parse('yyyy-MM-dd HH:mm:ss.SSS', '2010-04-03 10:30:58.999') - - assert legacy.toLocalDate() == LocalDate.of(2010, 4, 3) - assert legacy.toLocalTime() == LocalTime.of(10, 30, 58, 999_000_000) // 999M ns = 999ms - assert legacy.toOffsetTime().hour == 10 - assert legacy.toYear() == Year.of(2010) - assert legacy.toMonth() == Month.APRIL - assert legacy.toDayOfWeek() == DayOfWeek.SATURDAY - assert legacy.toMonthDay() == MonthDay.of(Month.APRIL, 3) - assert legacy.toYearMonth() == YearMonth.of(2010, Month.APRIL) - assert legacy.toLocalDateTime().year == 2010 - assert legacy.toOffsetDateTime().dayOfMonth == 3 - assert legacy.toZonedDateTime().zone == ZoneId.systemDefault() - // end::to_jsr310_types[] - } - -} http://git-wip-us.apache.org/repos/asf/groovy/blob/718a820a/src/test/groovy/DateTest.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/DateTest.groovy b/src/test/groovy/DateTest.groovy deleted file mode 100644 index 3c2034d..0000000 --- a/src/test/groovy/DateTest.groovy +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy - -import java.text.SimpleDateFormat - -import static java.util.Calendar.* - -class DateTest extends GroovyTestCase { - void testCalendarNextPrevious() { - TimeZone tz = TimeZone.getTimeZone('GMT+00') - Calendar c = getInstance(tz) - c[HOUR_OF_DAY] = 6 - c[YEAR] = 2002 - c[MONTH] = FEBRUARY - c[DATE] = 2 - c.clearTime() - def formatter = new SimpleDateFormat('dd-MMM-yyyy', Locale.US) - formatter.calendar.timeZone = tz - - assert formatter.format(c.previous().time) == '01-Feb-2002' - assert formatter.format(c.time) == '02-Feb-2002' - assert formatter.format(c.next().time) == '03-Feb-2002' - def dates = (c.previous()..c.next()).collect{ formatter.format(it.time) } - assert dates == ['01-Feb-2002', '02-Feb-2002', '03-Feb-2002'] - } - - void testDateNextPrevious() { - def tz = TimeZone.default - def x = new Date() - def y = x + 2 - assert x < y - def crossedDaylightSavingBoundary = tz.inDaylightTime(x) ^ tz.inDaylightTime(y) - ++x - --y - if (!crossedDaylightSavingBoundary) assert x == y - x += 2 - assert x > y - } - - void testDateRange() { - def today = new Date() - def later = today + 3 - def expected = [today, today + 1, today + 2, today + 3] - def list = [] - for (d in today..later) { - list << d - } - assert list == expected - } - - void testCalendarIndex() { - Calendar c = new GregorianCalendar(2002, FEBRUARY, 2) - assert c[MONTH] == FEBRUARY - assert c[DAY_OF_WEEK] == SATURDAY - } - - void testDateIndex() { - Date d = new GregorianCalendar(2002, FEBRUARY, 2).time - assert d[MONTH] == FEBRUARY - assert d[DAY_OF_WEEK] == SATURDAY - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/718a820a/src/test/groovy/DateTimeTest.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/DateTimeTest.groovy b/src/test/groovy/DateTimeTest.groovy deleted file mode 100644 index db2e266..0000000 --- a/src/test/groovy/DateTimeTest.groovy +++ /dev/null @@ -1,821 +0,0 @@ -package groovy - -import java.text.SimpleDateFormat -import java.time.* -import java.time.chrono.JapaneseDate -import java.time.temporal.ChronoField -import java.time.temporal.ChronoUnit - -class DateTimeTest extends GroovyTestCase { - - void testDurationPlusMinusPositiveNegative() { - def duration = Duration.ofSeconds(10) - def longer = duration + 5 - def shorter = duration - 5 - - assert longer.seconds == 15 - assert shorter.seconds == 5 - assert (++longer).seconds == 16 - assert (--shorter).seconds == 4 - } - - void testInstantPlusMinusPositiveNegative() { - def epoch = Instant.ofEpochMilli(0) - - def twoSecPastEpoch = epoch + 2 - def oneSecPastEpoch = twoSecPastEpoch - 1 - - assert oneSecPastEpoch.epochSecond == 1 - assert twoSecPastEpoch.epochSecond == 2 - assert (++twoSecPastEpoch).epochSecond == 3 - assert (--oneSecPastEpoch).epochSecond == 0 - } - - void testLocalDatePlusMinusPositiveNegative() { - def epoch = LocalDate.of(1970, Month.JANUARY, 1) - - def twoDaysPastEpoch = epoch + 2 - def oneDayPastEpoch = twoDaysPastEpoch - 1 - - assert oneDayPastEpoch.dayOfMonth == 2 - assert twoDaysPastEpoch.dayOfMonth == 3 - assert (++twoDaysPastEpoch).dayOfMonth == 4 - assert (--oneDayPastEpoch).dayOfMonth == 1 - } - - void testLocalDateTimePlusMinusPositiveNegative() { - def epoch = LocalDateTime.of(1970, Month.JANUARY, 1, 0, 0, 0, 0) - - def twoSecsPastEpoch = epoch + 2 - def oneSecPastEpoch = twoSecsPastEpoch - 1 - - assert oneSecPastEpoch.second == 1 - assert twoSecsPastEpoch.second == 2 - assert (++twoSecsPastEpoch).second == 3 - assert (--oneSecPastEpoch).second == 0 - } - - void testLocalTimePlusMinusPositiveNegative() { - def epoch = LocalTime.of(0, 0, 0, 0) - - def twoSecsPastEpoch = epoch + 2 - def oneSecPastEpoch = twoSecsPastEpoch - 1 - - assert oneSecPastEpoch.second == 1 - assert twoSecsPastEpoch.second == 2 - assert (++twoSecsPastEpoch).second == 3 - assert (--oneSecPastEpoch).second == 0 - } - - void testOffsetDateTimePlusMinusPositiveNegative() { - def epoch = OffsetDateTime.of(LocalDateTime.of(1970, Month.JANUARY, 1, 0, 0, 0, 0), - ZoneOffset.ofHours(0)) - - def twoSecsPastEpoch = epoch + 2 - def oneSecPastEpoch = twoSecsPastEpoch - 1 - - assert oneSecPastEpoch.second == 1 - assert twoSecsPastEpoch.second == 2 - assert (++twoSecsPastEpoch).second == 3 - assert (--oneSecPastEpoch).second == 0 - } - - void testOffsetTimePlusMinusPositiveNegative() { - def epoch = OffsetTime.of(LocalTime.of(0, 0, 0, 0), - ZoneOffset.ofHours(0)) - - def twoSecsPastEpoch = epoch + 2 - def oneSecPastEpoch = twoSecsPastEpoch - 1 - - assert oneSecPastEpoch.second == 1 - assert twoSecsPastEpoch.second == 2 - assert (++twoSecsPastEpoch).second == 3 - assert (--oneSecPastEpoch).second == 0 - } - - void testPeriodPlusMinusPositiveNegative() { - def fortnight = Period.ofDays(14) - - def fortnightAndTwoDays = fortnight + 2 - def fortnightAndOneDay = fortnightAndTwoDays - 1 - - assert fortnightAndOneDay.days == 15 - assert fortnightAndTwoDays.days == 16 - assert (++fortnightAndTwoDays).days == 17 - assert (--fortnightAndOneDay).days == 14 - } - - void testYearPlusMinusPositiveNegative() { - def epoch = Year.of(1970) - - def twoYearsAfterEpoch = epoch + 2 - def oneYearAfterEpoch = twoYearsAfterEpoch - 1 - - assert oneYearAfterEpoch.value == 1971 - assert twoYearsAfterEpoch.value == 1972 - assert (++twoYearsAfterEpoch).value == 1973 - assert (--oneYearAfterEpoch).value == 1970 - } - - void testYearMonthPlusMinusPositiveNegative() { - def epoch = YearMonth.of(1970, Month.JANUARY) - - def twoMonthsAfterEpoch = epoch + 2 - def oneMonthAfterEpoch = twoMonthsAfterEpoch - 1 - - assert oneMonthAfterEpoch.month == Month.FEBRUARY - assert twoMonthsAfterEpoch.month == Month.MARCH - assert (++twoMonthsAfterEpoch).month == Month.APRIL - assert (--oneMonthAfterEpoch).month == Month.JANUARY - } - - void testZonedDateTimePlusMinusPositiveNegative() { - def epoch = ZonedDateTime.of(LocalDateTime.of(1970, Month.JANUARY, 1, 0, 0, 0, 0), - ZoneId.systemDefault()) - - def twoSecsPastEpoch = epoch + 2 - def oneSecPastEpoch = twoSecsPastEpoch - 1 - - assert oneSecPastEpoch.second == 1 - assert twoSecsPastEpoch.second == 2 - assert (++twoSecsPastEpoch).second == 3 - assert (--oneSecPastEpoch).second == 0 - } - - void testDayOfWeekPlusMinus() { - def mon = DayOfWeek.MONDAY - - assert mon + 4 == DayOfWeek.FRIDAY - assert mon - 4 == DayOfWeek.THURSDAY - } - - void testMonthPlusMinus() { - def jan = Month.JANUARY - - assert jan + 4 == Month.MAY - assert jan - 4 == Month.SEPTEMBER - } - - void testDurationPositiveNegative() { - def positiveDuration = Duration.ofSeconds(3) - assert (-positiveDuration).seconds == -3 - - def negativeDuration = Duration.ofSeconds(-5) - assert (+negativeDuration).seconds == 5 - } - - void testDurationMultiplyDivide() { - def duration = Duration.ofSeconds(60) - - assert (duration / 2).seconds == 30 - assert (duration * 2).seconds == 120 - } - - void testDurationIsPositiveIsNonnegativeIsNonpositive() { - def pos = Duration.ofSeconds(10) - assert pos.isPositive() == true - assert pos.isNonpositive() == false - assert pos.isNonnegative() == true - - def neg = Duration.ofSeconds(-10) - assert neg.isPositive() == false - assert neg.isNonpositive() == true - assert neg.isNonnegative() == false - - assert Duration.ZERO.isPositive() == false - assert Duration.ZERO.isNonpositive() == true - assert Duration.ZERO.isNonnegative() == true - } - - void testPeriodPositiveNegative() { - def positivePeriod = Period.of(1,2,3) - Period madeNegative = -positivePeriod - assert madeNegative.years == -1 : "All Period fields should be made negative" - assert madeNegative.months == -2 - assert madeNegative.days == -3 - - def negativePeriod = Period.of(-1,2,-3) - Period madePositive = +negativePeriod - assert madePositive.years == 1 : "Negative Period fields should be made positive" - assert madePositive.months == 2 : "Positive Period fields should remain positive" - assert madePositive.days == 3 - } - - void testPeriodMultiply() { - def period = Period.of(1,1,1) - Period doublePeriod = period * 2 - assert doublePeriod.years == 2 - assert doublePeriod.months == 2 - assert doublePeriod.days == 2 - } - - void testPeriodIsPositiveIsNonnegativeIsNonpositive() { - def pos = Period.ofDays(10) - assert pos.isPositive() == true - assert pos.isNonpositive() == false - assert pos.isNonnegative() == true - - def neg = Period.ofDays(-10) - assert neg.isPositive() == false - assert neg.isNonpositive() == true - assert neg.isNonnegative() == false - - assert Period.ZERO.isPositive() == false - assert Period.ZERO.isNonpositive() == true - assert Period.ZERO.isNonnegative() == true - } - - void testTemporalGetAt() { - def epoch = Instant.ofEpochMilli(0) - assert epoch[ChronoField.INSTANT_SECONDS] == 0 - } - - void testTemporalAmountGetAt() { - def duration = Duration.ofHours(10) - assert duration[ChronoUnit.SECONDS] == 36_000 - } - - void testZoneOffsetGetAt() { - def offset = ZoneOffset.ofTotalSeconds(360) - assert offset[ChronoField.OFFSET_SECONDS] == 360 - } - - void testTemporalRightShift() { - def epoch = Instant.ofEpochMilli(0) - def dayAfterEpoch = epoch + (60 * 60 * 24) - Duration instantDuration = epoch >> dayAfterEpoch - assert instantDuration == Duration.ofDays(1) - } - - void testLocalDateRightShift() { - def localDate1 = LocalDate.of(2000, Month.JANUARY, 1) - def localDate2 = localDate1.plusYears(2) - Period localDatePeriod = localDate1 >> localDate2 - assert localDatePeriod.years == 2 - } - - void testYearRightShift() { - def year1 = Year.of(2000) - def year2 = Year.of(2018) - Period yearPeriod = year1 >> year2 - assert yearPeriod.years == 18 - } - - void testYearMonthRightShift() { - def yearMonth1 = YearMonth.of(2018, Month.JANUARY) - def yearMonth2 = YearMonth.of(2018, Month.MARCH) - Period yearMonthPeriod = yearMonth1 >> yearMonth2 - assert yearMonthPeriod.months == 2 - } - - void testRightShiftDifferentTypes() { - try { - LocalDate.now() >> LocalTime.now() - fail('Should not be able to use right shift on different Temporal types.') - } catch (e) { - assert e instanceof GroovyRuntimeException - } - } - - void testUptoDifferentTypes() { - try { - LocalDate.now().upto(JapaneseDate.now().plus(1, ChronoUnit.MONTHS)) { d -> } - fail('Cannot use upto() with two different Temporal types.') - } catch (e) { - assert e instanceof GroovyRuntimeException - } - } - - void testDowntoDifferentTypes() { - try { - LocalDate.now().downto(JapaneseDate.now().minus(1, ChronoUnit.MONTHS)) { d -> } - fail('Cannot use downto() with two different argument types.') - } catch (e) { - assert e instanceof GroovyRuntimeException - } - } - - void testUptoSelfWithDefaultUnit() { - def epoch = Instant.ofEpochMilli(0) - - int iterations = 0 - epoch.upto(epoch) { - ++iterations - assert it == epoch: 'upto closure should be provided with arg' - } - assert iterations == 1: 'Iterating upto same value should call closure once' - } - - void testDowntoSelfWithDefaultUnit() { - def epoch = Instant.ofEpochMilli(0) - int iterations = 0 - epoch.downto(epoch) { - ++iterations - assert it == epoch: 'downto closure should be provided with arg' - } - assert iterations == 1: 'Iterating downto same value should call closure once' - } - - void testUptoWithSecondsDefaultUnit() { - def epoch = Instant.ofEpochMilli(0) - - int iterations = 0 - Instant end = null - epoch.upto(epoch + 1) { - ++iterations - end = it - } - assert iterations == 2: 'Iterating upto Temporal+1 value should call closure twice' - assert end.epochSecond == 1: 'Unexpected upto final value' - } - - void testDowntoWithSecondsDefaultUnit() { - def epoch = Instant.ofEpochMilli(0) - - int iterations = 0 - Instant end = null - epoch.downto(epoch - 1) { - ++iterations - end = it - } - assert iterations == 2 : 'Iterating downto Temporal+1 value should call closure twice' - assert end.epochSecond == -1 : 'Unexpected downto final value' - } - - void testUptoWithYearsDefaultUnit() { - def endYear = null - Year.of(1970).upto(Year.of(1971)) { year -> endYear = year } - assert endYear.value == 1971 - } - - void testDowntoWithYearsDefaultUnit() { - def endYear = null - Year.of(1971).downto(Year.of(1970)) { year -> endYear = year } - assert endYear.value == 1970 - } - - void testUptoWithMonthsDefaultUnit() { - def endYearMonth = null - YearMonth.of(1970, Month.JANUARY).upto(YearMonth.of(1970, Month.FEBRUARY)) { yearMonth -> - endYearMonth = yearMonth - } - assert endYearMonth.month == Month.FEBRUARY - } - - void testDowntoWithMonthsDefaultUnit() { - def endYearMonth = null - YearMonth.of(1970, Month.FEBRUARY).downto(YearMonth.of(1970, Month.JANUARY)) { yearMonth -> - endYearMonth = yearMonth - } - assert endYearMonth.month == Month.JANUARY - } - - void testUptoWithDaysDefaultUnit() { - def endLocalDate = null - LocalDate.of(1970, Month.JANUARY, 1).upto(LocalDate.of(1970, Month.JANUARY, 2)) { localDate -> - endLocalDate = localDate - } - assert endLocalDate.dayOfMonth == 2 - } - - void testDowntoWithDaysDefaultUnit() { - def endLocalDate = null - LocalDate.of(1970, Month.JANUARY, 2).downto(LocalDate.of(1970, Month.JANUARY, 1)) { localDate -> - endLocalDate = localDate - } - assert endLocalDate.dayOfMonth == 1 - } - - void testUptoWithIllegalReversedArguments() { - def epoch = Instant.ofEpochMilli(0) - try { - epoch.upto(epoch - 1) { - fail('upto() should fail when passed earlier arg') - } - } catch (GroovyRuntimeException e) { - } - } - - void testDowntoWithIllegalReversedArguments() { - def epoch = Instant.ofEpochMilli(0) - try { - epoch.downto(epoch + 1) { - fail('downto() should fail when passed earlier arg') - } - } catch (GroovyRuntimeException e) {} - } - - void testUptoSelfWithCustomUnit() { - def today = LocalDate.now() - - int iterations = 0 - today.upto(today, ChronoUnit.MONTHS) { - ++iterations - assert it == today: 'upto closure should be provided with arg' - } - assert iterations == 1: 'Iterating upto same value should call closure once' - } - - void testDowntoSelfWithCustomUnit() { - def today = LocalDate.now() - - int iterations = 0 - today.downto(today, ChronoUnit.MONTHS) { - ++iterations - assert it == today: 'downto closure should be provided with arg' - } - assert iterations == 1: 'Iterating downto same value should call closure once' - } - - void testUptoWithCustomUnit() { - LocalDateTime from = LocalDateTime.of(2018, Month.FEBRUARY, 11, 22, 9, 34) - // one second beyond one iteration - LocalDateTime to = from.plusDays(1).plusSeconds(1) - - int iterations = 0 - LocalDateTime end = null - from.upto(to, ChronoUnit.DAYS) { - ++iterations - end = it - } - assert iterations == 2 - assert end.dayOfMonth == 12: "Upto should have iterated by DAYS twice" - } - - void testDowntoWithCustomUnit() { - LocalDateTime from = LocalDateTime.of(2018, Month.FEBRUARY, 11, 22, 9, 34) - // one day beyond one iteration - LocalDateTime to = from.minusYears(1).minusDays(1) - - int iterations = 0 - LocalDateTime end = null - from.downto(to, ChronoUnit.YEARS) { - ++iterations - end = it - } - assert iterations == 2 - assert end.year == 2017 : "Downto should have iterated by YEARS twice" - } - - void testInstantToDateToCalendar() { - def epoch = Instant.ofEpochMilli(0).plusNanos(999_999) - - def date = epoch.toDate() - def cal = epoch.toCalendar() - assert cal.time == date - def sdf = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss.SSS') - sdf.timeZone = TimeZone.getTimeZone('GMT') - assert sdf.format(date) == '1970-01-01 00:00:00.000' - } - - void testLocalDateToDateToCalendar() { - def ld = LocalDate.of(2018, Month.FEBRUARY, 12) - - Calendar cal = ld.toCalendar() - assert cal.get(Calendar.YEAR) == 2018 - assert cal.get(Calendar.MONTH) == Calendar.FEBRUARY - assert cal.get(Calendar.DAY_OF_MONTH) == 12 - assert cal.timeZone.getID() == TimeZone.default.getID() - - Date date = ld.toDate() - assert date.format('yyyy-MM-dd') == '2018-02-12' - } - - void testLocalDateTimeToDateToCalendar() { - def ldt = LocalDateTime.of(2018, Month.FEBRUARY, 12, 22, 26, 30, 123_999_999) - - Calendar cal = ldt.toCalendar() - assert cal.get(Calendar.YEAR) == 2018 - assert cal.get(Calendar.MONTH) == Calendar.FEBRUARY - assert cal.get(Calendar.DAY_OF_MONTH) == 12 - assert cal.get(Calendar.HOUR_OF_DAY) == 22 - assert cal.get(Calendar.MINUTE) == 26 - assert cal.get(Calendar.SECOND) == 30 - assert cal.get(Calendar.MILLISECOND) == 123 - assert cal.timeZone.getID() == TimeZone.default.getID() - - Date date = ldt.toDate() - assert date.format('yyyy-MM-dd HH:mm:ss.SSS') == '2018-02-12 22:26:30.123' - } - - void testLocalTimeToDateToCalendar() { - def today = Calendar.instance - def lt = LocalTime.of(22, 38, 20, 9_999_999) - - Calendar cal = lt.toCalendar() - assert cal.get(Calendar.YEAR) == today.get(Calendar.YEAR) : 'LocalTime.toCalendar() should have current year' - assert cal.get(Calendar.MONTH) == today.get(Calendar.MONTH) : 'LocalTime.toCalendar() should have current month' - assert cal.get(Calendar.DAY_OF_MONTH) == today.get(Calendar.DAY_OF_MONTH) : 'LocalTime.toCalendar() should have current day' - assert cal.get(Calendar.HOUR_OF_DAY) == 22 - assert cal.get(Calendar.MINUTE) == 38 - assert cal.get(Calendar.SECOND) == 20 - assert cal.get(Calendar.MILLISECOND) == 9 - assert cal.timeZone.getID() == TimeZone.default.getID() - - Date date = lt.toDate() - assert date.format('HH:mm:ss.SSS') == '22:38:20.009' - } - - void testOffsetDateTimeToDateToCalendar() { - def ld = LocalDate.of(2018, Month.FEBRUARY, 12) - def lt = LocalTime.of(22, 46, 10, 16_000_001) - def offset = ZoneOffset.ofHours(-5) - def odt = OffsetDateTime.of(ld, lt, offset) - - Calendar cal = odt.toCalendar() - assert cal.get(Calendar.YEAR) == 2018 - assert cal.get(Calendar.MONTH) == Calendar.FEBRUARY - assert cal.get(Calendar.DAY_OF_MONTH) == 12 - assert cal.get(Calendar.HOUR_OF_DAY) == 22 - assert cal.get(Calendar.MINUTE) == 46 - assert cal.get(Calendar.SECOND) == 10 - assert cal.get(Calendar.MILLISECOND) == 16 - assert cal.timeZone.getOffset(System.currentTimeMillis()) == -5 * 60 * 60 * 1000 - - Date date = odt.toDate() - def sdf = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss.SSS Z') - sdf.timeZone = cal.timeZone - assert sdf.format(date) == '2018-02-12 22:46:10.016 -0500' - } - - void testOffsetTimeToDateToCalendar() { - def lt = LocalTime.of(22, 53, 2, 909_900_009) - def offset = ZoneOffset.ofHours(-4) - def ot = OffsetTime.of(lt, offset) - Calendar today = Calendar.getInstance(TimeZone.getTimeZone('GMT-4')) - - Calendar cal = ot.toCalendar() - assert cal.get(Calendar.YEAR) == today.get(Calendar.YEAR) : 'OffsetTime.toCalendar() should have current year' - assert cal.get(Calendar.MONTH) == today.get(Calendar.MONTH) : 'OffsetTime.toCalendar() should have current month' - assert cal.get(Calendar.DAY_OF_MONTH) == today.get(Calendar.DAY_OF_MONTH) : 'OffsetTime.toCalendar() should have current day' - assert cal.get(Calendar.HOUR_OF_DAY) == 22 - assert cal.get(Calendar.MINUTE) == 53 - assert cal.get(Calendar.SECOND) == 2 - assert cal.get(Calendar.MILLISECOND) == 909 - assert cal.timeZone.getOffset(System.currentTimeMillis()) == -4 * 60 * 60 * 1000 - - Date date = ot.toDate() - def sdf = new SimpleDateFormat('HH:mm:ss.SSS Z') - sdf.timeZone = cal.timeZone - assert sdf.format(date) == '22:53:02.909 -0400' - } - - void testZonedDateTimeToDateToCalendar() { - def ldt = LocalDateTime.of(2018, Month.FEBRUARY, 13, 20, 33, 57) - def zoneId = ZoneId.ofOffset('GMT', ZoneOffset.ofHours(3)) - def zdt = ZonedDateTime.of(ldt, zoneId) - - Calendar cal = zdt.toCalendar() - assert cal.get(Calendar.YEAR) == 2018 - assert cal.get(Calendar.MONTH) == Calendar.FEBRUARY - assert cal.get(Calendar.DAY_OF_MONTH) == 13 - assert cal.get(Calendar.HOUR_OF_DAY) == 20 - assert cal.get(Calendar.MINUTE) == 33 - assert cal.get(Calendar.SECOND) == 57 - assert cal.get(Calendar.MILLISECOND) == 0 - assert cal.timeZone.getOffset(System.currentTimeMillis()) == 3 * 60 * 60 * 1000 - - Date date = zdt.toDate() - def sdf = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss.SSS Z') - sdf.timeZone = cal.timeZone - assert sdf.format(date) == '2018-02-13 20:33:57.000 +0300' - } - - void testZoneOffsetExtensionProperties() { - def offset = ZoneOffset.ofHoursMinutesSeconds(3,4,5) - assert offset.hours == 3 - assert offset.minutes == 4 - assert offset.seconds == 5 - - def negOffset = ZoneOffset.ofHoursMinutesSeconds(-1, -2, -3) - assert negOffset.hours == -1 - assert negOffset.minutes == -2 - assert negOffset.seconds == -3 - } - - void testZoneOffsetToZimeZone() { - TimeZone utcTz = ZoneOffset.UTC.toTimeZone() - assert utcTz.getID() == 'GMT' - - TimeZone noSecsTz = ZoneOffset.ofHoursMinutes(1, 30).toTimeZone() - assert noSecsTz.getID() == 'GMT+01:30' - - TimeZone secsTz = ZoneOffset.ofHoursMinutesSeconds(-4, -15, -30).toTimeZone() - assert secsTz.getID() == 'GMT-04:15' - } - - void testZoneIdExtensionProperties() { - def offset = ZoneOffset.ofHours(7) - def zoneId = ZoneId.ofOffset('GMT', offset) - - assert zoneId.offset.totalSeconds == offset.totalSeconds - assert zoneId.getOffset(Instant.now()).totalSeconds == offset.totalSeconds - assert zoneId.shortName == 'GMT+07:00' - assert zoneId.fullName == 'GMT+07:00' - - ZoneId ny = ZoneId.of('America/New_York') - assert ny.getShortName(Locale.US) == 'ET' - assert ny.getFullName(Locale.US) == 'Eastern Time' - } - - void testZoneIdToTimeZone() { - ZoneId ny = ZoneId.of('America/New_York') - - assert ny.toTimeZone() == TimeZone.getTimeZone(ny) - } - - void testYearExtensionProperties() { - def year = Year.of(2009) - assert year.era == 1 - assert year.yearOfEra == 2009 - } - - void testDayOfWeekExtensionProperties() { - assert DayOfWeek.SUNDAY.weekend - assert DayOfWeek.MONDAY.weekday - } - - void testYear_Month_leftShift() { - def a = Year.now() - def b = Month.JULY - - YearMonth x = a << b - YearMonth y = b << a - assert x == y - } - - void testYear_MonthDay_leftShift() { - def a = Year.now() - def b = MonthDay.now() - - LocalDate x = a << b - LocalDate y = b << a - assert x == y - } - - void testMonthDay_leftShift() { - LocalDate d = MonthDay.of(Month.FEBRUARY, 13) << 2018 - assert d.year == 2018 - assert d.month == Month.FEBRUARY - assert d.dayOfMonth == 13 - } - - void testMonth_leftShift() { - MonthDay md = Month.JANUARY << 10 - assert md.month == Month.JANUARY - assert md.dayOfMonth == 10 - } - - void testLocalDate_LocalTime_leftShift() { - def a = LocalDate.now() - def b = LocalTime.now() - - LocalDateTime x = a << b - LocalDateTime y = b << a - assert x == y - } - - void testLocalDate_OffsetTime_leftShift() { - def a = LocalDate.now() - def b = OffsetTime.now() - - OffsetDateTime x = a << b - OffsetDateTime y = b << a - assert x == y - } - - void testLocalDateTime_ZoneOffset_leftShift() { - def a = LocalDateTime.now() - def b = ZoneOffset.ofHours(5) - - OffsetDateTime x = a << b - OffsetDateTime y = b << a - assert x == y - } - - void testLocalDateTime_ZoneId_leftShift() { - def a = LocalDateTime.now() - def b = ZoneId.systemDefault() - - ZonedDateTime x = a << b - ZonedDateTime y = b << a - assert x == y - } - - void testLocalTime_ZoneOffset_leftShift() { - def a = LocalTime.now() - def b = ZoneOffset.ofHours(5) - - OffsetTime x = a << b - OffsetTime y = b << a - assert x == y - } - - void testLocalDateTimeClearTime() { - def d = LocalDateTime.of(LocalDate.now(), LocalTime.of(8, 9, 10, 100_032)) - d = d.clearTime() - - assert d.hour == 0 - assert d.minute == 0 - assert d.second == 0 - assert d.nano == 0 - } - - void testOffsetDateTimeClearTime() { - def offset = ZoneOffset.ofHours(-1) - def d = OffsetDateTime.of(LocalDate.now(), LocalTime.of(8, 9, 10, 100_032), offset) - d = d.clearTime() - - assert d.hour == 0 - assert d.minute == 0 - assert d.second == 0 - assert d.nano == 0 - assert d.offset == offset : 'cleartTime() should not change offset' - } - - void testZonedDateTimeClearTime() { - def zone = ZoneId.of('America/New_York') - def d = ZonedDateTime.of(LocalDate.now(), LocalTime.of(8, 9, 10, 100_032), zone) - d = d.clearTime() - - assert d.hour == 0 - assert d.minute == 0 - assert d.second == 0 - assert d.nano == 0 - assert d.zone == zone : 'cleartTime() should not change zone' - } - - void testFormatByPattern() { - def zone = ZoneId.of('America/New_York') - def offset = ZoneOffset.ofHours(2) - - LocalDate ld = LocalDate.of(2018, Month.FEBRUARY, 13) - LocalTime lt = LocalTime.of(3,4,5,6_000_000) - LocalDateTime ldt = LocalDateTime.of(ld, lt) - OffsetTime ot = OffsetTime.of(lt, offset) - OffsetDateTime odt = OffsetDateTime.of(ldt, offset) - ZonedDateTime zdt = ZonedDateTime.of(ldt, zone) - - assert ld.format('yyyy-MM-dd') == '2018-02-13' - assert lt.format('HH:mm:ss.SSS') == '03:04:05.006' - assert ldt.format('yyyy-MM-dd HH:mm:ss.SSS') == '2018-02-13 03:04:05.006' - assert ot.format('HH:mm:ss.SSS Z') == '03:04:05.006 +0200' - assert odt.format('yyyy-MM-dd HH:mm:ss.SSS Z') == '2018-02-13 03:04:05.006 +0200' - assert zdt.format('yyyy-MM-dd HH:mm:ss.SSS VV') == '2018-02-13 03:04:05.006 America/New_York' - } - - void testLocalDateParse() { - LocalDate ld = LocalDate.parse('2018-02-15', 'yyyy-MM-dd') - assert [ld.year, ld.month, ld.dayOfMonth] == [2018, Month.FEBRUARY, 15] - } - - void testLocalDateTimeParse() { - LocalDateTime ldt = LocalDateTime.parse('2018-02-15 21:43:03.002', 'yyyy-MM-dd HH:mm:ss.SSS') - assert [ldt.year, ldt.month, ldt.dayOfMonth] == [2018, Month.FEBRUARY, 15] - assert [ldt.hour, ldt.minute, ldt.second] == [21, 43, 03] - assert ldt.nano == 2 * 1e6 - } - - void testLocalTimeParse() { - LocalTime lt = LocalTime.parse('21:43:03.002', 'HH:mm:ss.SSS') - assert [lt.hour, lt.minute, lt.second] == [21, 43, 03] - assert lt.nano == 2 * 1e6 - } - - void testOffsetDateTimeParse() { - OffsetDateTime odt = OffsetDateTime.parse('2018-02-15 21:43:03.002 -00', 'yyyy-MM-dd HH:mm:ss.SSS X') - assert [odt.year, odt.month, odt.dayOfMonth] == [2018, Month.FEBRUARY, 15] - assert [odt.hour, odt.minute, odt.second] == [21, 43, 03] - assert odt.nano == 2 * 1e6 - assert odt.offset.totalSeconds == 0 - } - - void testOffsetTimeParse() { - OffsetTime ot = OffsetTime.parse('21:43:03.002 -00', 'HH:mm:ss.SSS X') - assert [ot.hour, ot.minute, ot.second] == [21, 43, 03] - assert ot.nano == 2 * 1e6 - assert ot.offset.totalSeconds == 0 - } - - void testZonedDateTimeParse() { - ZonedDateTime zdt = ZonedDateTime.parse('2018-02-15 21:43:03.002 UTC', 'yyyy-MM-dd HH:mm:ss.SSS z') - assert [zdt.year, zdt.month, zdt.dayOfMonth] == [2018, Month.FEBRUARY, 15] - assert [zdt.hour, zdt.minute, zdt.second] == [21, 43, 03] - assert zdt.nano == 2 * 1e6 - } - - void testPeriodBetweenYears() { - def period = Period.between(Year.of(2000), Year.of(2010)) - assert period.years == 10 - assert period.months == 0 - assert period.days == 0 - } - - void testPeriodBetweenYearMonths() { - def period = Period.between(YearMonth.of(2018, Month.MARCH), YearMonth.of(2016, Month.APRIL)) - - assert period.years == -1 - assert period.months == -11 - assert period.days == 0 - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/718a820a/src/test/java/org/codehaus/groovy/runtime/DateGroovyMethodsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/codehaus/groovy/runtime/DateGroovyMethodsTest.java b/src/test/java/org/codehaus/groovy/runtime/DateGroovyMethodsTest.java deleted file mode 100644 index c182b12..0000000 --- a/src/test/java/org/codehaus/groovy/runtime/DateGroovyMethodsTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.codehaus.groovy.runtime; - -import org.junit.Test; - -import java.sql.Timestamp; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.*; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -import static org.junit.Assert.assertEquals; - -public class DateGroovyMethodsTest { - @Test - public void minus() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - assertEquals("20171231", sdf.format(DateGroovyMethods.minus(sdf.parse("20180101"), 1))); - } - - @Test - public void plus() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - assertEquals("20180101", sdf.format(DateGroovyMethods.plus(new Timestamp(sdf.parse("20171231").getTime()), 1))); - } - - @Test - public void next() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(sdf.parse("20171231")); - assertEquals("20180101", sdf.format(DateGroovyMethods.next(calendar).getTime())); - } - - @Test - public void previous() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(sdf.parse("20180101")); - assertEquals("20171231", sdf.format(DateGroovyMethods.previous(calendar).getTime())); - } - - @Test - public void calendarConversionsDefaultTimeZone() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss SSS"); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(sdf.parse("20180115 153256 001")); - - LocalDate expectedLocalDate = LocalDate.of(2018, Month.JANUARY, 15); - LocalTime expectedLocalTime = LocalTime.of(15, 32, 56, 1_000_000); - LocalDateTime expectedLocalDateTime = LocalDateTime.of(expectedLocalDate, expectedLocalTime); - - assertEquals("DayOfWeek", DayOfWeek.MONDAY, DateGroovyMethods.toDayOfWeek(calendar)); - assertEquals("Month", Month.JANUARY, DateGroovyMethods.toMonth(calendar)); - assertEquals("MonthDay", MonthDay.of(Month.JANUARY, 15), DateGroovyMethods.toMonthDay(calendar)); - assertEquals("YearMonth", YearMonth.of(2018, Month.JANUARY), DateGroovyMethods.toYearMonth(calendar)); - assertEquals("Year", Year.of(2018), DateGroovyMethods.toYear(calendar)); - assertEquals("LocalDate", expectedLocalDate, DateGroovyMethods.toLocalDate(calendar)); - assertEquals("LocalTime", expectedLocalTime, DateGroovyMethods.toLocalTime(calendar)); - assertEquals("LocalDateTime", expectedLocalDateTime, DateGroovyMethods.toLocalDateTime(calendar)); - assertEquals("OffsetTime", expectedLocalTime, DateGroovyMethods.toOffsetTime(calendar).toLocalTime()); - assertEquals("OffsetDateTime", expectedLocalDateTime, - DateGroovyMethods.toOffsetDateTime(calendar).toLocalDateTime()); - assertEquals("ZonedDateTime", expectedLocalDateTime, - DateGroovyMethods.toZonedDateTime(calendar).toLocalDateTime()); - } - - @Test - public void calendarConversionsDifferingTimeZones() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss SSS"); - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC+0")); - calendar.setTime(sdf.parse("20180115 153256 001")); - } - - @Test - public void sameCalendarAndDateConvertIdentically() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss SSS"); - Date date = sdf.parse("20180115 153256 001"); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(date); - - assertEquals("DayOfWeek", DateGroovyMethods.toDayOfWeek(calendar), DateGroovyMethods.toDayOfWeek(date)); - assertEquals("Month", DateGroovyMethods.toMonth(calendar), DateGroovyMethods.toMonth(date)); - assertEquals("MonthDay", DateGroovyMethods.toMonthDay(calendar), DateGroovyMethods.toMonthDay(date)); - assertEquals("YearMonth", DateGroovyMethods.toYearMonth(calendar), DateGroovyMethods.toYearMonth(date)); - assertEquals("Year", DateGroovyMethods.toYear(calendar), DateGroovyMethods.toYear(date)); - assertEquals("LocalDate", DateGroovyMethods.toLocalDate(calendar), DateGroovyMethods.toLocalDate(date)); - assertEquals("LocalTime", DateGroovyMethods.toLocalTime(calendar), DateGroovyMethods.toLocalTime(date)); - assertEquals("LocalDateTime", DateGroovyMethods.toLocalDate(calendar), DateGroovyMethods.toLocalDate(date)); - assertEquals("OffsetTime", DateGroovyMethods.toOffsetTime(calendar), DateGroovyMethods.toOffsetTime(date)); - assertEquals("OffsetDateTime", - DateGroovyMethods.toOffsetDateTime(calendar), DateGroovyMethods.toOffsetDateTime(date)); - assertEquals("ZonedDateTime", - DateGroovyMethods.toZonedDateTime(calendar), DateGroovyMethods.toZonedDateTime(date)); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/718a820a/src/test/org/codehaus/groovy/runtime/DateGDKTest.groovy ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/DateGDKTest.groovy b/src/test/org/codehaus/groovy/runtime/DateGDKTest.groovy deleted file mode 100644 index 2c27878..0000000 --- a/src/test/org/codehaus/groovy/runtime/DateGDKTest.groovy +++ /dev/null @@ -1,275 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.codehaus.groovy.runtime - -import java.text.DateFormat -import java.text.SimpleDateFormat - -/** - * @author tnichols - * @author Paul King - */ -class DateGDKTest extends GroovyTestCase { - - void testGDKDateMethods() { - Locale defaultLocale = Locale.default - TimeZone defaultTZ = TimeZone.default - try { - Locale locale = Locale.GERMANY - Locale.setDefault locale // set this otherwise the test will fail if your locale isn't the same - TimeZone.setDefault TimeZone.getTimeZone('Europe/Berlin') - - Date d = new Date(0) - - assertEquals '1970-01-01', d.format('yyyy-MM-dd') - assertEquals '01/01/1970', d.format('dd/MM/yyyy', TimeZone.getTimeZone('GMT')) - assertEquals DateFormat.getDateInstance(DateFormat.SHORT, locale).format(d), d.dateString - assertEquals '01.01.70', d.dateString - assertEquals DateFormat.getTimeInstance(DateFormat.MEDIUM, locale).format(d), d.timeString - assertEquals '01:00:00', d.timeString - assertEquals DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale).format(d), d.dateTimeString - } finally { - Locale.default = defaultLocale - TimeZone.setDefault defaultTZ - } - } - - void testStaticParse() { - TimeZone defaultTZ = TimeZone.default - try { - TimeZone.setDefault TimeZone.getTimeZone('Etc/GMT') - - Date d = Date.parse('yy/MM/dd hh:mm:ss', '70/01/01 00:00:00') - - assertEquals 0, d.time - } finally { - TimeZone.setDefault defaultTZ - } - } - - void testParseWithTimeZone() { - TimeZone defaultTZ = TimeZone.default - try { - TimeZone.default = TimeZone.getTimeZone("GMT+05") - def tz = TimeZone.getTimeZone("GMT+03") - - def newYear = Date.parse('yyyy-MM-dd', "2015-01-01", tz) - - assert newYear.toString() == 'Thu Jan 01 02:00:00 GMT+05:00 2015' - } finally { - TimeZone.default = defaultTZ - } - } - - void testRoundTrip() { - Date d = new Date() - String pattern = 'dd MMM yyyy, hh:mm:ss,SSS a z' - String out = d.format(pattern) - - Date d2 = Date.parse(pattern, out) - - assertEquals d.time, d2.time - } - - void testCalendarTimeZone() { - Locale defaultLocale = Locale.default - TimeZone defaultTZ = TimeZone.default - try { - Locale locale = Locale.UK - Locale.setDefault locale // set this otherwise the test will fail if your locale isn't the same - TimeZone.setDefault TimeZone.getTimeZone('Etc/GMT') - - def offset = 8 - def notLocalTZ = TimeZone.getTimeZone("GMT-$offset") - Calendar cal = Calendar.getInstance(notLocalTZ) - def offsetHr = cal.format('HH') as int - def hr = cal.time.format('HH') as int - if (hr < offset) hr += 24 // if GMT hr has rolled over to next day - - // offset should be 8 hours behind GMT: - assertEquals(offset, hr - offsetHr) - } finally { - Locale.default = defaultLocale - TimeZone.setDefault defaultTZ - } - } - - static SimpleDateFormat f = new SimpleDateFormat('MM/dd/yyyy') - - static java.sql.Date sqlDate(String s) { - return new java.sql.Date(f.parse(s).time) - } - - void testMinusDates() { - assertEquals(10, f.parse("1/11/2007") - f.parse("1/1/2007")) - assertEquals(-10, f.parse("1/1/2007") - f.parse("1/11/2007")) - assertEquals(375, f.parse("1/11/2008") - f.parse("1/1/2007")) - assertEquals(356, f.parse("1/1/2008") - f.parse("1/10/2007")) - assertEquals(1, f.parse("7/12/2007") - f.parse("7/11/2007")) - assertEquals(0, f.parse("1/1/2007") - f.parse("1/1/2007")) - assertEquals(-1, f.parse("12/31/2007") - f.parse("1/1/2008")) - assertEquals(365, f.parse("1/1/2008") - f.parse("1/1/2007")) - assertEquals(36525, f.parse("1/1/2008") - f.parse("1/1/1908")) - - assertEquals(1, sqlDate("7/12/2007") - f.parse("7/11/2007")) - assertEquals(0, sqlDate("1/1/2007") - sqlDate("1/1/2007")) - assertEquals(-1, f.parse("12/31/2007") - sqlDate("1/1/2008")) - assertEquals(365, sqlDate("1/1/2008") - sqlDate("1/1/2007")) - assertEquals(36525, f.parse("1/1/2008") - sqlDate("1/1/1908")) - - Date d = f.parse("7/4/1776"); - assertEquals(44, (d + 44) - d); - - java.sql.Date sqld = sqlDate("7/4/1776"); - assertEquals(-4444, (sqld - 4444) - sqld); - } - - /** GROOVY-3374 */ - void testClearTime() { - def now = new Date() - def calendarNow = Calendar.getInstance() - - now.clearTime() - calendarNow.clearTime() - - assert now == calendarNow.time - - assert calendarNow.get(Calendar.HOUR) == 0 - assert calendarNow.get(Calendar.MINUTE) == 0 - assert calendarNow.get(Calendar.SECOND) == 0 - assert calendarNow.get(Calendar.MILLISECOND) == 0 - } - - /** GROOVY-4789 */ - void testStaticParseToStringDate() { - TimeZone tz = TimeZone.getDefault() - try { - TimeZone.setDefault(TimeZone.getTimeZone("GMT")) - - Date date = new Date(0) - String toStringRepresentation = date.toString() - - assert toStringRepresentation == "Thu Jan 01 00:00:00 GMT 1970" - assert date == Date.parseToStringDate(toStringRepresentation) - } - finally { - TimeZone.setDefault(tz) - } - } - - void test_Upto_Date_ShouldExecuteClosureForEachDayUpToDate() { - Date startDate = new Date() - List expectedResults = [startDate, startDate + 1, startDate + 2] - - List actualResults = [] - - startDate.upto(startDate + 2){ - actualResults << it - } - - assert actualResults == expectedResults - } - - void test_upto_Date_ShouldNotAcceptToDatesLessThanStartDate() { - Date startDate = new Date() - Date toDate = new Date(startDate.getTime() - 1L) - - shouldFail(GroovyRuntimeException) { - startDate.upto(toDate){} - } - } - - void test_downto_Date_ShouldExecuteClosureForEachDayDownToDate() { - Date startDate = new Date() - List expectedResults = [startDate, startDate - 1, startDate - 2] - - List actualResults = [] - startDate.downto(startDate - 2){ - actualResults << it - } - - assert actualResults == expectedResults - } - - void test_downto_Date_ShouldNotAcceptToDatesGreaterThanStartDate() { - Date startDate = new Date() - Date toDate = new Date(startDate.getTime() + 1L) - - shouldFail(GroovyRuntimeException) { - startDate.downto(toDate){} - } - } - - void test_upto_Calendar_ShouldExecuteClosureForEachDayUpToDate() { - Calendar startDate = Calendar.getInstance() - Calendar toDate = startDate.clone() - toDate.add(Calendar.DATE, 1) - List expectedResults = [startDate, toDate] - - List actualResults = [] - startDate.upto(toDate){ - actualResults << it - } - - assert actualResults == expectedResults - } - - void test_upto_Calendar_ShouldNotAcceptToDatesLessThanStartDate() { - Calendar startDate = Calendar.getInstance() - Calendar toDate = startDate.clone() - toDate.add(Calendar.MILLISECOND, -1) - - shouldFail(GroovyRuntimeException) { - startDate.upto(toDate){} - } - } - - void test_downto_Calendar_ShouldExecuteClosureForEachDayDownToDate() { - Calendar startDate = Calendar.getInstance() - Calendar toDate = startDate.clone() - toDate.add(Calendar.DATE, -1) - List expectedResults = [startDate, toDate] - - List actualResults = [] - startDate.downto(toDate){ - actualResults << it - } - - assert actualResults == expectedResults - } - - void test_downto_Calendar_ShouldNotAcceptToDatesGreaterThanStartDate() { - Calendar startDate = Calendar.getInstance() - Calendar toDate = startDate.clone() - toDate.add(Calendar.MILLISECOND, 1) - - shouldFail(GroovyRuntimeException) { - startDate.downto(toDate){} - } - } - - void testCopyWith() { - Date febOne1970 = new Date(70, 1, 1) - Date aprilSix = febOne1970.copyWith(dayOfMonth: 6, month: Calendar.APRIL) - assertEquals '1970-04-06', aprilSix.format('yyyy-MM-dd') - Map updates = [:] - updates[Calendar.DAY_OF_MONTH] = 4 - Date aprilFour = aprilSix.copyWith(updates) - assertEquals '1970-04-04', aprilFour.format('yyyy-MM-dd') - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/718a820a/subprojects/groovy-datetime/build.gradle ---------------------------------------------------------------------- diff --git a/subprojects/groovy-datetime/build.gradle b/subprojects/groovy-datetime/build.gradle new file mode 100644 index 0000000..92326c7 --- /dev/null +++ b/subprojects/groovy-datetime/build.gradle @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +dependencies { + compile rootProject + testCompile project(':groovy-test') + testCompile project(':groovy-dateutil') +} + +task moduleDescriptor(type: org.codehaus.groovy.gradle.WriteExtensionDescriptorTask) { + extensionClasses = 'org.apache.groovy.datetime.extensions.DateTimeExtensions' + staticExtensionClasses = 'org.apache.groovy.datetime.extensions.DateTimeStaticExtensions' +} +compileJava.dependsOn moduleDescriptor
