joda-time 文档的部分翻译

Why Joda Time?

The standard date and time classes prior to Java SE 8 are poor(标准日期和时间类在jdk1.8之前是极差的). By tackling this problem head-on(为了迎面解决这个问题), Joda-Time became the de facto(事实上的) standard date and time library for Java prior to Java SE 8. Note that from Java SE 8 onwards, users are asked to migrate(迁移) to java.time (JSR-310) - a core part of the JDK which replaces this project.(JSR -Java Specification Requests 即Java规范要求

The design allows for multiple calendar systems, while still providing a simple API. The “default” calendar is the ISO8601 standard which is used by many other standards. The Gregorian, Julian, Buddhist, Coptic, Ethiopic and Islamic calendar systems are also included. Supporting classes include time zone(时区), duration(持续时间), format and parsing.

A selection of key features:   核心类的特点

  • LocalDate - date without time 
  • LocalTime - time without date
  • Instant - an instantaneous(瞬间的) point on the time-line
  • DateTime - full date and time with time-zone
  • DateTimeZone - a better time-zone
  • Duration(持续时间)and Period (一段时间)- amounts of time
  • Interval(间隔)- the time between two instants
  • A comprehensive and flexible formatter-parser (一个全面而灵活的格式化-解析器)

1. The getting started guide (入门指南)

    

Quick start guide

This guide provides a quick introduction to Joda-Time. For more information, see the full user guide.

Date and Time

Date and time is a surprisingly complex domain. The many classes in Joda-Time are designed to allow the nuances of the domain to be fully expressed.

The five date-time classes that will be used most are:

  • Instant - Immutable class representing an instantaneous point on the time-line(表示时间线上瞬时点的不可变类)
  • DateTime - Immutable replacement for JDK Calendar
  • LocalDate - Immutable class representing a local date without a time (no time-zone)
  • LocalTime - Immutable class representing a time without a date (no time-zone)
  • LocalDateTime - Immutable class representing a local date and time (no time-zone)

An Instant(瞬间) is a good class to use for the timestamp of an event, as there is no calendar system or time-zone to worry about.

A LocalDate is a good class to use to represent a date of birth, as there is no need to refer to the time of day.

A LocalTime is a good class to use to represent the time of day that a shop opens or closes.

A DateTime is a good class to use as a general purpose replacement for the JDK Calendar class, where the time-zone information is important. For more detail, see the documentation on instants and partials.

Using the Date and Time classes

Each date-time class provides a variety of constructors. These include the Object constructor. This allows you to construct an instance from a variety of different objects: For example, a DateTime can be constructed from the following objects:

  • Date - a JDK instant
  • Calendar - a JDK calendar
  • String - in ISO8601 format
  • Long - in milliseconds
  • any Joda-Time date-time class

The use of an Object constructor is a little unusual(罕见的), but it is used because the list of types that can be converted(转换) is extensible(可延伸的). The main advantage is that converting from a JDK Date or Calendar to a Joda-Time class is easy - simply pass the JDK class into the constructor. For example, this code converts a java.util.Date to a DateTime: (如下例子 展示jdk 自带的Date与joda-time转换)

java.util.Date juDate = new Date();
  DateTime dt = new DateTime(juDate);

Each date-time class provides simple easy methods to access the date-time fields. For example, to access the month and year you can use:

DateTime dt = new DateTime();
  int month = dt.getMonthOfYear();  // where January is 1 and December is 12
  int year = dt.getYear();

 

All the main date-time classes are immutable, like String, and cannot be changed after creation. However, simple methods have been provided to alter field values in a newly created object. For example, to set the year, or add 2 hours you can use:

DateTime dt = new DateTime();
  DateTime year2000 = dt.withYear(2000);
  DateTime twoHoursLater = dt.plusHours(2);

In addition to the basic get methods, each date-time class provides property methods for each field. These provide access to the full wealth of Joda-Time functionality. For example, to access details about a month or year:

DateTime dt = new DateTime();
  String monthName = dt.monthOfYear().getAsText();
  String frenchShortName = dt.monthOfYear().getAsShortText(Locale.FRENCH);
  boolean isLeapYear = dt.year().isLeap();
  DateTime rounded = dt.dayOfMonth().roundFloorCopy();

Calendar systems and time-zones

Joda-Time provides support for multiple calendar systems and the full range of time-zones. The Chronology and DateTimeZone classes provide this support.

Joda-Time defaults to using the ISO calendar system, which is the de facto civil calendar used by the world. The default time-zone is the same as the default of the JDK. These default values can be overridden whenever necessary. Please note that the ISO calendar system is historically inaccurate before 1583.

Joda-Time uses a pluggable(可插拔的) mechanism(机制) for calendars. By contrast(对比), the JDK uses subclasses (子类)such as GregorianCalendar(公历日历). This code obtains a Joda-Time chronology by calling one of the factory methods on the Chronology(年表) implementation:

Chronology coptic = CopticChronology.getInstance();

Time zones are implemented as part of the chronology. The code obtains a Joda-Time chronology in the Tokyo time-zone:

DateTimeZone zone = DateTimeZone.forID("Asia/Tokyo");
  Chronology gregorianJuian = GJChronology.getInstance(zone);

Intervals and time periods

Joda-Time provides support for intervals and time periods.

An interval is represented by the Interval class. It holds a start and end date-time, and allows operations based around that range of time.

A time period is represented by the Period class. This holds a period such as 6 months, 3 days and 7 hours. You can create a Period directly, or derive it from an interval.

A time duration is represented by the Duration class. This holds an exact duration in milliseconds. You can create a Duration directly, or derive it from an interval.

Although a period and a duration may seem similar, they operate differently. For example, consider adding one day to a DateTime at the daylight savings cutover:

DateTime dt = new DateTime(2005, 3, 26, 12, 0, 0, 0);
  DateTime plusPeriod = dt.plus(Period.days(1));
  DateTime plusDuration = dt.plus(new Duration(24L*60L*60L*1000L));

Adding a period will add 23 hours in this case, not 24 because of the daylight savings change, thus the time of the result will still be midday. Adding a duration will add 24 hours no matter what, thus the time of the result will change to 13:00.

More information

See the following for more information:

 

2.The helpful user guide

Introduction

Joda-Time is like an iceberg, 9/10ths of it is invisible to user-code. Many, perhaps most, applications will never need to see what's below the surface. This document provides an introduction to the Joda-Time API for the average user, not for the would-be API developer.

The bulk of the text is devoted to code snippets that display the most common usage scenarios in which the library classes are used. In particular, we cover the usage of the key DateTime, Interval, Duration and Period classes.

We finish with a look at the important topic of formatting and parsing and a few more advanced topics.

 

Architecture Overview

The major building blocks of Joda-Time are introduced below. These are the concepts of instantintervaldurationperiodchronology and timezones. We then say a few words about the role of interfaces in the library design, which is a little different than the norm. We end with a few words on package structure. Usage examples for instant are delayed until the following sections of the guide. Examples for interval, duration and period may be found in the appropriate section in the "Key Concepts" part of the documentation.

Instants

The most frequently used concept in Joda-Time is that of the instant. An Instant is defined as a moment in the datetime continuum specified as a number of milliseconds from 1970-01-01T00:00Z. This definition of milliseconds is consistent with that of the JDK in Date or Calendar. Interoperating between the two APIs is thus simple.

Within Joda-Time an instant is represented by the ReadableInstant interface. The main implementation of this interface, and the class that the average API user needs to be most familiar with, is DateTime. DateTime is immutable - and once created the values do not change. Thus, this class can safely be passed around and used in multiple threads without synchronization.

The millisecond instant can be converted to any date time field using a Chronology. To assist with this, methods are provided on DateTime that act as getters for the most common date and time fields.

We discuss the chronology concept a litte further on in this overview.

A companion mutable class to DateTime is MutableDateTime. Objects of this class can be modified and are not thread-safe.

Other implementations of ReadableInstant include Instant and the deprecated DateMidnight.

Fields

The main API of DateTime has been kept small, limited to just get methods for each calendar field. So, for instance, the 'day-of-year' calendar field would be retrieved by calling the getDayOfYear() method. For a complete list of fields and their descriptions, see the field reference.

Properties

There is much more power available, however, through the use of what is termed a property. Each calendar field is associated with such a property. Thus, 'day-of-year', whose value is directly returned by the method getDayOfYear(), is also associated with the property returned by the dayOfYear() method. The property class associated with DateTime is DateTime.Property.

Knowing the methods on the property is the secret to making the most of the API. We have more to say on the usage of properties later in this document.

Intervals

An interval in Joda-Time represents an interval of time from one instant to another instant. Both instants are fully specified instants in the datetime continuum, complete with time zone.

Intervals are implemented as half-open, which is to say that the start instant is inclusive but the end instant is exclusive. The end is always greater than or equal to the start. Both end-points are restricted to having the same chronology and the same time zone.

Two implementations are provided, Interval and MutableInterval, both are specializations of ReadableInterval.

Durations

duration in Joda-Time represents a duration of time measured in milliseconds. The duration is often obtained from an interval.

Durations are a very simple concept, and the implementation is also simple. They have no chronology or time zone, and consist solely of the millisecond duration.

Durations can be added to an instant, or to either end of an interval to change those objects. In datetime maths you could say:

instant  +  duration  =  instant

Currently, there is only one implementation of the ReadableDuration interface: Duration.

Periods

period in Joda-Time represents a period of time defined in terms of fields, for example, 3 years 5 months 2 days and 7 hours. This differs from a duration in that it is inexact in terms of milliseconds. A period can only be resolved to an exact number of milliseconds by specifying the instant (including chronology and time zone) it is relative to.

For example, consider a period of 1 month. If you add this period to the 1st February (ISO) then you will get the 1st March. If you add the same period to the 1st March you will get the 1st April. But the duration added (in milliseconds) in these two cases is very different.

As a second example, consider adding 1 day at the daylight savings boundary. If you use a period to do the addition then either 23 or 25 hours will be added as appropriate. If you had created a duration equal to 24 hours, then you would end up with the wrong result.

Periods are implemented as a set of int fields. The standard set of fields in a period are years, months, weeks, days, hours, minutes, seconds and millis. The PeriodType class allows this set of fields to be restricted, for example to elimate weeks. This is significant when converting a duration or interval to a period, as the calculation needs to know which period fields it should populate.

Methods exist on periods to obtain each field value. Periods are not associated with either a chronology or a time zone.

Periods can be added to an instant, or to either end of an interval to change those objects. In datetime maths you could say:

instant  +  period  =  instant

There are two implementations of the ReadablePeriod interface, Period and MutablePeriod.

Chronology

The Joda-Time design is based around the Chronology. It is a calculation engine that supports the complex rules for a calendar system. It encapsulates the field objects, which are used on demand to split the absolute time instant into recognisable calendar fields like 'day-of-week'. It is effectively a pluggable calendar system.

The actual calculations of the chronology are split between the Chronology class itself and the field classes - DateTimeField and DurationField. Together, the subclasses of these three classes form the bulk of the code in the library. Most users will never need to use or refer directly to the subclasses. Instead, they will simply obtain the chronology and use it as a singleton, as follows:

Chronology coptic = CopticChronology.getInstance();

Internally, all the chronology, field, etc. classes are maintained as singletons. Thus there is an initial setup cost when using Joda-Time, but after that only the main API instance classes (DateTime, Interval, Period, etc.) have creation and garbage collector costs.

Although the Chronology is key to the design, it is not key to using the API !!

For most applications, the Chronology can be ignored as it will default to the ISOChronology. This is suitable for most uses. You would change it if you need accurate dates before October 15, 1582, or whenever the Julian calendar ceased in the territory you're interested in. You'd also change it if you need a specific calendar like the Coptic calendar illustrated earlier.

TimeZones

The chronology class also supports the time zone functionality. This is applied to the underlying chronology via the decorator design pattern. The DateTimeZone class provides access to the zones primarily through one factory method, as follows:

DateTimeZone zone = DateTimeZone.forID("Europe/London");

In addition to named time zones, Joda-Time also supports fixed time zones. The simplest of these is UTC, which is defined as a constant:

DateTimeZone zoneUTC = DateTimeZone.UTC;

Other fixed offset time zones can be obtained by a specialise factory method:

DateTimeZone zoneUTC = DateTimeZone.forOffsetHours(hours);

The time zone implementation is based on data provided by the public IANA time zone database. A full list of time zone ids can be found here

Joda-Time provides a default time zone which is used in many operations when a time zone is not specified. This is similar in concept to the default time zone of the java.util.TimeZone class. The value can be accessed and updated via static methods:

DateTimeZone defaultZone = DateTimeZone.getDefault();
DateTimeZone.setDefault(myZone);

Interface usage

As you have seen, Joda-Time defines a number of new interfaces which are visible throughout the javadocs. The most important is ReadableInstant which currently has 4 implementations. Other significant interfaces include ReadableInterval and ReadablePeriod. These are currently used as generalizations for a value-only and a mutable class, respectively.

An important point to mention here is that the Joda interfaces are used differently than, for instance, the JDK Collections Framework interfaces. When working with a Collections interface, such as List or Map you will normally hold your variable as a type of List or Map, only referencing the concrete class when you create the object.

List list = new ArrayList();
    Map map = new HashMap();

In Joda-Time, the interfaces exist to allow interoperation between similar date implementations, such as a mutable and immutable version of a class. As such, they only offer a subset of the methods of the concrete class. For most work, you will reference the concrete class, not the interface. This gives access to the full power of the library.

DateTime dt = new DateTime();

For maximum flexibility however, you might choose to declare your method parameters using the Joda-Time interface. A method on the interface can obtain the concrete class for use within the method.

public void process(ReadableDateTime dateTime) {
        DateTime dt = dateTime.toDateTime();
    }

Package structure

The package structure is designed to separate the methods in the public API from the private API. The public packages are the root package (under org.joda.time) and the format package. The private packages are the base, chrono, convert, field and tz packages. Most applications should not need to import classes from the private packages.

Working with DateTime

 

Construction

A datetime object is created by using a DateTime constructor. The default constructor is used as follows

DateTime dt = new DateTime();

and creates a datetime object representing the current date and time in milliseconds as determined by the system clock. It is constructed using the ISO calendar in the default time zone.

To create a datetime object representing a specific date and time, you may use an initialization string:

DateTime dt = new DateTime("2004-12-13T21:39:45.618-08:00");

The initialization string must be in a format that is compatible with the ISO8601 standard.

DateTime also provides other constructors to create a specific date and time using a variety of standard fields. This also permits the use of any calendar and timezone.

JDK Interoperability

The DateTime class has a constructor which takes an Object as input. In particular this constructor can be passed a JDK Date, JDK Calendar or JDK GregorianCalendar (It also accepts an ISO8601 formatted String, or Long object representing milliseconds). This is one half of the interoperability with the JDK. The other half of interoperability with JDK is provided by DateTime methods which return JDK objects.

Thus inter-conversion between Joda DateTime and JDK Date can be performed as follows

// from Joda to JDK
    DateTime dt = new DateTime();
    Date jdkDate = dt.toDate();

    // from JDK to Joda
    dt = new DateTime(jdkDate);

Similarly, for JDK Calendar:

// from Joda to JDK
    DateTime dt = new DateTime();
    Calendar jdkCal = dt.toCalendar(Locale.CHINESE);

    // from JDK to Joda
    dt = new DateTime(jdkCal);

and JDK GregorianCalendar:

// from Joda to JDK
    DateTime dt = new DateTime();
    GregorianCalendar jdkGCal = dt.toGregorianCalendar();

    // from JDK to Joda
    dt = new DateTime(jdkGCal);

Querying DateTimes

The separation of the calculation of calendar fields (DateTimeField) from the representation of the calendar instant (DateTime) makes for a powerful and flexible API. The connection between the two is maintained by the property (DateTime.Property) which provides access to the field.

For instance, the direct way to get the day of week for a particular DateTime, involves calling the method

int iDoW = dt.getDayOfWeek();

where iDoW can take the values (from class DateTimeConstants).

public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;
    public static final int SUNDAY = 7;

Accessing fields

The direct methods are fine for simple usage, but more flexibility can be achieved via the property/field mechanism. The day of week property is obtained by

DateTime.Property pDoW = dt.dayOfWeek();

which can be used to get richer information about the field, such as

String strST = pDoW.getAsShortText(); // returns "Mon", "Tue", etc.
    String strT = pDoW.getAsText(); // returns "Monday", "Tuesday", etc.

which return short and long name strings (based on the current locale) of the day-of-week. Localized versions of these methods are also available, thus

String strTF = pDoW.getAsText(Locale.FRENCH); // returns "Lundi", etc.

can be used to return the day-of-week name string in French.

Of course, the original integer value of the field is still accessible as

iDoW = pDoW.get();

The property also provides access to other values associated with the field such as metadata on the minimum and maximum text size, leap status, related durations, etc. For a complete reference, see the documentation for the base class AbstractReadableInstantFieldProperty.

In practice, one would not actually create the intermediate pDoW variable. The code is easier to read if the methods are called on anonymous intermediate objects. Thus, for example,

strT = dt.dayOfWeek().getAsText();
    iDoW = dt.dayOfWeek().get();

would be written instead of the more indirect code presented earlier.

Note: For the single case of getting the numerical value of a field, we recommend using the get method on the main DateTime object as it is more efficient.

iDoW = dt.getDayOfWeek();

Date fields

The DateTime implementation provides a complete list of standard calendar fields:

dt.getEra();
    dt.getYear();
    dt.getWeekyear();
    dt.getCenturyOfEra();
    dt.getYearOfEra();
    dt.getYearOfCentury();
    dt.getMonthOfYear();
    dt.getWeekOfWeekyear();
    dt.getDayOfYear();
    dt.getDayOfMonth();
    dt.getDayOfWeek();

Each of these also has a corresponding property method, which returns a DateTime.Property binding to the appropriate field, such as year() or monthOfYear(). The fields represented by these properties behave pretty much as their names would suggest. The precise definitions are available in the field reference.

As you would expect, all the methods we showed above in the day-of-week example can be applied to any of these properties. For example, to extract the standard month, day and year fields from a datetime, we can write

String month = dt.monthOfYear().getAsText();
    int maxDay = dt.dayOfMonth().getMaximumValue();
    boolean leapYear = dt.yearOfEra().isLeap();

Time fields

Another set of properties access fields representing intra-day durations for time calculations. Thus to compute the hours, minutes and seconds of the instant represented by a DateTime, we would write

int hour = dt.getHourOfDay();
    int min = dt.getMinuteOfHour();
    int sec = dt.getSecondOfMinute();

Again each of these has a corresponding property method for more complex manipulation. The complete list of time fields can be found in the field reference.

Manipulating DateTimes

DateTime objects have value semantics, and cannot be modified after construction (they are immutable). Therefore, most simple manipulation of a datetime object involves construction of a new datetime as a modified copy of the original.

WARNING: A common mistake to make with immutable classes is to forget to assign the result to a variable. Remember that calling an add or set method on an immtable object has no effect on that object - only the result is updated.

Modifying fields

One way to do this is to use methods on properties. To return to our prior example, if we wish to modify the dt object by changing its day-of-week field to Monday we can do so by using the setCopy method of the property:

DateTime result = dt.dayOfWeek().setCopy(DateTimeConstants.MONDAY);

Note: If the DateTime object is already set to Monday then the same object will be returned.

To add to a date you could use the addToCopy method.

DateTime result = dt.dayOfWeek().addToCopy(3);

DateTime methods

Another means of accomplishing similar calculations is to use methods on the DateTime object itself. Thus we could add 3 days to dt directly as follows:

DateTime result = dt.plusDays(3);

Using a MutableDateTime

The methods outlined above are suitable for simple calculations involving one or two fields. In situations where multiple fields need to be modified, it is more efficient to create a mutable copy of the datetime, modify the copy and finally create a new value datetime.

MutableDateTime mdt = dt.toMutableDateTime();
    // perform various calculations on mdt
    ...
    DateTime result = mdt.toDateTime();

MutableDateTime has a number of methods, including standard setters, for directly modifying the datetime.

Changing TimeZone

DateTime comes with support for a couple of common timezone calculations. For instance, if you want to get the local time in London at this very moment, you would do the following

// get current moment in default time zone
    DateTime dt = new DateTime();
    // translate to London local time
    DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));

