提交 f2141189 编写于 作者: S sherman

8007392: JSR 310: DateTime API Updates

8007520: Update date/time classes in j.util and j.sql packages
8007572: Replace existing jdk timezone data at <java.home>/lib/zi with JSR310's tzdb
Summary: Integration of JSR310 Date/Time API for M7
Reviewed-by: darcy, alanb, naoto
Contributed-by: scolebourne@joda.org, roger.riggs@oracle.com, masayoshi.okutsu@oracle.com, patrick.zhang@oracle.com
上级 09d88d90
......@@ -128,9 +128,9 @@ CORE_PKGS = \
java.text \
java.text.spi \
java.time \
java.time.temporal \
java.time.calendar \
java.time.chrono \
java.time.format \
java.time.temporal \
java.time.zone \
java.util \
java.util.concurrent \
......
......@@ -255,7 +255,6 @@ JAVA_JAVA_java = \
java/util/SimpleTimeZone.java \
sun/util/calendar/ZoneInfo.java \
sun/util/calendar/ZoneInfoFile.java \
sun/util/calendar/TzIDOldMapping.java \
java/util/TooManyListenersException.java \
java/util/Comparator.java \
java/util/Collections.java \
......
......@@ -70,7 +70,7 @@ else
endif
# nio need to be compiled before awt to have all charsets ready
SUBDIRS = jar security javazic misc net nio text util launcher cldr tzdb
SUBDIRS = jar security misc net nio text util launcher cldr tzdb
ifdef BUILD_HEADLESS_ONLY
DISPLAY_LIBS = awt $(HEADLESS_SUBDIR)
......
......@@ -33,11 +33,11 @@ include $(BUILDDIR)/common/Defs.gmk
# Time zone data file creation
TZDATA = ./tzdata/
TZDATA_VER = `$(GREP) '^tzdata' $(TZDATA)VERSION`
TZDATA_VER := $(shell $(GREP) '^tzdata' $(TZDATA)VERSION)
TZFILE = \
africa antarctica asia australasia europe northamerica \
pacificnew southamerica backward \
etcetera solar87 solar88 solar89 systemv
etcetera systemv
JDKTZDATA = ./tzdata_jdk/
JDKTZFILES = gmt jdk11_backward
TZFILES = \
......
#
# Copyright (c) 2000, 2005, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone GMT 0:00 - GMT
#
# Copyright (c) 2000, 2006, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# JDK 1.1.x compatible time zone IDs
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule SystemV min 1973 - Apr lastSun 2:00 1:00 D
Rule SystemV min 1973 - Oct lastSun 2:00 0 S
Rule SystemV 1974 only - Jan 6 2:00 1:00 D
Rule SystemV 1974 only - Nov lastSun 2:00 0 S
Rule SystemV 1975 only - Feb 23 2:00 1:00 D
Rule SystemV 1975 only - Oct lastSun 2:00 0 S
Rule SystemV 1976 max - Apr lastSun 2:00 1:00 D
Rule SystemV 1976 max - Oct lastSun 2:00 0 S
# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL]
Zone SystemV/AST4ADT -4:00 SystemV A%sT
Zone SystemV/EST5EDT -5:00 SystemV E%sT
Zone SystemV/CST6CDT -6:00 SystemV C%sT
Zone SystemV/MST7MDT -7:00 SystemV M%sT
Zone SystemV/PST8PDT -8:00 SystemV P%sT
Zone SystemV/YST9YDT -9:00 SystemV Y%sT
Zone SystemV/AST4 -4:00 - AST
Zone SystemV/EST5 -5:00 - EST
Zone SystemV/CST6 -6:00 - CST
Zone SystemV/MST7 -7:00 - MST
Zone SystemV/PST8 -8:00 - PST
Zone SystemV/YST9 -9:00 - YST
Zone SystemV/HST10 -10:00 - HST
......@@ -43,9 +43,15 @@ BUILD_MANIFEST=true
#
TZDATA_DIR := ../javazic/tzdata
TZDATA_VER := $(subst tzdata,,$(shell $(GREP) '^tzdata' $(TZDATA_DIR)/VERSION))
TZFILE := africa antarctica asia australasia europe northamerica southamerica backward etcetera
TZFILE := \
africa antarctica asia australasia europe northamerica \
pacificnew southamerica backward etcetera \
gmt jdk11_backward
TZFILES := $(addprefix $(TZDATA_DIR)/,$(TZFILE))
TZDB_JAR = tzdb.jar
#
......@@ -61,7 +67,7 @@ build: $(LIBDIR)/$(TZDB_JAR)
$(LIBDIR)/$(TZDB_JAR): $(TZFILES)
$(prep-target)
echo build tzdb from version $(TZDATA_VER)
$(BOOT_JAVA_CMD) -jar $(BUILDTOOLJARDIR)/tzdb.jar -verbose \
$(BOOT_JAVA_CMD) -jar $(BUILDTOOLJARDIR)/tzdb.jar \
-version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(LIBDIR) $(TZFILE)
clean clobber::
......
......@@ -48,7 +48,6 @@ SUBDIRS = \
hasher_classes \
jarreorder \
jarsplit \
javazic \
jdwpgen \
makeclasslist \
strip_properties \
......
......@@ -490,11 +490,16 @@ class Zoneinfo {
tz.addUsedRec(rrec);
usedZone = true;
}
} else {
} else { // fromTime == minTime
int save = rrec.getSave();
tz.addTransition(fromTime,
tz.addTransition(minTime,
tz.getOffsetIndex(gmtOffset),
tz.getDstOffsetIndex(0));
tz.addTransition(transition,
tz.getOffsetIndex(gmtOffset+save),
tz.getDstOffsetIndex(save));
tz.addUsedRec(rrec);
usedZone = true;
}
......
......@@ -227,6 +227,7 @@ public final class TzdbZoneRulesCompiler {
Map<String, SortedMap<String, ZoneRules>> allBuiltZones = new TreeMap<>();
Set<String> allRegionIds = new TreeSet<String>();
Set<ZoneRules> allRules = new HashSet<ZoneRules>();
Map<String, Map<String, String>> allLinks = new TreeMap<>();
for (File srcDir : srcDirs) {
// source files in this directory
......@@ -242,7 +243,8 @@ public final class TzdbZoneRulesCompiler {
}
// compile
String loopVersion = srcDir.getName();
String loopVersion = (srcDirs.size() == 1 && version != null)
? version : srcDir.getName();
TzdbZoneRulesCompiler compiler = new TzdbZoneRulesCompiler(loopVersion, srcFiles, verbose);
try {
// compile
......@@ -255,12 +257,13 @@ public final class TzdbZoneRulesCompiler {
if (verbose) {
System.out.println("Outputting file: " + dstFile);
}
outputFile(dstFile, loopVersion, builtZones);
outputFile(dstFile, loopVersion, builtZones, compiler.links);
// create totals
allBuiltZones.put(loopVersion, builtZones);
allRegionIds.addAll(builtZones.keySet());
allRules.addAll(builtZones.values());
allLinks.put(loopVersion, compiler.links);
} catch (Exception ex) {
System.out.println("Failed: " + ex.toString());
ex.printStackTrace();
......@@ -274,7 +277,7 @@ public final class TzdbZoneRulesCompiler {
if (verbose) {
System.out.println("Outputting combined file: " + dstFile);
}
outputFile(dstFile, allBuiltZones, allRegionIds, allRules);
outputFile(dstFile, allBuiltZones, allRegionIds, allRules, allLinks);
}
}
......@@ -283,12 +286,15 @@ public final class TzdbZoneRulesCompiler {
*/
private static void outputFile(File dstFile,
String version,
SortedMap<String, ZoneRules> builtZones) {
SortedMap<String, ZoneRules> builtZones,
Map<String, String> links) {
Map<String, SortedMap<String, ZoneRules>> loopAllBuiltZones = new TreeMap<>();
loopAllBuiltZones.put(version, builtZones);
Set<String> loopAllRegionIds = new TreeSet<String>(builtZones.keySet());
Set<ZoneRules> loopAllRules = new HashSet<ZoneRules>(builtZones.values());
outputFile(dstFile, loopAllBuiltZones, loopAllRegionIds, loopAllRules);
Map<String, Map<String, String>> loopAllLinks = new TreeMap<>();
loopAllLinks.put(version, links);
outputFile(dstFile, loopAllBuiltZones, loopAllRegionIds, loopAllRules, loopAllLinks);
}
/**
......@@ -297,10 +303,10 @@ public final class TzdbZoneRulesCompiler {
private static void outputFile(File dstFile,
Map<String, SortedMap<String, ZoneRules>> allBuiltZones,
Set<String> allRegionIds,
Set<ZoneRules> allRules)
{
Set<ZoneRules> allRules,
Map<String, Map<String, String>> allLinks) {
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(dstFile))) {
outputTZEntry(jos, allBuiltZones, allRegionIds, allRules);
outputTZEntry(jos, allBuiltZones, allRegionIds, allRules, allLinks);
} catch (Exception ex) {
System.out.println("Failed: " + ex.toString());
ex.printStackTrace();
......@@ -314,7 +320,8 @@ public final class TzdbZoneRulesCompiler {
private static void outputTZEntry(JarOutputStream jos,
Map<String, SortedMap<String, ZoneRules>> allBuiltZones,
Set<String> allRegionIds,
Set<ZoneRules> allRules) {
Set<ZoneRules> allRules,
Map<String, Map<String, String>> allLinks) {
// this format is not publicly specified
try {
jos.putNextEntry(new ZipEntry("TZDB.dat"));
......@@ -359,6 +366,16 @@ public final class TzdbZoneRulesCompiler {
out.writeShort(rulesIndex);
}
}
// alias-region
for (String version : allLinks.keySet()) {
out.writeShort(allLinks.get(version).size());
for (Map.Entry<String, String> entry : allLinks.get(version).entrySet()) {
int aliasIndex = Arrays.binarySearch(regionArray, entry.getKey());
int regionIndex = Arrays.binarySearch(regionArray, entry.getValue());
out.writeShort(aliasIndex);
out.writeShort(regionIndex);
}
}
out.flush();
jos.closeEntry();
} catch (Exception ex) {
......@@ -621,7 +638,8 @@ public final class TzdbZoneRulesCompiler {
private int parseYear(String str, int defaultYear) {
if (YEAR.reset(str).matches()) {
if (YEAR.group("min") != null) {
return YEAR_MIN_VALUE;
//return YEAR_MIN_VALUE;
return 1900; // systemv has min
} else if (YEAR.group("max") != null) {
return YEAR_MAX_VALUE;
} else if (YEAR.group("only") != null) {
......@@ -742,16 +760,20 @@ public final class TzdbZoneRulesCompiler {
if (realRules == null) {
throw new IllegalArgumentException("Alias '" + aliasId + "' links to invalid zone '" + realId + "' for '" + version + "'");
}
links.put(aliasId, realId);
}
builtZones.put(aliasId, realRules);
}
// remove UTC and GMT
builtZones.remove("UTC");
builtZones.remove("GMT");
builtZones.remove("GMT0");
//builtZones.remove("UTC");
//builtZones.remove("GMT");
//builtZones.remove("GMT0");
builtZones.remove("GMT+0");
builtZones.remove("GMT-0");
links.remove("GMT+0");
links.remove("GMT-0");
}
//-----------------------------------------------------------------------
......@@ -785,7 +807,6 @@ public final class TzdbZoneRulesCompiler {
boolean endOfDay;
/** The time of the cutover. */
TimeDefinition timeDefinition = TimeDefinition.WALL;
void adjustToFowards(int year) {
if (adjustForwards == false && dayOfMonth > 0) {
LocalDate adjustedDate = LocalDate.of(year, month, dayOfMonth).minusDays(6);
......
......@@ -30,7 +30,7 @@ GENDATA_TZDB :=
#
TZDATA_DIR := $(JDK_TOPDIR)/make/sun/javazic/tzdata
TZDATA_VER := $(subst tzdata,,$(shell $(GREP) '^tzdata' $(TZDATA_DIR)/VERSION))
TZDATA_TZFILE := africa antarctica asia australasia europe northamerica southamerica backward etcetera
TZDATA_TZFILE := africa antarctica asia australasia europe northamerica pacificnew southamerica backward etcetera gmt jdk11_backward
TZDATA_TZFILES := $(addprefix $(TZDATA_DIR)/,$(TZDATA_TZFILE))
GENDATA_TZDB_DST := $(JDK_OUTPUTDIR)/lib
......@@ -39,6 +39,6 @@ GENDATA_TZDB_JAR := tzdb.jar
$(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR) : $(TZDATA_TZFILES)
$(RM) $(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR)
echo building tzdb from version $(TZDATA_VER)
$(TOOL_TZDB) -verbose -version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(GENDATA_TZDB_DST) $(TZDATA_TZFILE)
$(TOOL_TZDB) -version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(GENDATA_TZDB_DST) $(TZDATA_TZFILE)
GENDATA_TZDB += $(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR)
......@@ -34,7 +34,7 @@ GENDATA_TIMEZONE_TMP := $(JDK_OUTPUTDIR)/gendata_timezone
TZFILE0 := \
africa antarctica asia australasia europe northamerica \
pacificnew southamerica backward \
etcetera solar87 solar88 solar89 systemv
etcetera systemv
TZFILE1 := \
gmt jdk11_backward
......
......@@ -44,9 +44,6 @@ GENDATA += $(BREAK_ITERATOR)
include GendataFontConfig.gmk
GENDATA += $(GENDATA_FONT_CONFIG)
include GendataTimeZone.gmk
GENDATA += $(GENDATA_TIMEZONE)
include GendataTZDB.gmk
GENDATA += $(GENDATA_TZDB)
......
......@@ -103,9 +103,6 @@ TOOL_HASHER=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
TOOL_JARSPLIT=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
build.tools.jarsplit.JarSplit
TOOL_JAVAZIC=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
build.tools.javazic.Main
TOOL_TZDB=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
build.tools.tzdb.TzdbZoneRulesCompiler
......
......@@ -25,6 +25,9 @@
package java.sql;
import java.time.Instant;
import java.time.LocalDate;
/**
* <P>A thin wrapper around a millisecond value that allows
* JDBC to identify this as an SQL <code>DATE</code> value. A
......@@ -113,7 +116,6 @@ public class Date extends java.util.Date {
int firstDash;
int secondDash;
Date d = null;
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
......@@ -255,4 +257,50 @@ public class Date extends java.util.Date {
* compatibility.
*/
static final long serialVersionUID = 1511598038487230103L;
/**
* Obtains an instance of {@code Date} from a {@link LocalDate} object
* with the same year, month and day of month value as the given
* {@code LocalDate}.
* <p>
* The provided {@code LocalDate} is interpreted as the local date
* in the local time zone.
*
* @param date a {@code LocalDate} to convert
* @return a {@code Date} object
* @exception NullPointerException if {@code date} is null
* @since 1.8
*/
@SuppressWarnings("deprecation")
public static Date valueOf(LocalDate date) {
return new Date(date.getYear() - 1900, date.getMonthValue() -1,
date.getDayOfMonth());
}
/**
* Converts this {@code Date} object to a {@code LocalDate}
* <p>
* The conversion creates a {@code LocalDate} that represents the same
* date value as this {@code Date} in local time zone
*
* @return a {@code LocalDate} object representing the same date value
*
* @since 1.8
*/
@SuppressWarnings("deprecation")
public LocalDate toLocalDate() {
return LocalDate.of(getYear() + 1900, getMonth() + 1, getDate());
}
/**
* This method always throws an UnsupportedOperationException and should
* not be used because SQL {@code Date} values do not have a time
* component.
*
* @exception java.lang.UnsupportedOperationException if this method is invoked
*/
@Override
public Instant toInstant() {
throw new java.lang.UnsupportedOperationException();
}
}
......@@ -25,6 +25,9 @@
package java.sql;
import java.time.Instant;
import java.time.LocalTime;
/**
* <P>A thin wrapper around the <code>java.util.Date</code> class that allows the JDBC
* API to identify this as an SQL <code>TIME</code> value. The <code>Time</code>
......@@ -246,4 +249,45 @@ public class Time extends java.util.Date {
* compatibility.
*/
static final long serialVersionUID = 8397324403548013681L;
/**
* Obtains an instance of {@code Time} from a {@link LocalTime} object
* with the same hour, minute and second time value as the given
* {@code LocalTime}.
*
* @param time a {@code LocalTime} to convert
* @return a {@code Time} object
* @exception NullPointerException if {@code time} is null
* @since 1.8
*/
@SuppressWarnings("deprecation")
public static Time valueOf(LocalTime time) {
return new Time(time.getHour(), time.getMinute(), time.getSecond());
}
/**
* Converts this {@code Time} object to a {@code LocalTime}.
* <p>
* The conversion creates a {@code LocalTime} that represents the same
* hour, minute, and second time value as this {@code Time}.
*
* @return a {@code LocalTime} object representing the same time value
* @since 1.8
*/
@SuppressWarnings("deprecation")
public LocalTime toLocalTime() {
return LocalTime.of(getHours(), getMinutes(), getSeconds());
}
/**
* This method always throws an UnsupportedOperationException and should
* not be used because SQL {@code Time} values do not have a date
* component.
*
* @exception java.lang.UnsupportedOperationException if this method is invoked
*/
@Override
public Instant toInstant() {
throw new java.lang.UnsupportedOperationException();
}
}
......@@ -25,6 +25,8 @@
package java.sql;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.StringTokenizer;
/**
......@@ -485,7 +487,6 @@ public class Timestamp extends java.util.Date {
}
}
return i;
}
/**
......@@ -530,4 +531,89 @@ public class Timestamp extends java.util.Date {
static final long serialVersionUID = 2745179027874758501L;
private static final int MILLIS_PER_SECOND = 1000;
/**
* Obtains an instance of {@code Timestamp} from a {@code LocalDateTime}
* object, with the same year, month, day of month, hours, minutes,
* seconds and nanos date-time value as the provided {@code LocalDateTime}.
* <p>
* The provided {@code LocalDateTime} is interpreted as the local
* date-time in the local time zone.
*
* @param dateTime a {@code LocalDateTime} to convert
* @return a {@code Timestamp} object
* @exception NullPointerException if {@code dateTime} is null.
* @since 1.8
*/
@SuppressWarnings("deprecation")
public static Timestamp valueOf(LocalDateTime dateTime) {
return new Timestamp(dateTime.getYear() - 1900,
dateTime.getMonthValue() - 1,
dateTime.getDayOfMonth(),
dateTime.getHour(),
dateTime.getMinute(),
dateTime.getSecond(),
dateTime.getNano());
}
/**
* Converts this {@code Timestamp} object to a {@code LocalDateTime}.
* <p>
* The conversion creates a {@code LocalDateTime} that represents the
* same year, month, day of month, hours, minutes, seconds and nanos
* date-time value as this {@code Timestamp} in the local time zone.
*
* @return a {@code LocalDateTime} object representing the same date-time value
* @since 1.8
*/
@SuppressWarnings("deprecation")
public LocalDateTime toLocalDateTime() {
return LocalDateTime.of(getYear() + 1900,
getMonth() + 1,
getDate(),
getHours(),
getMinutes(),
getSeconds(),
getNanos());
}
/**
* Obtains an instance of {@code Timestamp} from an {@link Instant} object.
* <p>
* {@code Instant} can store points on the time-line further in the future
* and further in the past than {@code Date}. In this scenario, this method
* will throw an exception.
*
* @param instant the instant to convert
* @return an {@code Timestamp} representing the same point on the time-line as
* the provided instant
* @exception NullPointerException if {@code instant} is null.
* @exception IllegalArgumentException if the instant is too large to
* represent as a {@code Timesamp}
* @since 1.8
*/
public static Timestamp from(Instant instant) {
try {
Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND);
stamp.nanos = instant.getNano();
return stamp;
} catch (ArithmeticException ex) {
throw new IllegalArgumentException(ex);
}
}
/**
* Converts this {@code Timestamp} object to an {@code Instant}.
* <p>
* The conversion creates an {@code Instant} that represents the same
* point on the time-line as this {@code Timestamp}.
*
* @return an instant representing the same point on the time-line
* @since 1.8
*/
@Override
public Instant toInstant() {
return Instant.ofEpochSecond(super.getTime() / MILLIS_PER_SECOND, nanos);
}
}
......@@ -377,60 +377,57 @@ public abstract class Clock {
* an instant on the time-line rather than a raw millisecond value.
* This method is provided to allow the use of the clock in high performance use cases
* where the creation of an object would be unacceptable.
* <p>
* The default implementation currently calls {@link #instant}.
*
* @return the current millisecond instant from this clock, measured from
* the Java epoch of 1970-01-01T00:00 UTC, not null
* @throws DateTimeException if the instant cannot be obtained, not thrown by most implementations
*/
public abstract long millis();
public long millis() {
return instant().toEpochMilli();
}
//-----------------------------------------------------------------------
/**
* Gets the current instant of the clock.
* <p>
* This returns an instant representing the current instant as defined by the clock.
* <p>
* The default implementation currently calls {@link #millis}.
*
* @return the current instant from this clock, not null
* @throws DateTimeException if the instant cannot be obtained, not thrown by most implementations
*/
public Instant instant() {
return Instant.ofEpochMilli(millis());
}
public abstract Instant instant();
//-----------------------------------------------------------------------
/**
* Checks if this clock is equal to another clock.
* <p>
* Clocks must compare equal based on their state and behavior.
* Clocks should override this method to compare equals based on
* their state and to meet the contract of {@link Object#equals}.
* If not overridden, the behavior is defined by {@link Object#equals}
*
* @param obj the object to check, null returns false
* @return true if this is equal to the other clock
*/
@Override
public abstract boolean equals(Object obj);
public boolean equals(Object obj) {
return super.equals(obj);
}
/**
* A hash code for this clock.
*
* @return a suitable hash code
*/
@Override
public abstract int hashCode();
//-----------------------------------------------------------------------
/**
* Returns a string describing this clock.
* <p>
* Clocks must have a string representation based on their state and behavior.
* For example, 'System[Europe/Paris]' could be used to represent the System
* clock in the 'Europe/Paris' time-zone.
* Clocks should override this method based on
* their state and to meet the contract of {@link Object#hashCode}.
* If not overridden, the behavior is defined by {@link Object#hashCode}
*
* @return a string representation of this clock, not null
* @return a suitable hash code
*/
@Override
public abstract String toString();
public int hashCode() {
return super.hashCode();
}
//-----------------------------------------------------------------------
/**
......@@ -460,6 +457,10 @@ public abstract class Clock {
return System.currentTimeMillis();
}
@Override
public Instant instant() {
return Instant.ofEpochMilli(millis());
}
@Override
public boolean equals(Object obj) {
if (obj instanceof SystemClock) {
return zone.equals(((SystemClock) obj).zone);
......
......@@ -170,8 +170,9 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
/**
* Obtains an instance of {@code DayOfWeek} from a temporal object.
* <p>
* A {@code TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@code DayOfWeek}.
* This obtains a day-of-week based on the specified temporal.
* A {@code TemporalAccessor} represents an arbitrary set of date and time information,
* which this factory converts to an instance of {@code DayOfWeek}.
* <p>
* The conversion extracts the {@link ChronoField#DAY_OF_WEEK DAY_OF_WEEK} field.
* <p>
......@@ -206,8 +207,9 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
/**
* Gets the textual representation, such as 'Mon' or 'Friday'.
* <p>
* This returns the textual name used to identify the day-of-week.
* The parameters control the length of the returned text and the locale.
* This returns the textual name used to identify the day-of-week,
* suitable for presentation to the user.
* The parameters control the style of the returned text and the locale.
* <p>
* If no textual mapping is found then the {@link #getValue() numeric value} is returned.
*
......@@ -215,8 +217,8 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
* @param locale the locale to use, not null
* @return the text value of the day-of-week, not null
*/
public String getText(TextStyle style, Locale locale) {
return new DateTimeFormatterBuilder().appendText(DAY_OF_WEEK, style).toFormatter(locale).print(this);
public String getDisplayName(TextStyle style, Locale locale) {
return new DateTimeFormatterBuilder().appendText(DAY_OF_WEEK, style).toFormatter(locale).format(this);
}
//-----------------------------------------------------------------------
......@@ -232,7 +234,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will return false.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the field is supported is determined by the field.
*
......@@ -244,7 +246,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
if (field instanceof ChronoField) {
return field == DAY_OF_WEEK;
}
return field != null && field.doIsSupported(this);
return field != null && field.isSupportedBy(this);
}
/**
......@@ -260,7 +262,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the range can be obtained is determined by the field.
*
......@@ -289,15 +291,13 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param field the field to get, not null
* @return the value for the field, within the valid range of values
* @throws DateTimeException if a value for the field cannot be obtained
* @throws DateTimeException if the range of valid values for the field exceeds an {@code int}
* @throws DateTimeException if the value is outside the range of valid values for the field
* @throws ArithmeticException if numeric overflow occurs
*/
@Override
......@@ -320,7 +320,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
......@@ -336,7 +336,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
} else if (field instanceof ChronoField) {
throw new DateTimeException("Unsupported field: " + field.getName());
}
return field.doGet(this);
return field.getFrom(this);
}
//-----------------------------------------------------------------------
......
......@@ -64,11 +64,11 @@ package java.time;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoUnit.MONTHS;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.time.temporal.Chrono;
import java.time.temporal.ChronoField;
import java.time.temporal.ISOChrono;
import java.time.temporal.Queries;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
......@@ -192,8 +192,9 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
/**
* Obtains an instance of {@code Month} from a temporal object.
* <p>
* A {@code TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@code Month}.
* This obtains a month based on the specified temporal.
* A {@code TemporalAccessor} represents an arbitrary set of date and time information,
* which this factory converts to an instance of {@code Month}.
* <p>
* The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} field.
* The extraction is only permitted if the temporal object has an ISO
......@@ -211,7 +212,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
return (Month) temporal;
}
try {
if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
temporal = LocalDate.from(temporal);
}
return of(temporal.get(MONTH_OF_YEAR));
......@@ -237,8 +238,9 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
/**
* Gets the textual representation, such as 'Jan' or 'December'.
* <p>
* This returns the textual name used to identify the month-of-year.
* The parameters control the length of the returned text and the locale.
* This returns the textual name used to identify the month-of-year,
* suitable for presentation to the user.
* The parameters control the style of the returned text and the locale.
* <p>
* If no textual mapping is found then the {@link #getValue() numeric value} is returned.
*
......@@ -246,8 +248,8 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
* @param locale the locale to use, not null
* @return the text value of the month-of-year, not null
*/
public String getText(TextStyle style, Locale locale) {
return new DateTimeFormatterBuilder().appendText(MONTH_OF_YEAR, style).toFormatter(locale).print(this);
public String getDisplayName(TextStyle style, Locale locale) {
return new DateTimeFormatterBuilder().appendText(MONTH_OF_YEAR, style).toFormatter(locale).format(this);
}
//-----------------------------------------------------------------------
......@@ -263,7 +265,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will return false.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the field is supported is determined by the field.
*
......@@ -275,7 +277,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
if (field instanceof ChronoField) {
return field == MONTH_OF_YEAR;
}
return field != null && field.doIsSupported(this);
return field != null && field.isSupportedBy(this);
}
/**
......@@ -291,7 +293,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the range can be obtained is determined by the field.
*
......@@ -320,15 +322,13 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param field the field to get, not null
* @return the value for the field, within the valid range of values
* @throws DateTimeException if a value for the field cannot be obtained
* @throws DateTimeException if the range of valid values for the field exceeds an {@code int}
* @throws DateTimeException if the value is outside the range of valid values for the field
* @throws ArithmeticException if numeric overflow occurs
*/
@Override
......@@ -351,7 +351,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
......@@ -367,7 +367,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
} else if (field instanceof ChronoField) {
throw new DateTimeException("Unsupported field: " + field.getName());
}
return field.doGet(this);
return field.getFrom(this);
}
//-----------------------------------------------------------------------
......@@ -554,8 +554,8 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
@SuppressWarnings("unchecked")
@Override
public <R> R query(TemporalQuery<R> query) {
if (query == Queries.chrono()) {
return (R) ISOChrono.INSTANCE;
if (query == Queries.chronology()) {
return (R) IsoChronology.INSTANCE;
} else if (query == Queries.precision()) {
return (R) MONTHS;
}
......@@ -599,7 +599,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
*/
@Override
public Temporal adjustInto(Temporal temporal) {
if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
throw new DateTimeException("Adjustment only supported on ISO date-time");
}
return temporal.with(MONTH_OF_YEAR, getValue());
......
......@@ -59,7 +59,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package java.time.temporal;
package java.time;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
......@@ -70,14 +70,19 @@ import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.time.Clock;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.time.temporal.Queries;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQuery;
import java.time.temporal.ValueRange;
import java.util.Objects;
/**
......@@ -198,8 +203,8 @@ public final class MonthDay
* @param month the month-of-year to represent, not null
* @param dayOfMonth the day-of-month to represent, from 1 to 31
* @return the month-day, not null
* @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month
* @throws DateTimeException if the value of any field is out of range,
* or if the day-of-month is invalid for the month
*/
public static MonthDay of(Month month, int dayOfMonth) {
Objects.requireNonNull(month, "month");
......@@ -224,8 +229,8 @@ public final class MonthDay
* @param month the month-of-year to represent, from 1 (January) to 12 (December)
* @param dayOfMonth the day-of-month to represent, from 1 to 31
* @return the month-day, not null
* @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month
* @throws DateTimeException if the value of any field is out of range,
* or if the day-of-month is invalid for the month
*/
public static MonthDay of(int month, int dayOfMonth) {
return of(Month.of(month), dayOfMonth);
......@@ -235,8 +240,9 @@ public final class MonthDay
/**
* Obtains an instance of {@code MonthDay} from a temporal object.
* <p>
* A {@code TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@code MonthDay}.
* This obtains a month-day based on the specified temporal.
* A {@code TemporalAccessor} represents an arbitrary set of date and time information,
* which this factory converts to an instance of {@code MonthDay}.
* <p>
* The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} and
* {@link ChronoField#DAY_OF_MONTH DAY_OF_MONTH} fields.
......@@ -254,7 +260,7 @@ public final class MonthDay
return (MonthDay) temporal;
}
try {
if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
temporal = LocalDate.from(temporal);
}
return of(temporal.get(MONTH_OF_YEAR), temporal.get(DAY_OF_MONTH));
......@@ -314,8 +320,6 @@ public final class MonthDay
* {@link #get(TemporalField) get} methods will throw an exception.
* <p>
* If the field is a {@link ChronoField} then the query is implemented here.
* The {@link #isSupported(TemporalField) supported fields} will return valid
* values based on this date-time.
* The supported fields are:
* <ul>
* <li>{@code MONTH_OF_YEAR}
......@@ -324,7 +328,7 @@ public final class MonthDay
* All other {@code ChronoField} instances will return false.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the field is supported is determined by the field.
*
......@@ -336,7 +340,7 @@ public final class MonthDay
if (field instanceof ChronoField) {
return field == MONTH_OF_YEAR || field == DAY_OF_MONTH;
}
return field != null && field.doIsSupported(this);
return field != null && field.isSupportedBy(this);
}
/**
......@@ -353,7 +357,7 @@ public final class MonthDay
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the range can be obtained is determined by the field.
*
......@@ -385,7 +389,7 @@ public final class MonthDay
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
......@@ -412,7 +416,7 @@ public final class MonthDay
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
* is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
......@@ -431,10 +435,24 @@ public final class MonthDay
}
throw new DateTimeException("Unsupported field: " + field.getName());
}
return field.doGet(this);
return field.getFrom(this);
}
//-----------------------------------------------------------------------
/**
* Gets the month-of-year field from 1 to 12.
* <p>
* This method returns the month as an {@code int} from 1 to 12.
* Application code is frequently clearer if the enum {@link Month}
* is used by calling {@link #getMonth()}.
*
* @return the month-of-year, from 1 to 12
* @see #getMonth()
*/
public int getMonthValue() {
return month;
}
/**
* Gets the month-of-year field using the {@code Month} enum.
* <p>
......@@ -444,6 +462,7 @@ public final class MonthDay
* provides the {@link Month#getValue() int value}.
*
* @return the month-of-year, not null
* @see #getMonthValue()
*/
public Month getMonth() {
return Month.of(month);
......@@ -524,8 +543,8 @@ public final class MonthDay
*
* @param dayOfMonth the day-of-month to set in the return month-day, from 1 to 31
* @return a {@code MonthDay} based on this month-day with the requested day, not null
* @throws DateTimeException if the day-of-month value is invalid
* @throws DateTimeException if the day-of-month is invalid for the month
* @throws DateTimeException if the day-of-month value is invalid,
* or if the day-of-month is invalid for the month
*/
public MonthDay withDayOfMonth(int dayOfMonth) {
if (dayOfMonth == this.day) {
......@@ -556,8 +575,8 @@ public final class MonthDay
@SuppressWarnings("unchecked")
@Override
public <R> R query(TemporalQuery<R> query) {
if (query == Queries.chrono()) {
return (R) ISOChrono.INSTANCE;
if (query == Queries.chronology()) {
return (R) IsoChronology.INSTANCE;
}
return TemporalAccessor.super.query(query);
}
......@@ -591,7 +610,7 @@ public final class MonthDay
*/
@Override
public Temporal adjustInto(Temporal temporal) {
if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
throw new DateTimeException("Adjustment only supported on ISO date-time");
}
temporal = temporal.with(MONTH_OF_YEAR, month);
......@@ -600,9 +619,10 @@ public final class MonthDay
//-----------------------------------------------------------------------
/**
* Returns a date formed from this month-day at the specified year.
* Combines this month-day with a year to create a {@code LocalDate}.
* <p>
* This returns a {@code LocalDate} formed from this month-day and the specified year.
* <p>
* This combines this month-day and the specified year to form a {@code LocalDate}.
* A month-day of February 29th will be adjusted to February 28th in the resulting
* date if the year is not a leap year.
* <p>
......@@ -610,7 +630,7 @@ public final class MonthDay
*
* @param year the year to use, from MIN_YEAR to MAX_YEAR
* @return the local date formed from this month-day and the specified year, not null
* @see Year#atMonthDay(MonthDay)
* @throws DateTimeException if the year is outside the valid range of years
*/
public LocalDate atYear(int year) {
return LocalDate.of(year, month, isValidYear(year) ? day : 28);
......@@ -626,6 +646,7 @@ public final class MonthDay
* @param other the other month-day to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
@Override
public int compareTo(MonthDay other) {
int cmp = (month - other.month);
if (cmp == 0) {
......@@ -705,7 +726,7 @@ public final class MonthDay
* Outputs this month-day as a {@code String} using the formatter.
* <p>
* This month-day will be passed to the formatter
* {@link DateTimeFormatter#print(TemporalAccessor) print method}.
* {@link DateTimeFormatter#format(TemporalAccessor) format method}.
*
* @param formatter the formatter to use, not null
* @return the formatted month-day string, not null
......@@ -713,7 +734,7 @@ public final class MonthDay
*/
public String toString(DateTimeFormatter formatter) {
Objects.requireNonNull(formatter, "formatter");
return formatter.print(this);
return formatter.format(this);
}
//-----------------------------------------------------------------------
......@@ -721,7 +742,7 @@ public final class MonthDay
* Writes the object using a
* <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
* <pre>
* out.writeByte(6); // identifies this as a Year
* out.writeByte(13); // identifies this as a MonthDay
* out.writeByte(month);
* out.writeByte(day);
* </pre>
......
此差异已折叠。
......@@ -65,7 +65,7 @@ package java.time.format;
* Enumeration of the style of a localized date, time or date-time formatter.
* <p>
* These styles are used when obtaining a date-time style from configuration.
* See {@link DateTimeFormatters} and {@link DateTimeFormatterBuilder} for usage.
* See {@link DateTimeFormatter} and {@link DateTimeFormatterBuilder} for usage.
*
* <h3>Specification for implementors</h3>
* This is an immutable and thread-safe enum.
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册