Skip to content

Commit

Permalink
8279185: Support for IsoFields in JapaneseDate/MinguoDate/ThaiBuddhis…
Browse files Browse the repository at this point in the history
…tDate

Reviewed-by: joehw, rriggs
  • Loading branch information
naotoj committed May 23, 2022
1 parent ac274c4 commit ef7a9f8
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 38 deletions.
34 changes: 31 additions & 3 deletions src/java.base/share/classes/java/time/chrono/Chronology.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -76,6 +76,7 @@
import java.time.format.ResolverStyle;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQueries;
Expand Down Expand Up @@ -736,7 +737,7 @@ default ChronoPeriod period(int years, int months, int days) {
* @throws DateTimeException if any of the values are out of range
* @since 9
*/
public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
default long epochSecond(int prolepticYear, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
Objects.requireNonNull(zoneOffset, "zoneOffset");
HOUR_OF_DAY.checkValidValue(hour);
Expand Down Expand Up @@ -765,11 +766,38 @@ public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
* @throws DateTimeException if any of the values are out of range
* @since 9
*/
public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
Objects.requireNonNull(era, "era");
return epochSecond(prolepticYear(era, yearOfEra), month, dayOfMonth, hour, minute, second, zoneOffset);
}

/**
* Checks if this chronology is ISO based.
* <p>
* An ISO based chronology has the same basic structure as the {@link IsoChronology
* ISO chronology}, i.e., the chronology has the same number of months, the number
* of days in each month, and day-of-year and leap years are the same as ISO chronology.
* It also supports the concept of week-based-year of ISO chronology.
* For example, the {@link MinguoChronology Minguo}, {@link ThaiBuddhistChronology
* ThaiThaiBuddhist} and {@link JapaneseChronology Japanese} chronologies are ISO based.
*
* @implSpec
* The default implementation returns {@code false}.
*
* @return {@code true} only if all the fields of {@link IsoFields} are supported by
* this chronology. Otherwise, returns {@code false}.
* @see IsoChronology
* @see JapaneseChronology
* @see MinguoChronology
* @see ThaiBuddhistChronology
* @see IsoFields
* @since 19
*/
default boolean isIsoBased() {
return false;
}

//-----------------------------------------------------------------------
/**
* Compares this chronology to another chronology.
Expand Down
17 changes: 16 additions & 1 deletion src/java.base/share/classes/java/time/chrono/IsoChronology.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -87,6 +87,7 @@
import java.time.ZoneOffset;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.ValueRange;
Expand Down Expand Up @@ -677,6 +678,20 @@ public Period period(int years, int months, int days) {
return Period.of(years, months, days);
}

//-----------------------------------------------------------------------
/**
* {@code IsoChronology} is an ISO based chronology, which supports fields
* in {@link IsoFields}, such as {@link IsoFields#DAY_OF_QUARTER DAY_OF_QUARTER}
* and {@link IsoFields#QUARTER_OF_YEAR QUARTER_OF_YEAR}.
* @see IsoFields
* @return {@code true}
* @since 19
*/
@Override
public boolean isIsoBased() {
return true;
}

//-----------------------------------------------------------------------
/**
* Writes the Chronology using a
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -76,6 +76,7 @@
import java.time.ZoneId;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalField;
Expand Down Expand Up @@ -504,6 +505,20 @@ private ChronoLocalDate resolveYD(JapaneseEra era, int yoe, Map <TemporalField,L
return dateYearDay(era, yoe, doy); // smart is same as strict
}

//-----------------------------------------------------------------------
/**
* {@code JapaneseChronology} is an ISO based chronology, which supports fields
* in {@link IsoFields}, such as {@link IsoFields#DAY_OF_QUARTER DAY_OF_QUARTER}
* and {@link IsoFields#QUARTER_OF_YEAR QUARTER_OF_YEAR}.
* @see IsoFields
* @return {@code true}
* @since 19
*/
@Override
public boolean isIsoBased() {
return true;
}

//-----------------------------------------------------------------------
/**
* Writes the Chronology using a
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -465,13 +465,13 @@ public ValueRange range(TemporalField field) {

@Override
public long getLong(TemporalField field) {
if (field instanceof ChronoField) {
if (field instanceof ChronoField cf) {
// same as ISO:
// DAY_OF_WEEK, DAY_OF_MONTH, EPOCH_DAY, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR
//
// calendar specific fields
// DAY_OF_YEAR, YEAR_OF_ERA, ERA
switch ((ChronoField) field) {
switch (cf) {
case ALIGNED_DAY_OF_WEEK_IN_MONTH:
case ALIGNED_DAY_OF_WEEK_IN_YEAR:
case ALIGNED_WEEK_OF_MONTH:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -69,6 +69,7 @@
import java.time.ZoneId;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.ValueRange;
Expand Down Expand Up @@ -335,6 +336,20 @@ public MinguoDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyl
return (MinguoDate) super.resolveDate(fieldValues, resolverStyle);
}

//-----------------------------------------------------------------------
/**
* {@code MinguoChronology} is an ISO based chronology, which supports fields
* in {@link IsoFields}, such as {@link IsoFields#DAY_OF_QUARTER DAY_OF_QUARTER}
* and {@link IsoFields#QUARTER_OF_YEAR QUARTER_OF_YEAR}.
* @see IsoFields
* @return {@code true}
* @since 19
*/
@Override
public boolean isIsoBased() {
return true;
}

//-----------------------------------------------------------------------
/**
* Writes the Chronology using a
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -69,6 +69,7 @@
import java.time.ZoneId;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.ValueRange;
Expand Down Expand Up @@ -335,6 +336,20 @@ public ThaiBuddhistDate resolveDate(Map<TemporalField, Long> fieldValues, Resolv
return (ThaiBuddhistDate) super.resolveDate(fieldValues, resolverStyle);
}

//-----------------------------------------------------------------------
/**
* {@code ThaiBuddhistChronology} is an ISO based chronology, which supports fields
* in {@link IsoFields}, such as {@link IsoFields#DAY_OF_QUARTER DAY_OF_QUARTER}
* and {@link IsoFields#QUARTER_OF_YEAR QUARTER_OF_YEAR}.
* @see IsoFields
* @return {@code true}
* @since 19
*/
@Override
public boolean isIsoBased() {
return true;
}

//-----------------------------------------------------------------------
/**
* Writes the Chronology using a
Expand Down
24 changes: 14 additions & 10 deletions src/java.base/share/classes/java/time/temporal/IsoFields.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -546,7 +546,10 @@ public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
if (isSupportedBy(temporal) == false) {
throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear");
}
return super.rangeRefinedBy(temporal);
var range = super.rangeRefinedBy(temporal);
var chronoRange = Chronology.from(temporal).range(YEAR);
return ValueRange.of(Math.max(range.getMinimum(), chronoRange.getMinimum()),
Math.min(range.getMaximum(), chronoRange.getMaximum()));
}
@SuppressWarnings("unchecked")
@Override
Expand Down Expand Up @@ -591,12 +594,6 @@ public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
private static final int[] QUARTER_DAYS = {0, 90, 181, 273, 0, 91, 182, 274};


private static void ensureIso(TemporalAccessor temporal) {
if (isIso(temporal) == false) {
throw new DateTimeException("Resolve requires IsoChronology");
}
}

private static ValueRange getWeekRange(LocalDate date) {
int wby = getWeekBasedYear(date);
return ValueRange.of(1, getWeekRange(wby));
Expand Down Expand Up @@ -731,7 +728,14 @@ public String toString() {
}
}

static boolean isIso(TemporalAccessor temporal) {
return Chronology.from(temporal).equals(IsoChronology.INSTANCE);
private static void ensureIso(TemporalAccessor temporal) {
if (!isIso(temporal)) {
throw new DateTimeException("Resolve requires ISO based chronology: " +
Chronology.from(temporal));
}
}

private static boolean isIso(TemporalAccessor temporal) {
return Chronology.from(temporal).isIsoBased();
}
}
24 changes: 19 additions & 5 deletions test/jdk/java/time/tck/java/time/chrono/TCKChronology.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -64,10 +64,6 @@
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.time.Clock;
import java.time.DateTimeException;
import java.time.LocalDate;
Expand Down Expand Up @@ -424,4 +420,22 @@ public void test_bad_epochSecond(Chronology chrono, int y, int m, int d, int h,
chrono.epochSecond(y, m, d, h, min, s, offset);
}

@DataProvider
Object[][] data_isIsoBased() {
return new Object[][] {
{IsoChronology.INSTANCE, true},
{JapaneseChronology.INSTANCE, true},
{MinguoChronology.INSTANCE, true},
{ThaiBuddhistChronology.INSTANCE, true},
{HijrahChronology.INSTANCE, false},
};
}

//-----------------------------------------------------------------------
// isIsoBased()
//-----------------------------------------------------------------------
@Test(dataProvider = "data_isIsoBased")
public void test_isIsoBased(Chronology chrono, boolean expected) {
assertEquals(chrono.isIsoBased(), expected);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -79,6 +80,7 @@ public void test_TestServiceLoader() {
ChronoLocalDate copticDate = chrono.date(1729, 4, 27);
LocalDate ld = LocalDate.from(copticDate);
assertEquals(ld, LocalDate.of(2013, 1, 5), "CopticDate does not match LocalDate");
assertEquals(chrono.isIsoBased(), false);
}

}
8 changes: 4 additions & 4 deletions test/jdk/java/time/tck/java/time/temporal/TCKIsoFields.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -71,7 +71,7 @@
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.chrono.ThaiBuddhistDate;
import java.time.chrono.HijrahDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
Expand Down Expand Up @@ -463,7 +463,7 @@ public void test_isofields_rangerefinedby(TemporalField field, int value, ValueR

@Test(dataProvider = "isofields", expectedExceptions = UnsupportedTemporalTypeException.class)
public void test_nonisofields_rangerefinedby(TemporalField field, int value, ValueRange valueRange) {
field.rangeRefinedBy(ThaiBuddhistDate.now());
field.rangeRefinedBy(HijrahDate.now());
}

//-----------------------------------------------------------------------
Expand All @@ -477,7 +477,7 @@ public void test_isofields_getFrom(TemporalField field, int value, ValueRange va

@Test(dataProvider = "isofields", expectedExceptions = UnsupportedTemporalTypeException.class)
public void test_nonisofields_getFrom(TemporalField field, int value, ValueRange valueRange) {
field.getFrom(ThaiBuddhistDate.now());
field.getFrom(HijrahDate.now());
}

//-----------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -58,6 +59,7 @@
*/
package test.java.time.chrono;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;

import java.time.chrono.Chronology;
Expand All @@ -81,7 +83,9 @@ public void test_copticServiceLoader() {
for (Chronology chrono : loader) {
chronos.put(chrono.getId(), chrono);
}
assertNotNull(chronos.get("Coptic"), "CopticChronology not found");
var coptic = chronos.get("Coptic");
assertNotNull(coptic, "CopticChronology not found");
assertEquals(coptic.isIsoBased(), false);
}

}
Loading

1 comment on commit ef7a9f8

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.