where DateTimeZone.forID("Europe/London") returns the timezone value for London. The resulting value dtLondon has the same absolute millisecond time, but a different set of field values.

There is also support for the reverse operation, i.e. to get the datetime (absolute millisecond) corresponding to the moment when London has the same local time as exists in the default time zone now. This is done as follows

// get current moment in default time zone
    DateTime dt = new DateTime();
    // find the moment when London will have / had the same time
    dtLondonSameTime = dt.withZoneRetainFields(DateTimeZone.forID("Europe/London"));

A set of all TimeZone ID strings (such as "Europe/London") may be obtained by calling DateTimeZone.getAvailableIDs(). A full list of available time zones is provided here.

Changing Chronology

The DateTime class also has one method for changing calendars. This allows you to change the calendar for a given moment in time. Thus if you want to get the datetime for the current time, but in the Buddhist Calendar, you would do

// get current moment in default time zone
    DateTime dt = new DateTime();
    dt.getYear();  // returns 2004
    // change to Buddhist chronology
    DateTime dtBuddhist = dt.withChronology(BuddhistChronology.getInstance());
    dtBuddhist.getYear();  // returns 2547

where BuddhistChronology.getInstance is a factory method for obtaining a Buddhist chronology.

Input and Output

Reading date time information from external sources which have their own custom format is a frequent requirement for applications that have datetime computations. Writing to a custom format is also a common requirement.

