<?xml version="1.0" encoding="ISO-8859-1"?> | |
<document> | |
<properties> | |
<title>Java date and time API - Upgrade from 1.6 to 2.0</title> | |
<author>Stephen Colebourne</author> | |
</properties> | |
<body> | |
<section name="Upgrade"> | |
<p> | |
These are the release notes and advice for upgrading Joda-Time from | |
version 1.6 to version 2.0. | |
<source> | |
Joda-Time version 2.0 | |
--------------------- | |
Joda-Time is a date and time handling library that seeks to replace the JDK | |
Date and Calendar classes. | |
This is the eighth release of Joda-Time. | |
This release contains enhancements, bug fixes and a time zone update. | |
We require JDK 1.5 or later as features such as generics are used. | |
It may be possible to use retroweaver to compile this under an earlier JDK but we haven't tried. | |
****************************************************************************** | |
Compatibility | |
The change in major version indicates compatibility issues. | |
Please read the detailed notes below. | |
If your code just _used_ Joda-Time and had no deprecation warnings then you | |
will _probably_ see no issues. | |
****************************************************************************** | |
Joda-Time is licensed under the business-friendly Apache License Version 2. | |
This is the same license as all of Apache, plus other open source projects such as Spring. | |
The intent is to make the code available to the Java community with the minimum | |
of restrictions. If the license causes you problems please contact the mailing list. | |
** Please also check out our related projects ** | |
** http://www.joda.org/joda-time/related.html ** | |
Enhancements since 1.6 | |
---------------------- | |
- Move to Java 5, with generics | |
See compatability notes. | |
- Appropriate Java Memory Model settings | |
The fields in the Base* classes, such as BaseDateTime and BaseDuration have been made volatile/final. | |
This was necessary to comply with the Java Memory Model to ensure correct immutable behaviour. | |
There should be no adverse effect from this change. | |
- Add YearMonth, useful for credit card dates [1863090] | |
- Add MonthDay, useful for birth dates without year | |
- System clock can now be controlled by applications | |
DateTimeUtils.MillisProvider is now public | |
- Word based period formatters available in multiple languages [1252708] | |
PeriodFormat provides a resource bundle based language formatter | |
Currently supported (via online translators) are English, German, Dutch, | |
French, Spanish and Portuguese. Corrections and additional languages welcome. | |
- Static now() methods available on all major types [3134566] | |
These should be used instead of the constructors when creating the current date/time | |
Unlike the constructors, these methods validate any argument to ensure it is non-null | |
- Static parse() methods available on all major types | |
These allow the formatter to be controlled | |
They do not always parse the same formats as the constructor taking an object | |
- Parsing of month and day without year now handles February 29th | |
This is achieved by changing the default year from 1970 to 2000 when parsing | |
a month or day without a year. This behaviour can be controlled using the new | |
withDefaultYear() setting on the formatter (set to 1970 for the old behaviour). | |
- Add static factory method millis() to Duration [2648777] | |
This checks for and returns the singleton value for ZERO | |
- Add methods to Duration to get standard minutes, hours and days [2862884] | |
- Support pluggable locale text and additional locales in JDK 6 [2690370] | |
Extra info accessed by reflection if JDK 6 used | |
- Better error messages for invalid time zone ids [2781835] | |
- Allow 'Z' and 'ZZ' in format patterns to parse 'Z' as '+00:00' [2827359] | |
- Support parsing of date-time zone IDs like Europe/London | |
- Support parsing of date-time zone names like "EST" and "British Summer Time" | |
These names are not unique, so the new API methods on the builder require you | |
to pass in a map listing all the names you want to be able to parse. | |
The existing method is unaltered and does not permit parsing. | |
- Add DateTimeFormatter.withZoneUTC() | |
Provides easy way to set UTC, which is often required for parsing | |
- Add DateTimeFormatter.parseLocalDate(), .parseLocalTime(), .parseLocalDateTime() | |
These parse the input string in the expected manner handing time zones and offsets. | |
For example, the LocalDate parse will parse any time or offset from the string, but | |
will completely ignore them when returning the actual LocalDate. | |
- Add DateTime.withEarlierOffsetAtOverlap() .withLaterOffsetAtOverlap() [3192457] | |
Allow fine grained control of the offset during a DST overlap | |
- Add DateTime.withTimeAtStartOfDay() [3304757] | |
Provide a simple, reliable way to get the start of day from DateTime. | |
- Add LocalDate.toDate() [2465359] | |
- Add LocalDateTime.toDate() | |
This provides a direct conversion to JDK Date which handles DST and | |
time zone data differences | |
- Cache hash code in LocalDate | |
Enhances performance | |
- DateTime constructors without seconds/millis [1982629] | |
- DateTimeFormatter convenience methods taking an Appendable [2607923] | |
- Add @FromString/@ToString annotations from joda-convert | |
This does NOT require the inclusion of joda-convert at runtime! | |
- Reduce logging from ZoneInfoCompiler by adding a verbose flag | |
- Better Javadoc of DateTimeZone.default behaviour | |
Compatibility with 1.6 | |
---------------------- | |
Binary compatible - Not fully, see below: | |
Source compatible - Not fully, see below: | |
Where possible, changes are binary compatible and source compatible. | |
The primary binary incompatible changes are the removal of the deprecated methods and | |
the addition of Comparable to ReadablePartial. | |
Testing has included clirr, javap and manual testing of old files with new code. | |
Deprecated methods removed: | |
- Chronology.getISO() | |
- Chronology.getISOUTC() | |
- Chronology.getISO(DateTimeZone) | |
- Chronology.getGJ() | |
- Chronology.getGJUTC() | |
- Chronology.getGJ(DateTimeZone) | |
- Chronology.getGregorian() | |
- Chronology.getGregorianUTC() | |
- Chronology.getGregorian(DateTimeZone) | |
- Chronology.getJulian() | |
- Chronology.getJulianUTC() | |
- Chronology.getJulian(DateTimeZone) | |
- Chronology.getBuddhist() | |
- Chronology.getBuddhistUTC() | |
- Chronology.getBuddhist(DateTimeZone) | |
- Chronology.getCoptic() | |
- Chronology.getCopticUTC() | |
- Chronology.getCoptic(DateTimeZone) | |
ReadablePartial has had the Comparable interface added (was previously just Javadoc). | |
Any implementation that extended AbstractPartial should have no problems, however any implementation | |
that extended ReadablePartial directly without implementing Comparable will be incompatible. | |
Any direct implementations of ReadableInstant or ReadableDuration are not source compatible. | |
This is because of the additional generics in Comparable. | |
Your code will be source compatible if you extended AbstractInstant or AbstractDuration. | |
This minor source incompatibility for a very few users was deemed to be the best balance of the various | |
difficult options that generics offers. | |
As mentioned above, erasure ensures that this source incompatibility is *not* a binary compatibility. | |
Note that not all deprecated elements have been removed. | |
Some methods and classes have been retained simply because the potential pain of binary incompatability | |
is greater than the gain of removing the deprecations. | |
Serialization compatible - Yes | |
Data compatible - Yes, except | |
- DateTimeZone data updated to version 2011h | |
Semantic compatible - Yes, except | |
Previously, DateTimeZone.forID matched time zone names case-insensitively, now it is case-sensitive | |
Previously, parsing a string where only the month and/or day is present would use 1970 as | |
the base year. This failed to handle February 29th. The new behaviour is as follows: | |
If the parse includes a field with a duration between months and days inclusive and does not include | |
any field larger than months, then the default year is changed to the value of getDefaultYear() on | |
DateTimeFormatter, which is the year 2000 by default. | |
In effect, this means that a pattern "ddMMM" which would previously have parsed to dates | |
in 1970 will now parse to dates in 2000 unless further customised. | |
The old behaviour can be simulated by calling withDefautYear(1970) on the formatter. | |
Previously, calling various methods during a daylight savings overlap would change the offset. | |
Now, most methods (such as withMillis/withSeconds/withMinutes/...) will retain the offset wherever possible. | |
Previously, calling DateTimeZone.getOffsetFromLocal during a daylight savings overlap chose the | |
earlier instant in the Western hemisphere and the later instant in the Eastern hemisphere. | |
Now, it always returns the earlier instant (summer time) during an overlap. | |
This affects the constructor of DateTime and other methods. | |
Previously, DateTimeZone.getMillisKeepLocal used DateTimeZone.getOffsetFromLocal, now it uses | |
DateTimeZone.convertUTCToLocal and DateTimeZone.convertLocalToUTC retaining the offset where possible | |
Previously, the internals of DateTimeParserBucket linked the parsed offset and zone. | |
This has now changed so that they are independent to allow the parsing of time-zone IDs. | |
If you implemented the DateTimeParser interface (unlikely), you should re-test your logic. | |
Previously, some parses of mixed weekyear and month formats would yield a result about a year out | |
Now, most (but not all) of these give a more appropriate result | |
Previously, java.util.TimeZone "MET" was incorrectly mapped to "Asia/Tehran". | |
It is now mapped to "CET" (Central European Time). | |
Previously, java.util.TimeZone "EET", "WET", "ECT" were mapped to European cities. | |
They are now mapped to "EET", "WET" and "CET" respectively. | |
Previously, java.util.TimeZone "IET", "AGT", "IST" and "VST" were mapped to old time-zone IDs. | |
They are now mapped to the newer IDs "America/Indiana/Indianapolis", "America/Argentina/Buenos_Aires", "Asia/Kolkata" and "Asia/Ho_Chi_Minh". | |
Deprecations since 1.6 | |
---------------------- | |
- DateTimeFormatter.getChronolgy() [2783325] | |
Incorrect spelling - new method DateTimeFormatter.getChronology() | |
Bug fixes since 1.6 | |
------------------- | |
- LocalTime.fromDateFields() | |
Now handles times based on java.util.Date before 1970 | |
- LocalDate.toInterval() [2487417] | |
Now handles time zones which have no midnight at DST cutover | |
- DateTimeZone.convertLocalToUTC [3102760,2182444,2553453] | |
New method now retains the offset wherever possible during calculations | |
This affects higher methods like withHourOfDay/withMinuteOfHour/withSecondOfMinute/withMillisOfSecond | |
which now do not change offset when called within a DST overlap | |
- DateTimeZone.convertLocalToUTC [2903029] | |
Now handles date after last ever DST change | |
- DateTimeZone.getOffsetFromLocal [2952991] | |
The behaviour during DST overlaps is now defined to always return the earlier instant | |
which is normally known as daylight or summer time. Previously, the result varied by hemisphere | |
This affects the constructor of DateTime and other methods | |
- DateTimeZone.getMillisKeepLocal | |
The behaviour now retains the offset when changing zones where possible | |
This affects DateTime.withZoneRetainFields and MutableDateTime.setZoneRetainFields | |
- DateTimeZone.getDefault [3048468,3056104] | |
Handle missing user.timezone system property on Android that resulted in stack overflow | |
- DateTimeZone.forTimeZone [3216471] | |
Time-zone ID "MET" from java.util.TimeZone is now mapped correctly. | |
See compatibility notes above. | |
- Duration.toString | |
Fixed to work correctly for negative values | |
- Duraton.toPeriod(), new Period(long), new MutablePeriod(long) [3264409] | |
Fixed to obey Javadoc. | |
Previously, they didn't obey the Javadoc if the default time-zone had no daylight savings. | |
- Period formatting concurrency [2820871] | |
Fix possible concurrency hole in PeriodFormatBuilder.Separator | |
- Period formatter builder append(PeriodFormatter) did not handle some case [2495455] | |
If the appended formatter contained a separator as the first element, it failed | |
- Classloading CachedDateTimeZone could invalidate state [2935625] | |
Default time zone now lazily loaded | |
- DateTimeUtils shared static variable now volatile [2986043] | |
- DateTimeZone.forID(String) now case-sensitive | |
Previously, it was case-insensitive | |
- Handle broken serialization in other tools [3117678] | |
Some tools can't handle the joda-time stub serialization, kludge a fix for them | |
- Standard DateTimeFieldType implements hashCode and equals for stability across serialization | |
- Conversion from parsed values to a date-time handles weird sets of fields better [3161586] | |
This change is mostly for combinations like weekyear-month-week | |
The new code doesn't handle all combinations perfectly, but its better than it was | |
- Time zone compiler now handles 24:00 [2804258] | |
- Time zone compiler now handles non-UTC better | |
- Remove OSGi BundleExecutionEnvironment [3175068,3175612] | |
- Javadoc fix in Months [2721880] | |
- Javadoc fix in PeriodFormatterBuilder [3100939] | |
</source> | |
</p> | |
</section> | |
</body> | |
</document> |