Making Sense of Java's Dates
By Philipp K. Janert, Ph.d. Translated by Humx
06/04/2003
Introduction
It is difficult to have a precise processing date in your computer program. Not only is an obvious (English: January, French: Janvier, German: Januar, etc.) Internationalization, but also considers different date systems (not all cultures use Christ Jesus's birthday as the beginning of the year). If there is a high-precision or very large-scale time to be processed, there is an additional aspect that needs to be careful, such as changes in leap seconds or time systems. (Gu calendar (Qi Qi, Gri Galelligent Law) is generally accepted in 1582, but not all countries are accepted on the same day!)
Although the problem time is a very simple concept: the time is linear, it is easy to neglect. Once the area of the time axis is defined, any time point is determined from the lapse of the start time. This and geographic or local time zone is independent-to arbitrary designated time points, the same region, from the starting point process (ignore the correction of relativity).
But when we tried to explain this time in some calendar, it is difficult to say this, for example, according to month, day, or year to express it. The geographic information in this step becomes related: at a time corresponding to a different day, depending on the region (such as: time zone). Based on the interpretation date is often necessary (which day after a month?) And add additional difficulties: overflow and underflow (December 15th, the next year is the next year), and it is not clear ( What day after January 30?).
In the initial JDK 1.0, a point in time, by explaining it as a Java.util.date class, it is calculated together. Although it is relatively easy to handle, it does not support international; from JDK 1.1.4 or JDK 1.1.5, diverse responsibilities responsible for processing dates are assigned to the following classes:
Java.util.date
Represents a point in time.
Abstract java.util.calendarjava.util.gregoriancalendar Extends java.util.calendar
Interpret and process Date.
Abstract java.util.timezonejava.util.SIMpletimezone Extends java.util.timezone
Represents an arbitrary offset from Greenwich, also contains information for Daylight Savings Rules.
Abstract java.text.dateFormat Extends java.text.format java.text.SIMPLEDATEFORMAT EXTENDS JAVA.TEXT.DATEFORMAT
Deformation into the format, printable String, and vice versa.
Java.text.dateFormatsymbols
The translation of the month, week, etc., as an alternative to the information obtained from Locale.
Java.sql.date extends java.util.datejava.sql.time extends java.util.datejava.sql.timestamp extends java.util.date
On behalf of the time point, in order to use in the SQL statement, it also contains the appropriate format.
Note: DateFormat and related classes are in java.text. * Pack. All java.sql. * Package Date Processing Related classes inherit the java.util.date class. All other classes are in the java.util. * Pack.
These "new" classes come from three separation inheritance hierarchies, which are abstract. For each abstract class, the Java standard class library provides a specific implementation.
Java.util.date
Class java.util.date represents a time point. In many applications, this abstraction is called "TimeStamp." In the standard Java class library implementation, this point representative Unix Era January 1, 1970, 00:00: 00 gmt starts milliseconds. Therefore, it is conceptive, this class is a simple package of long.
According to this explanation, only the only expired (except for those GET and SET methods of those milliseconds) are those sorting methods.
This class relies on System.CurrentTimeMillis () to achieve the current point in time. Therefore, its accuracy and accuracy are determined by the implementation of the System and the underlying (essential operating system) it calls.
The java.util.date API
The name and agreement in the initial DATE class have caused endless confusion. However, use 0-11 computing month, from 1900 calculating the annual decision to imitate the habit of the C standard class library, call function getTime () returns to start with UNIX Era The number of milliseconds and getdate () returns the week's decision is obviously the Java class designer.
Java.util.calendar
Semantic
Calendar represents a point in time (a "date") to an interpreter in a specific area and time zone. Each Calendar instance has a long variable that contains a representative time point starting from the end.
This means that Calendar is not a (stateless) converter or interpreter, nor a factory that modifies Dates. It does not support the following:
Month Interpreter.getMonth (InputDate) OR
Date factory.addmonth (Inputdate)
INSTEAD, Calendar instance must be initialized to specific DATE. This Calendar instance can be modified or queried in the interpreted property.
Surprisingly, this type of instances is always initialized to the current time. Getting a Calendar instance initialized to any Date is an impossible -API forced programmer calls through a series of instances, such as SetTime (Date) To explicitly set the date.
Access the interpreted field and a class
The Calendar class complies with a single field of the Interpreted Date instance. Instead of providing some Dedicated attributes getters and setters methods (such as getMonth ()), it only provides one, using a label as a parameter to obtain the request Methods:
INT GET (Calendar.Mont), etc.
Note that this function always returns an int!
The label of these fields is defined as the public static final variable of the Calendar class. (These Identifiers are the integers of the RAW, not packaged as an enumeration abstraction.)
In addition to these fields (key values), the Calendar class defines a number of additional public static final variables to save the values of these fields. So, to test a particular date (expressed by Calendar instance Calendar) whether it is in one year One month, there will be as follows:
IF (Calendar.Mont) == Calendar.January) {...}
Note that the month is called January, February, and so on, regardless of the location, such as: Month_1, Month_2, and the like. There is also a field undecimber, which is some (non-Quele calendar, Gri Galelligent dealers) Use, represents the 13th month of the year.
Unfortunately, key values and values are not distinguished from NETREFACE.
deal with
Calendar provides three ways to modify the date of the current instance representative: set (), add (), and roll (). Set () method Simple setting of the specific field as the desired value. Add () and roll () Differences are in terms of over- and understand: add () transfer to "smaller" or "larger" fields, and roll () does not affect other fields. For example, it adds one to the Calendar instance of December 15th. Month, when add () uses the year of use, but use roll () does not change. The motivation for each Case corresponding to a function is that they may differ in the GUI.
Due to Calendar's implementation, it contains redundant data: All fields can be calculated from a given time zone and the number of milliseconds starting with the era, and vice versa. This class defines abstract methods for these operations Computefields () And CompleTime (), but also defined the Complete () method to perform a complete recruitment. Because there are two sets of redundant data, the two sets of data may not synchronize. According to the Javadoc documentation, dependent data is dependent when changing Lazily's way to recalculate. When recalculates, the subclass must maintain a set of dirty data signs as a symbol. Implemented Leakage
For a "new" date related processing class, the details of the implementation have to be leaked to the API to some extent. At this point, this is the reflection of custom development of the base class, but it It is also possible to see the result of not fully clearly designing a public interface. Calendar Abstract Whether to maintain two redundant data collection is completely detail, and thus hide the customer class. This also includes intending to reuse this class by inheritance.
Additional function
Additional functions provided by the Calendar base class are divided into three categories. Several static factory methods are used to initialize an example of any time zone and locals. As mentioned earlier, all instances have been initialized to the current time in this way. No factory The method is provided to obtain an example initialized to any point in time.
The second group contains the Before (Object) and an after (Object) method. They accept the parameters of the object type, thus allowing these methods to be covered by the subclasses overwritten in any type of parameters.
Finally, there are many additional methods to get set attributes, such as the current time zone. There are several possible and actual maximum, minimum, minimum, minimum, minimal, minimum, for querying specific fields under current Calendar implementation.
Java.util.gregoriancalendar
GregorianCalendar is a subclass of only available Calendar. It provides basic Calendar abstraction suitable for implementation based on habit explanations in the West. It adds many public constructor, which also has methods for Gregorian Calendars, such as IsleApyear () .
Java.util.Timezone and java.util.simpletimezone
The Timezone class and its subclasses are auxiliary class, which is used by Calendar to interpret the date according to the selected time zone. Press, a time zone represents a certain offset of the current time zone to the current time zone. Obviously, this offset Changes when daylight saving time. Therefore, in order to calculate local time for a given date and time, Timezone abstraction not only understands the extra shift when DST is valid, but also understands the rules of DST effective rules.
Abstract Based Timezone provides basic processing of "RAW" (not considering daylight saving time) method (using milliseconds!), But any functional implementation of DST rules is left to subclasses, such as SimpleTimezone. Many ways to specify rules that control DST start and end, such as a certain day or one day in a month or a day. Every timezone has a readable, locally independent display name. Show name Style: long and short presentation.
The start of the week?
Calendar's documentation has invested a quite text to compute the monthly or year Weeks. Weekday is considered to be a week's start in the country. In the United States, a week is usually considered starting from Sunday. In some European countries The week from Monday started on Sunday a week. This will affect which week is considered to be the first complete week of one year (or month), and calculate the number of weeks.
Time zone is clearly decided by a marked string. The base class provides static methods String [] getavailableids () to get all standard time zones that are known (JDK). (557 in my installation, JDK1.4.1 If needed, JavadoC defines the syntax of strictly establishing a custom time zone marker. It also provides a static factory method to get the Timezone instance of the specified ID or the default current time zone. SimpleTimezone provides some public constructor, strange For an abstract class, such as Timezone. (Javadoc Write "Subclass Constructor Call." Obviously, it should be declared as protected.)
Java.text.dateFormat
Although Calendar and related classes handle the explanation of Locale-Specific, there are still DateFormat class auxiliary date and (human) to read the transformation between strings. When a time point, additional localization issues: not only in language And the date format is regional independent (United States: Month / Day / Year, Germany: day.month.year, etc.). DateFormat tries to manage these different efforts. Abstract base class DateFormat does not need (and not allowed) Arbitrary, programmer defined date format. As an alternative, it defines four formatting style: short, medium, long, and full (in order of redundancy). For a given Locale and Style, programmers Rely on this kind of acquisition of the appropriate date format.
Abstract base class DateFormat does not define a static method to complete the formatting and conversion between text and date. As an alternative, it defines several static factory methods to get instances that are initialized to give LOCALE and selected Style. Since the standard Format always contains the date and time, and the additional factory method can be used to obtain an instance of only the time or date portion. String format (date) and date parse (String) method then perform deformed. Note that the specific subclass can choose to break this habit.
Inside them, the Calendar object explaining the date is accessible and modified, and the Timezone and NumberFormat objects are also. However, once the DateFormat is instantiated locale and style can no longer be modified.
There are also available (abstract) to splicing string parsing and formatting methods, each accepts additional parsePosition or fieldPosition parameters. Each of these methods has two versions. An accepting or return DATE instance another Accept Or return normal Object to allow selective processing DATE in the subclass. It defines some variables that are possible with the PUBLIC Static variable ending with _field (CF. Java.util.Format) Javadoc).
Only the specific implementation of the most common DateFormat class is SimpleDateFormat. It provides all the above functions and allows you to define any time format. There is a rich grammar to specify formatting mode; JavadoC provides all details. Mode can be specified For the parameters or explicit settings of the constructor.
Printing a TimeStamp: a cut-and-paste eXample
Imagine printing the current time in the format defined in the user; for example, to the log file. Here is to do:
// Create the following format: Hour (0-23): minute: second
SimpleDateFormat Formatter = New SimpleDateFormat ("HH: mm: SS");
Date now = new date ();
String LogenTry = formatter.format (now);
// Read from the backend
Try {
Date Sometime = formatter.parse (LOGENTRY);
} catch (parseException eXC) {
Exc.printStackTrace ();
}
Note that it is necessary to be being thrown when the input string cannot be thrown when the input string cannot be by PARSE.
Java.sql. * Related classes
In Java.sql. * The date time in the package inherits java.util.date. In fact they need Date, Time, and TimeStamp. Types require Date, Time, and TimeStamp.
These three classes like java.util.date, the three classes in the SQL package are simple packages for numbers in a time point. Date and Time class ignore the date on time or calendar in one day, respectively.
The TimeStamp class, not only contains not only to millisecond accuracy, usual time and date, but also allows the additional accurate to nanosecond accuracy of the time point of the time point. (Naose is more than one hundred in one)
In addition to the SQL data type corresponding to the image, these classes are denoted by the SQL consistent string. At this point, each of the three classes overwrite the toString () method. In addition, each class provides a static factory Method, Valueof (String), returns an example of the current call class initialized to transfer the time of the parameter string. The format of the string representation of these three methods has been selected by the SQL standard, and cannot be changed by the programmer. Storage Additional data required for nanoseconds, is not good to consistent with other usual time and date information in TimeStamp. For example, call gettime () on the TimeStamp instance () will return to the number of milliseconds starting from the Unix era, ignore nanoseconds Data. Simply, according to Javadoc documents, the HashCode () method is not covered in the subclass, and the nanosecond data is ignored.
Java.sql.TimeStamp's Javadoc pointed out that "Inheritance Relationship (...) actually represents the inheritance of the implementation, not the type inheritance (this violates the original intention of the inheritance). Even if this sentence is wrong, since Java has no private inheritance Concepts (that is, inherited). All classes in the java.sql. * Packages should be designed to encapsulate a java.util.date object, not inherited it, only the way you need - minimum, method, such as Hashcode () It should be covered properly.
The last comment is the processing of the time zone of the database engine. In the java.sql. * Pack, the class does not allow the explicit setting time zone. Database server (or driver) freely interpret this information according to the local time zone of server Server, and It may be affected and change (for example, because of daylight saving time).
to sum up
Through the previous discussion, it is very clear that Java's date is not very complicated, but it is not well designed. The package is omitted, the APIS structure is complex and there is no well organized, and the very good ideas are often unreasonable. Use. Realize more inexplicable wonder (proposal to see Calendar.GetInstance (Locale) For all types of Locale actually returned objects!) On the other hand, the class of the classes management in, IN Any Case, Are Here To Stay. I hope this article helps you understand their usage help.
Call me by My True Names
As a last example of the wonderful consistency and orthogonality of Java's APIs, I would like to list three (maybe there are more!) Different methods to obtain the number of milliseconds since the start of the Unix epoch:
Long java.util.date.gettime ()
Long java.util.calendar.gettimeinmillis () (New with JDK 1.4.1. Note That Java.util.calendar.gettime () Returns a date Object!)
Long java.lang.system.currenttimemillis ()
thank
The author is very grateful to Wilhelm Fitzpatrick (Seattle) carefully read original and valuable comments.
References
INTERNATIONAL CALENDARS in Java At IBM: a Detailed White Paper by One of the Original Authors on The Genesis and Intended Usage of Java's Date-Handling Classes. Highly Recommended.
IBM alphaWorks: International Calendars: Additional subclasses of Calendar for Buddhist, Hebrew, Muslim, and Japanese calendars used to be available at IBM's alphaWorks Unfortunately, they seem to be temporarily unavailable.Reingold on Calendars:. Web site of Edward M. Reingold, author Of Calendrical Calculation, The Standard Reference on Calendars.
About The Calendars: a brief overview of some of the more common international calendars.
Thread on JavaLobby:. A brief, but interesting, thread on JavaLobby Apparently, some people considered the APIs of Java's date classes to be so bad that they filed an official bug-report to have them changed Unfortunately, the request has been rejected..
Philipp K. Janert, Ph.d. Is A Software Project Consultant, Server Programmer, And Architect.