Many custom formats can be represented by date-format strings which specify a sequence of calendar fields along with the representation (numeric, name string, etc) and the field length. For example the pattern "yyyy" would represent a 4 digit year. Other formats are not so easily represented. For example, the pattern "yy" for a two digit year does not uniquely identify the century it belongs to. On output, this will not cause problems, but there is a problem of interpretation on input.

In addition, there are several date/time serialization standards in common use today, in particular the ISO8601. These must also be supported by most datetime applications.

Joda-Time supports these different requirements through a flexible architecture. We will now describe the various elements of this architecture.

Formatters

All printing and parsing is performed using a DateTimeFormatter object. Given such an object fmt, parsing is performed as follows

String strInputDateTime;
    // string is populated with a date time string in some fashion
    ...
    DateTime dt = fmt.parseDateTime(strInputDateTime);

Thus a DateTime object is returned from the parse method of the formatter. Similarly, output is performed as

String strOutputDateTime = fmt.print(dt);

Standard Formatters

Support for standard formats based on ISO8601 is provided by the ISODateTimeFormat class. This provides a number of factory methods.

For example, if you wanted to use the ISO standard format for datetime, which is yyyy-MM-dd'T'HH:mm:ss.SSSZZ, you would initialize fmt as

DateTimeFormatter fmt = ISODateTimeFormat.dateTime();

You would then use fmt as described above, to read or write datetime objects in this format.

Custom Formatters

If you need a custom formatter which can be described in terms of a format pattern, you can use the factory method provided by the DateTimeFormat class. Thus to get a formatter for a 4 digit year, 2 digit month and 2 digit day of month, i.e. a format of yyyyMMdd you would do

DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");

The pattern string is compatible with JDK date patterns.

You may need to print or parse in a particular Locale. This is achieved by calling the withLocale method on a formatter, which returns another formatter based on the original.

DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");
    DateTimeFormatter frenchFmt = fmt.withLocale(Locale.FRENCH);
    DateTimeFormatter germanFmt = fmt.withLocale(Locale.GERMAN);

Formatters are immutable, so the original is not altered by the withLocale method.

Freaky Formatters

Finally, if you have a format that is not easily represented by a pattern string, Joda-Time architecture exposes a builder class that can be used to build a custom formatter which is programatically defined. Thus if you wanted a formatter to print and parse dates of the form "22-Jan-65", you could do the following:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
            .appendDayOfMonth(2)
            .appendLiteral('-')
            .appendMonthOfYearShortText()
            .appendLiteral('-')
            .appendTwoDigitYear(1956)  // pivot = 1956
            .toFormatter();

Each append method appends a new field to be parsed/printed to the calling builder and returns a new builder. The final toFormatter method creates the actual formatter that will be used to print/parse.

What is particularly interesting about this format is the two digit year. Since the interpretation of a two digit year is ambiguous, the appendTwoDigitYear takes an extra parameter that defines the 100 year range of the two digits, by specifying the mid point of the range. In this example the range will be (1956 - 50) = 1906, to (1956 + 49) = 2005. Thus 04 will be 2004 but 07 will be 1907. This kind of conversion is not possible with ordinary format strings, highlighting the power of the Joda-Time formatting architecture.

Direct access

To simplify the access to the formatter architecture, methods have been provided on the datetime classes such as DateTime.

DateTime dt = new DateTime();
    String a = dt.toString();
    String b = dt.toString("dd:MM:yy");
    String c = dt.toString("EEE", Locale.FRENCH);
    DateTimeFormatter fmt = ...;
    String d = dt.toString(fmt);

Each of the four results demonstrates a different way to use the formatters. Result a is the standard ISO8601 string for the DateTime. Result b will output using the pattern 'dd:MM:yy' (note that patterns are cached internally). Result c will output using the pattern 'EEE' in French. Result d will output using the specified formatter, and is thus the same as fmt.print(dt).

Advanced features

Change the Current Time

Joda-Time allows you to change the current time. All methods that get the current time are indirected via DateTimeUtils. This allows the current time to be changed, which can be very useful for testing.

// always return the same time when querying current time
    DateTimeUtils.setCurrentMillisFixed(millis);
    // offset the real time
    DateTimeUtils.setCurrentMillisOffset(millis);

Note that changing the current time this way does not affect the system clock.

Converters

The constructors on each major concrete class in the API take an Object as a parameter. This is passed to the converter subsystem which is responsible for converting the object to one acceptable to Joda-Time. For example, the converters can convert a JDK Date object to a DateTime. If required, you can add your own converters to those supplied in Joda-Time.

Security

Joda-Time includes hooks into the standard JDK security scheme for sensitive changes. These include changing the time zone handler, changing the current time and changing the converters. See JodaTimePermission for details.

 

 

 

 

3.The key concepts and chronology guides

   3.1 

Key concepts

Documentation on the key concepts in Joda-Time:

Instant

The most frequently used concept in Joda-Time is that of the instant. An Instant is defined as an instant in the datetime continuum specified as a number of milliseconds from 1970-01-01T00:00Z. This definition of milliseconds is consistent with that of the JDK in Date or Calendar. Interoperating between the two APIs is thus simple.

The millisecond instant can be converted to any date time field using a Chronology. To assist with this, methods are provided on DateTime that act as getters for the most common date and time fields. More powerful access to the field can be obtained via its property.

DateTime dt = new DateTime();  // current time
int month = dt.getMonth();     // gets the current month
int month = dt.month().get();  // alternative way to get value
String monthStr = dt.month().getAsText();  // gets the month name

To deal with local times (no time zone), or with date only or time only concepts, you should use the partial classes.

Using Instants in Joda-Time

Within Joda-Time an instant is represented by the ReadableInstant interface. There are four implementations of the interface provided:

  • Instant - A simple immutable implementation which is restricted to the UTC time zone and is intended for time zone and calendar neutral data transfer
  • DateTime - The most commonly used class in the library, and an immutable representation of a date and time with calendar and time zone
  • MutableDateTime - A mutable representation of date and time with calendar and time zone
  • DateMidnight - A deprecated implementation, similar to DateTime but with the time component forced to be midnight (at the start of a day)

We recommend the immutable implementations for general usage.

The code can be used in various ways:

// setup date object for midday on Christmas 2004 (ISO year 2004)
DateTime dt = new DateTime(2004, 12, 25, 12, 0, 0, 0);
// get the year, 2004
int year = dt.getYear();
// get the day of week index 1 (Monday) to 7 (Sunday)
int dow = dt.getDayOfWeek();
// get the text, such as 'Tuesday'
String dowStr = dt.dayOfWeek().getAsText();

Compared to GregorianCalendar Joda-Time classes use 1-12 for months, and are immutable in the standard implementations. It is also easy to convert to and from the JDK classes.

// construct DateTime from JDK Date
Date jdkDate = new Date();
DateTime dt = new DateTime(jdkDate);

// construct Calendar from DateTime (could also construct a Date)
GregorianCalendar cal = dt.toGregorianCalendar();

Note that the interface ReadableInstant should not be used like the collections API. The interface only contains the core subset of the operations of DateTime. You should use the interface only when you feel the need to be flexible about future changes to the object passed into a method. You might also want to consider the ReadableDateTime interface which extends ReadableInstant to provide additional methods.

Nulls

Joda-Time defines a null instant as the current time. Thus, when a method is defined as taking a ReadableInstant, passing null in will be the same as passing in an instant set to the current time.

    

Partial

partial in Joda-Time is a partial date and time representation. All implementations represent local dates and times, and do not reference a time zone. As such, they only partiallyrepresent a date or time in the datetime continuum.

The main implementations changed in version 1.3. This was to address implementation issues with the original design. The previous classes - TimeofDay and YearMonthDay - are now effectively deprecated. The new implementations are LocalDate, LocalTime and LocalDateTime.

It is not possible to directly interoperate between a partial and an instant. A partial does not fully specify a single point in the datetime continuum, but instead may match multiple points. For example, a LocalTime occurs once per day on the datetime continuum.

A partial can be converted to a full instant by specifying the missing values. At a minimum the time zone must be specified. It may be necessary to specify other missing fields. For example, to convert a LocalDate to a DateTime requires filling in the time fields and the time zone.

In terms of datetime maths, you could write:

partial  +  missing fields  +  time zone  =  instant

Date representations

Two classes represent a date in Joda-Time - DateMidnight and LocalDate. These have different meanings. DateMidnight is a fully specified instant, with a time zone. It is defined as the millisecond instant at exactly mignight (00:00) at the start of a day. LocalDate defines a day using the year, monthOfYear and dayOfMonth fields and no time zone. It can be thought of as a local date that covers the whole of the day from 00:00 to 23:59.

Using Partials in Joda-Time

Within Joda-Time a partial is represented by the ReadablePartial interface. There are six implementations of the interface provided:

  • LocalDate - An immutable implementation that represents a date without a time or time zone.
  • LocalTime - An immutable implementation that represents a time without a date or time zone.
  • LocalDateTime - An immutable implementation that represents a datetime without a time zone.
  • YearMonth - An immutable implementation that represents a year and month, useful for credit card expiry dates.
  • MonthDay - An immutable implementation that represents a month and day, useful for birthdays without years.
  • Partial - An immutable implementation that can store any combination of datetime fields. For example, using this class you could create a YearMonth or DayOfWeekDayOfMonth partial.
  • YearMonthDay - Effectively deprecated - only supports the year, monthOfYear and dayOfMonth fields.
  • TimeOfDay - Effectively deprecated - only supports the hour, minute, second and millisecond fields.

The code can be used in various ways:

// setup objects
LocalDate date = new LocalDate(2004, 12, 25);
LocalTime time = new LocalTime(12, 20);

int year = date.getYear();  // returns 2004
int hour = time.getHour();  // returns 12
String monthStr = date.month().getAsText();  // returns 'December'

Conversion to and from instants is easy:

LocalDate date = new LocalDate(2004, 12, 25);
LocalTime time = new LocalTime(12, 20);

// merge, resulting in 2004-25-12T12:20 (default time zone)
DateTime dt = date.toDateTime(time);

// extract the date fields from someDT
DateTime someDT = ...
LocalDate date = new LocalDate(someDT);

Note that the interface ReadablePartial should not be used like the collections API. The interface only contains the core subset of the operations. Instead, you should refer directly to the implementation classes in your APIs.

Nulls

Joda-Time defines a null partial as the current time. Thus, when a method is defined as taking a ReadablePartial, passing null in will be the same as passing in a partial set to the current time.

 

Interval

An interval in Joda-Time represents an interval of time from one millisecond instant to another instant. Both instants are fully specified instants in the datetime continuum, complete with time zone.

Intervals are implemented as half-open, which is to say that the start instant is inclusive but the end instant is exclusive. The end is always greater than or equal to the start. The interval is also restricted to just one chronology and time zone.

Methods exist on intervals to obtain the start and end instants plus the chronology and time zone. There are also methods to obtain the duration and period of the interval.

You cannot compare intervals for order (i.e., they do not implement Comparable). If you want to compare the length of intervals you must obtain the duration of each and compare those.

Using Intervals in Joda-Time

Within Joda-Time an interval is represented by the ReadableInterval interface. There are two implementations of the interface provided:

We recommend the immutable implementation for general usage.

The code can be used in various ways:

// interval from start to end
DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);
Interval interval = new Interval(start, end);

Accessing other objects is easy:

Interval interval = ...
DateTime start = interval.getStart();
DateTime end = interval.getEnd();
Chronology chrono = interval.getChronology();
Duration duration = interval.toDuration();
Period period = interval.toPeriod();

Note that the interface ReadableInterval should not be used like the collections API. The interface only contains the core subset of the operations. Instead, you should usually refer directly to the implementation classes in your APIs.

Nulls

Joda-Time defines a null interval as a zero length interval from now to now. Thus, when a method is defined as taking a ReadableInterval, passing null in will be the same as passing in a zero length interval at the current time.

 

Duration

duration in Joda-Time represents a duration of time measured in milliseconds. The duration is often obtained from an interval.

Durations are a very simple concept, and the implementation is also simple. They have no chronology or time zone, and consist solely of the millisecond duration.

Durations can be added to an instant, or to either end of an interval to change those objects. In datetime maths you could say:

instant  +  duration  =  instant

Durations implement Comparable which compares the lengths of the two durations.

Using Durations in Joda-Time

Within Joda-Time a duration is represented by the ReadableDuration interface. There is one implementation of the interface provided:

The code can be used in various ways:

DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);

// duration in ms between two instants
Duration dur = new Duration(start, end);

// calc will be the same as end
DateTime calc = start.plus(dur);

Note that the interface ReadableDuration should not be used like the collections API. The interface only contains the core subset of the operations. Instead, you should usually refer directly to the implementation class in your APIs.

Directionality

Joda-Time durations can be negative. For example, the duration between 14:00 and 15:00 on the same day is 1 hour (PT1H), but the duration between 15:00 and 14:00 is minus 1 hour (PT-1H).

Negative durations will affect the results of comparisons. The equals, hashCode, compareTo, isLongerThan, isShorterThan and isEqualTo methods all take the sign of the duration into account. As such, a duration of minus 2 hours (PT-2H) is shorter than a duration of 1 hour (PT1H).

The Duration class has an abs method that will convert a negative duration to a position one if desired.

Nulls

Joda-Time defines a null duration as zero length. Thus, when a method is defined as taking a ReadableDuration, passing null in will be the same as passing in a zero length duration.

 

Period

period in Joda-Time represents a period of time defined in terms of fields, for example, 3 years 5 months 2 days and 7 hours. This differs from a duration in that it is inexact in terms of milliseconds. A period can only be resolved to an exact number of milliseconds by specifying the instant (including chronology and time zone) it is relative to.

Periods do not have a chronology or time zone. They can be added to an instant, or to either end of an interval to change those objects. In datetime maths you could say:

instant  +  period  =  instant

For example, consider a period of 1 month. If you add this period to the 1st February (ISO) then you will get the 1st March. If you add the same period to the 1st March you will get the 1st April. But the duration added (in milliseconds) in these two cases is very different.

As a second example, consider adding 1 day at the daylight savings boundary. If you use a period to do the addition then either 23 or 25 hours will be added as appropriate. If you had created a duration equal to 24 hours, then you would end up with the wrong result.

The Joda-Time library defines two types of implementation of the period concept. The first type can only store a single-field, such as days or hours, but not both. The second type can store any-field, expressing a value such as 5 months 8 days and 7 hours.

Single field Periods

The first type, single-field periods, is new to version 1.4 of Joda-Time. These classes - Years, Months, Weeks, Days, Hours, Minutes, Seconds - all follow a very similar design, and only store the single field as implied by their name. Thus a Days object can only store a number of days.

These classes can be useful when you want to write an API that must specifically take in a period measured in a particular unit. For example, a travel website where you are given the option of travelling ±1 days or ±3 days could store this information in a Days object.

These classes provide static factory methods rather than constructors. For Days these include daysBetween(startDate, endDate) to obtain the number of whole days between two dates or datetimes, and daysIn(interval) to obtain the number of whole days in an interval. In addition, there are a range of constants, such as Days.ZERO and Days.ONE. The factory method days(int) either returns a constant, or creates a new instance as appropriate.

The single-field classes include basic mathemaical operator support. For Days this includes plus(int), plus(Days), multipliedBy(int), dividedBy(int) and negated(). All operations return a new instance, as Days is immutable. The single-field classes are also comparable.

Converting between different types of period is a difficult problem. One day is not always equal to 24 hours. (It might be 23 or 25 at daylight savings time change.) However, many applications have business rules that assume a 24 hour day and so on. To support this, Days has methods named toStandardHours() and so on which convert the number of days to a number of hours assuming a 24 hour day. The word 'standard' is being specifically used in the method name to remind users of the assumption.

Any field Periods

The second type of period is the any-field period. These are implemented by the Period and MutablePeriod classes. Internally, they store a set of int fields, one for each field. The standard set of fields in a period are years, months, weeks, days, hours, minutes, seconds and millis. The PeriodType class allows this set of fields to be restricted, for example to elimate weeks. This is significant when converting a duration or interval to a period, as the calculation needs to know which period fields it should populate.

The Period class is useful when you want to write an API that can take a period that probably contains more than one field. However, to be even more general, your API could define itself to accept a ReadablePeriod, and then the calling code could pass in either a Period or a single field period like Days.

Methods exist on Period to obtain each field value. There are also methods to change a field value, such as withDays(int). They are named 'with' as they return a new Periodobject, due to immutability.

You cannot compare any-field periods for order, as there is no sensible comparison strategy. Instead, you need to convert the period to a Duration based on a specific date and then compare the duration.

Using Periods in Joda-Time

Within Joda-Time a period is represented by the ReadablePeriod interface. There are nine implementations of the interface provided:

  • Period - An immutable implementation
  • MutablePeriod - A mutable implementation
  • Years - An immutable years-only implementation
  • Months - An immutable months-only implementation
  • Weeks - An immutable weeks-only implementation
  • Days - An immutable days-only implementation
  • Hours - An immutable hours-only implementation
  • Minutes - An immutable minutes-only implementation
  • Seconds - An immutable seconds-only implementation

We recommend the immutable implementation for general usage.

The code can be used in various ways:

DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2006, 1, 1, 0, 0, 0, 0);

// period of 1 year and 7 days
Period period = new Period(start, end);

// calc will equal end
DateTime calc = start.plus(period);

// able to calculate whole days between two dates easily
Days days = Days.daysBetween(start, end);

// able to calculate whole months between two dates easily
Months months = Months.monthsBetween(start, end);

Note that the interface ReadablePeriod should not be used like the collections API. The interface only contains the core subset of the operations. Instead, you should usually refer directly to the implementation classes in your APIs.

Nulls

Joda-Time defines a null period as a zero length period. Thus, when a method is defined as taking a ReadablePeriod, passing null in will be the same as passing in a zero length period.

 

Chronology

chronology in Joda-Time is a pluggable calendar system. The JDK supports multiple calendar systems via subclasses of Calendar. This is clunky, and in practice it is very difficult to write another calendar system. Joda-Time supports multiple calendar systems by designing a pluggable system.

The default chronology in Joda-Time is ISO. This calendar system is the same as that used by business in the majority of the world today. The ISO system is unsuitable for historical work before 1583 as it applies the leap year rules from today back in time (it is a proleptic calendar). As a result, users requiring a more historically accurate calendar system are forced to think about their actual requirements, which we believe is a Good Thing.

The actual calculations of the chronology are split between the Chronology class itself and the field classes - DateTimeField and DurationField. Together, the subclasses of these three classes form the bulk of the code in the library. However, most users will never need to use or refer directly to the subclasses. Instead, most applications will simply obtain the chronology and use it as a singleton.

The chronology class also supports the time zone functionality. This is applied to the underlying chronology via the decorator design pattern. The DateTimeZone class provides access to the zones via factories, and also supports a default zone concept. A full list of time zones can be found here. It is also possible to update the zone data yourself.

Internally, all the chronology, field and time zone classes are maintained as singletons. Thus there is an initial setup cost when using Joda-Time, but after that only the main API instance classes (DateTime, Interval, Period, etc.) have creation and garbage collector costs.

Reference documentation is provided for each of the 8 calendar systems that Joda-Time includes.

Using Chronology in Joda-Time

A Chronology is obtained and used in Joda-Time as a singleton:

DateTimeZone zone = DateTimeZone.forID("Europe/London");
Chronology coptic = CopticChronology.getInstance(zone);

// current time with coptic chronology
DateTime dt = new DateTime(coptic);

int year = dt.getYear();   // gets the current coptic year
int month = dt.getMonthOfYear(); // gets the current coptic month

Nulls

A null chronology always refers to ISO chronology in the default zone. Thus, when a method is defined as taking a Chronology, passing null in will be the same as passing in the ISO chronology in the default time zone.

 

Formatting

Joda-Time provides a comprehensive formatting system. There are two layers:

  • High level - pre-packaged constant formatters
  • Mid level - pattern-based, like SimpleDateFormat
  • Low level - builder

Constant and Localized formatting

The class ISODateTimeFormat contains a large number of pre-defined formatters based on the ISO-8601 specification (although not all are fully compatible). These handle many common cases.

The class DateTimeFormat contains an additional set of pre-defined formatters based on Locale. These "style-based" formatters handle the case where the application needs to format a date-time in a manner appropriate to a particular global location.

Pattern-based formatting

The class DateTimeFormat provides a single method forPattern(String) that supports formatting by pattern. These "pattern-based" formatters provide a similar approach to that of SimpleDateFormat.

For example:

LocalDate date = LocalDate.now();
DateTimeFormatter fmt = DateTimeFormat.forPattern("d MMMM, yyyy");
String str = date.toString(fmt);
// might output "6 October, 2013"

The pattern letters are:

Symbol  Meaning                      Presentation  Examples
------  -------                      ------------  -------
 G       era                          text          AD
 C       century of era (>=0)         number        20
 Y       year of era (>=0)            year          1996

 x       weekyear                     year          1996
 w       week of weekyear             number        27
 e       day of week                  number        2
 E       day of week                  text          Tuesday; Tue

 y       year                         year          1996
 D       day of year                  number        189
 M       month of year                month         July; Jul; 07
 d       day of month                 number        10

 a       halfday of day               text          PM
 K       hour of halfday (0~11)       number        0
 h       clockhour of halfday (1~12)  number        12

 H       hour of day (0~23)           number        0
 k       clockhour of day (1~24)      number        24
 m       minute of hour               number        30
 s       second of minute             number        55
 S       fraction of second           number        978

 z       time zone                    text          Pacific Standard Time; PST
 Z       time zone offset/id          zone          -0800; -08:00; America/Los_Angeles

 '       escape for text              delimiter
 ''      single quote                 literal       '

The count of pattern letters determine the format.

Text: If the number of pattern letters is 4 or more, the full form is used; otherwise a short or abbreviated form is used if available. Thus, "EEEE" might output "Monday" whereas "E" might output "Mon" (the short form of Monday).

Number: The minimum number of digits. Shorter numbers are zero-padded to this amount. Thus, "HH" might output "09" whereas "H" might output "9" (for the hour-of-day of 9 in the morning).

Year: Numeric presentation for year and weekyear fields are handled specially. For example, if the count of 'y' is 2, the year will be displayed as the zero-based year of the century, which is two digits.

Month: 3 or over, use text, otherwise use number. Thus, "MM" might output "03" whereas "MMM" might output "Mar" (the short form of March) and "MMMM" might output "March".

Zone: 'Z' outputs offset without a colon, 'ZZ' outputs the offset with a colon, 'ZZZ' or more outputs the zone id.

Zone names: Time zone names ('z') cannot be parsed.

Any characters in the pattern that are not in the ranges of ['a'..'z'] and ['A'..'Z'] will be treated as quoted text. For instance, characters like ':', '.', ' ', '#' and '?' will appear in the resulting time text even they are not embraced within single quotes.

Builder

All formatting is ultimately built using DateTimeFormatterBuilder. The builder allows a format pattern to be built up step by step, consisting of literal, text, numeric, pattern and localized elements in any order. Some facilities are only available via the builder.

For example, this will build a formatter consisting of the month and year:

DateTimeFormatter monthAndYear = new DateTimeFormatterBuilder()
     .appendMonthOfYearText()
     .appendLiteral(' ')
     .appendYear(4, 4)
     .toFormatter();

Time zone updates

Time zones are a concept driven by the political situation in each country around the world. As such, they change frequently, and often at short notice. In order to manage this, Joda-Time uses the internationally recognised tz database, which is also used in most operating systems and the JDK itself.

Using JDK time zone data is a problem however, as the zones are only updated when the JDK is updated. This can cause issues if you are locked into an older version of the JDK.

Joda-Time also compiles the time zone data into our jar file. However, the key difference is that you can update the raw data and recompile the jar at any time.

Updating the time zone data

Firstly, download the latest version of the data files from tz database. Ensure you select the "Data" download which comes as a tar.gz.

Secondly, you need a source code download of Joda-Time.

Thirdly, you must take the time zone data files from step one, and replace those in the Joda-Time download. They are located at {root}/src/main/java/org/joda/time/tz/src. Note that only some of the files need to be copied across.

Fourthly, change the version number in the pom.xml file to indicate that it is a non-standard release.

Finally, recompile the Joda-Time jar file using maven. Simply type mvn package in the root directory.

 

3.2   Calendar systems

Joda-Time provide 8 calendar systems:

Buddhist calendar system

The Buddhist calendar system implemented in Joda-Time is based on that supplied in the private Sun packages of a typical JDK. It differs from the GregorianJulian calendar only in the year and era. The Buddhist calendar has one era (the current era), and has a year offset by 543 from the current Gregorian year.

It appears that Sun developed the Buddhist Calendar system to meet the needs of Thailand. However, the calendar is only accurate from 1941-01-01 (ISO). Before that date Thailand used three other calendar systems. The BuddhistChronology follows the design of the BuddhistCalendar. It is hoped that in the future an accurate Thai chronology can be developed.

References

Using Buddhist chronology in Joda-Time

Within Joda-Time the Buddhist calendar system can be used by obtaining an instance of BuddhistChronology. This is normally created using the factory method BuddhistChronology.getInstance(). This is then passed into the constructors of the main date and time classes.

// setup date object for midday on May Day 2004 (ISO year 2004)
DateTime dtISO = new DateTime(2004, 5, 1, 12, 0, 0, 0);

// find out what the same instant is using the Buddhist Chronology
DateTime dtBudd = dtISO.withChronology(BuddhistChronology.getInstance());

 

Coptic calendar system

The Coptic calendar system is based on that used in ancient Egypt. It is sometimes referred to as the Alexandrian Calendar. The calendar system is in use today by the Coptic Orthodox Church and by farmers tracking the seasons in Egypt.

The Coptic calendar system consists of 12 months of exactly 30 days, followed by a 5 or 6 day intercalary month making a year of 365 or 366 days. Leap years (6 day intercalary month) occur every 4 years without exception (as per the Julian calendar). They occur when the remainder left after dividing the Coptic year by four is 3. The Coptic year starts on Septamber 11th/12th depending on leap years. The epoch date for the calendar is 0284-08-29 (Julian), which therefore is 0001-01-01 (Coptic). The current era is 'AM' (Anno Martyrum or Year of the Martyrs).

Joda-Time implements the rules described above. We model the 5 or 6 day intercalary month as month 13. We also prevent the entry of dates before year 1.

References

Using Coptic chronology in Joda-Time

Within Joda-Time the Coptic calendar system can be used by obtaining an instance of CopticChronology. This is normally created using the factory method CopticChronology.getInstance(). This is then passed into the constructors of the main date and time classes.

// setup date object for midday on May Day 2004 (ISO year 2004)
DateTime dtISO = new DateTime(2004, 5, 1, 12, 0, 0, 0);

// find out what the same instant is using the Coptic Chronology
DateTime dtCopt = dtISO.withChronology(CopticChronology.getInstance());

 

Ethiopic calendar system

The Ethiopic calendar system is similiar to the Coptic calendar and based on that used in ancient Egypt. The calendar system is in use today in Ethiopia.

The Ethiopic calendar system consists of 12 months of exactly 30 days, followed by a 5 or 6 day intercalary month making a year of 365 or 366 days. Leap years (6 day intercalary month) occur every 4 years without exception (as per the Julian calendar). They occur when the remainder left after dividing the Ethiopic year by four is 3. The Ethiopic year starts on Septamber 11th/12th depending on leap years. The epoch date for the calendar is 0008-08-29 (Julian), which therefore is 0001-01-01 (Ethiopic). The current era is 'EE' (Ethiopian Era).

Joda-Time implements the rules described above. We model the 5 or 6 day intercalary month as month 13. We also prevent the entry of dates before year 1.

References

Using Ethiopic chronology in Joda-Time

Within Joda-Time the Ethiopic calendar system can be used by obtaining an instance of EthiopicChronology. This is normally created via the EthiopicChronology.getInstance()factory. The chronology is then passed into the constructors of the main date and time classes.

// setup date object for midday on May Day 2004 (ISO year 2004)
DateTime dtISO = new DateTime(2004, 5, 1, 12, 0, 0, 0);

// find out what the same instant is using the Ethiopic Chronology
DateTime dtEthiopic = dtISO.withChronology(EthiopicChronology.getInstance());

 

GregorianJulian (GJ) calendar system

The GregorianJulian calendar system is the fusion of the two calendar systems in the Christian or Roman tradition. This calendar system is widely used today throughout the world, and is especially useful for historical work.

The GregorianJulian calendar is a combination of two separate calendar systems, the Gregorian and the Julian. The switch from one to the other occurs at a configurable date. The default date is 1582-10-15, as defined by Pope Gregory XIII.

The two calendar systems differ mainly in their accuracy of recording leap years. The Julian calendar defines a leap year as being once every four years. The Gregorian calendar adds two extra rules to state that years divisible by 100 are not leap, but those divisible by 400 are.

Joda-Time defines this calendar system using the GJChronology. This is a replacement for the JDK GregorianCalendar. If you intend to only refer to modern dates (after 1583) then you should use the Joda-Time default of ISO chronology.

References

Using GregorianJulian in Joda-Time

Within Joda-Time the GregorianJulian calendar system can be used by obtaining an instance of GJChronology. This is normally created using the factory method GJChronology.getInstance(). This is then passed into the constructors of the main date and time classes.

// setup date object for the Battle of Hastings in 1066
Chronology chrono = GJChronology.getInstance();
DateTime dt = new DateTime(1066, 10, 14, 10, 0, 0, 0, chrono);

If you want to change the cutover date between Julian and Gregorian, you will need to use the other factory methods on GJChronology.

Gregorian calendar system

The Gregorian calendar system is calendar system used by most of the modern business world. It was first introduced on 1582-10-15 replacing the Julian calendar. Gregorian rules define a leap year as once every four years, except every 100, but including every 400.

The Gregorian chronology in Joda-Time is equivalent* to the ISO chronology, and uses Gregorian rules for all time. Thus it is not historically accurate before 1583. This also means that the Gregorian chronology does not correspond to the java class GregorianCalendar. See GregorianJulian for a suitable replacement.

* The Gregorian and ISO chronologies do in fact differ slightly. The Gregorian chronology defines a century as it is spoken, thus 2005 is in the 21st century. The ISO chronology defines a century as the first two digits of the year, thus 2005 has a century field of 20.

References

Using Gregorian chronology in Joda-Time

Within Joda-Time the Gregorian calendar system can be used by obtaining an instance of GregorianChronology. This is normally created using the factory method GregorianChronology.getInstance(). This is then passed into the constructors of the main date and time classes.

// setup date object for midday on Christmas 2004
Chronology chrono = GregorianChronology.getInstance();
DateTime dt = new DateTime(2004, 12, 25, 12, 0, 0, 0, chrono);

 

Islamic calendar system

The Islamic, or Hijri, calendar system is a Lunar calendar used in many Muslim countries.

The Islamic calendar system is a lunar calendar based on observation. The observation aspect of the calendar means that a new month can only be declared based on human observations of the moon, something which can obviously vary and is unsuited to computer calculation.

Joda-Time implements the arithmetic Islamic calendar, which is an approximation of the actual calendar. There are 12 months, each of 29 or 30 days, making a year of 354 days, or 355 in a leap year. The days in the month alternate, with the first month having 30 days, the second 29 days and so on. In a leap year, the twelfth month has 30 days instead of the normal 29.

The definition of a leap year in the Islamic calendar varies. All agree on a 30 year cycle, however which years within the 30 are leap varies by the leap year pattern:

15-based2, 5, 7, 10, 13, 15, 18, 21, 24, 26, 29
16-based2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29
Indian2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29
Habash al-Hasib2, 5, 8, 11, 13, 16, 19, 21, 24, 27, 30

Joda-Time allows you to choose between these leap year patterns. The 16-based algorithm is the most commonly used, and is the default. Note that Microsoft uses the 15-based pattern, and calls it the 'Kuwaiti algorithm'.

The epoch of the calendar system is 0622-07-16 (Julian) which is therefore 0001-01-01 (Islamic). The current (and only implemented) era is 'AH' (Anno Hegirae).

Days of the week are named 'the first day', 'the second day' and so on, where Sunday is the first day. The day of the week value (numeric) returned by Joda-Time however, is the same as the ISO day of week definition. Thus Sunday will return the numeric value 7, and Monday will return the numeric value 1.

A day in the Islamic calendar begins at sunset on the previous 'day'. Joda-Time does not model this, thus times and date rollover follow standard ISO definitions, in other words starting at midnight.

References

Using Islamic chronology in Joda-Time

Within Joda-Time the Islamic calendar system can be used by obtaining an instance of IslamicChronology. This is normally created via the IslamicChronology.getInstance() factory. The chronology is then passed into the constructors of the main date and time classes.

// setup date object for midday on May Day 2004 (ISO year 2004)
DateTime dtISO = new DateTime(2004, 5, 1, 12, 0, 0, 0);

// find out what the same instant is using the Islamic Chronology
DateTime dtIslamic = dtISO.withChronology(IslamicChronology.getInstance());

ISO8601 Java calendar system

The ISO 8601 calendar system is the default implementation within Joda-Time. The standard formalises the Gregorian calendar system used by the modern business world.

The ISO8601 standard was created by the International Organization for Standards based in Geneva. It aims to eliminate the risk of misinterpretting dates and times when representations are passed between systems and across national boundaries. We are unable to provide a direct link to the standard as it is a paid-for document.

The ISO8601 standard is based on the proleptic Gregorian calendar. This makes it fully compatible with the calendar system used in most countries today. The proleptic means that the Gregorian rules for leap years are applied for all time, thus the ISO8601 standard gives different results for dates before the year 1583 when the historic cutover from the Julian calendar occurred.

The standard sets out a framework within which dates and times can be represented. It offers many choices, however in reality there are three main date representations, year month day, year dayOfYear and year week dayOfWeek.

References

Month based

yyyy-mm-ddTHH:MM:SS.SSS
This is the most common format of ISO8601 and separates the fields by dashes. The fields are:

  • four digit year
  • two digit month, where 01 is Janurary and 12 is December
  • two digit day of month, from 01 to 31
  • two digit hour, from 00 to 23
  • two digit minute, from 00 to 59
  • two digit second, from 00 to 59
  • three decimal places for milliseconds if required

This format is used in XML standards for passing dates and times.

Day of Year based

yyyy-dddTHH:MM:SS.SSS
This format of ISO8601 has the following fields:

  • four digit year
  • three digit day of year, from 001 to 366
  • two digit hour, from 00 to 23
  • two digit minute, from 00 to 59
  • two digit second, from 00 to 59
  • three decimal places for milliseconds if required

Week based

yyyy-Www-dTHH:MM:SS.SSS
This format of ISO8601 has the following fields:

  • four digit weekyear, see rules below
  • two digit week of year, from 01 to 53
  • one digit day of week, from 1 to 7 where 1 is Monday and 7 is Sunday
  • two digit hour, from 00 to 23
  • two digit minute, from 00 to 59
  • two digit second, from 00 to 59
  • three decimal places for milliseconds if required

Weeks are always complete, and the first week of a year is the one that includes the first Thursday of the year. This definition can mean that the first week of a year starts in the previous year, and the last week finishes in the next year. The weekyear field is defined to refer to the year that owns the week, which may differ from the actual year.

Using ISO8601 in Joda-Time

Within Joda-Time the ISO8601 calendar system is the default. As such, all methods that take a chronology as a parameter will use the ISO chronology if null is passed in. There is almost always a version of the method without the chronology parameter, and this will default to ISO chronology.

The actual chronology class is ISOChronology. This is normally created if required using the factory method ISOChronology.getInstance().

// setup date object for midday on Christmas 2004 (default time zone)
DateTime dt = new DateTime(2004, 12, 25, 12, 0, 0, 0);

// or specify the chronology explicitly
Chronology chrono = ISOChronology.getInstance();
DateTime dt = new DateTime(2004, 12, 25, 12, 0, 0, 0, chrono);

// or use the default null handling behaviour
DateTime dt = new DateTime(2004, 12, 25, 12, 0, 0, 0, (Chronology) null);

Julian calendar system

The Julian calendar system is calendar system that was widely used from about 4CE to 1582CE. It was replaced by the Gregorian calendar on 1582-10-15. The Julian calendar defines a leap year as once every four years. This becomes inaccurate over time, to such an extent that by 1582, 10 days had to be 'lost' to correct the calendar.

The Julian calendar is represented in Joda-Time by the Julian chronology. This chronology applies Julian rules for all time. Normally, a more accurate historic calendar is found by using the GregorianJulian chronology instead.

References

Using Julian chronology in Joda-Time

Within Joda-Time the Julian calendar system can be used by obtaining an instance of JulianChronology. This is normally created using the factory method JulianChronology.getInstance(). This is then passed into the constructors of the main date and time classes.

// setup date object for the Battle of Hastings in 1066
Chronology chrono = JulianChronology.getInstance();
DateTime dt = new DateTime(1066, 10, 14, 10, 0, 0, 0, chrono);

 

 

4.The Javadoc

 

 

 

5.The list of FAQs.

 

 

 

 

6.The change notes for each release

 

 

 

7.The GitHub source repository

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/shanesen/blog/3047050

注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: 中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·本文档为双语同时展示,一行原文、一行译文,可逐行对照,避免了原文/译文来回切换的麻烦; ·有原文可参照,不再担心翻译偏差误导; ·边学技术、边学英语。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值