| Home > Core Java FAQ
> Language Fundamentals FAQ |
| Java
Fundamentals |
| Basic(19) * Constants
and Expressions(40) * Variables and Methods(16)
* Array(11) * Date/Time(36)
* Compile Time(11) * Run
Time(02) * C-vs-Java(12) |
| |
|
Q .
What happen to java.util.Date between JDK 1.0 and JDK 1.1?
|
Ans : In JDK 1.1 the java.util.Date class was split to provide better
support for timezones, and internationalization.
The classes specifially related to dates are summarized below:
1. The class Date represents a specific instant in time, with millisecond precision.
2. The class TimeZone is an abstract class that represents a time zone offset, and also figures out daylight
savings time adjustment.
3. The class SimpleTimeZone is the only concrete subclass of TimeZone in the JDK. It is what defines an ordinary
timezone with a simple daylight savings and daylight savings time period.
4. The class Calendar is an abstract class for converting between a Date object and a set of integer fields such
as year, month, day, and hour.
5. The class GregorianCalendar is the only concrete subclass of Calendar in the JDK. It does the
Date-to-fields conversions for the calendar system in common use.
6. The class DateFormat is an abstract class that lets you convert a Date to a printable string with fields in the
way you want (e.g. dd/mm/yy or dd.MMM.yyyy).
7. The class SimpleDateFormat is the only concrete subclass of DateFormat in the JDK. It takes a format string and
either parses a string to produce a date or takes a date and produces a string.
At least one critic has used the term "baroque" when describing the complexities of the Java date related classes, but other critics would
spell that "broke". The good news is that as of JDK 1.2 all of the
common problems have been corrected and many of the bugs were corrected in 1.1.4 and 1.1.6. Even in 1.1.1, you can avoid most of the most
annoying bugs by always keeping in mind which timezone each class is
using.
|
|
Q . Exactly what is a java.util.Date?
|
Ans
:
A java.util.Date stores a moment in time as a long integer
representing the number of milliseconds since 00:00:00 Jan 1, 1970 UTC
(Coordinated Universal Time). This zero moment is known as the "Epoch".
This is the same Epoch as is used on Unix systems. Dates earlier than
the Epoch are represented as negative numbers, counting away from 1/1/1970.
The scheme is sufficient to represent dates from 292,269,053 B.C. to 292,272,993 A.D. (64 bits covers -9,223,372,036,854,775,808 to
+9,223,372,036,854,775,807 milliseconds. But note that prior to JDK
1.2, a GregorianCalendar will not accept values earlier than 4713 B.C.
A java.util.Date is the light-weight object intended to just hold a millisecond value. It is used to hold, communicate and store a moment
in time. Other tasks like creating a formated string, or calculating
dates are best done using other classes.
|
|
Q . Does a java.util.Date really represent the true UTC?
|
Ans
: No, but it is close enough for most human time-keeping purposes. On
most computers, it only represents the time since the epoch as converted from the value on the underlying hardware. If you have
hardware that is synchronized with an atomic clock your time is UTC; most hardware assumes a day is 24 hours long, but there have been more
than 20 leap seconds added to UTC, since the first one was added in
1972.
|
|
Q . How do I create a Date object that represents the current time?
|
Ans
:
The default value of a date object is the current time, so the
following code creates a date object that contains the current time.
Date now = new Date();
|
|
Q . I want to create a string that represents a date in a format
other than what is returned by java.util.Date.toString() do I have to
use a Calendar?
|
Ans
:
No. Instead of creating a Calendar and pulling out all of the
appropriate fields and making a string, you could use
SimpleDateFormat.format() to create a string.
|
|
Q .
Why are all the methods in java.util.Date deprecated?
|
Ans : Mostly because the original java.util.Date was not completely aware
of the timezone and "not amenable to internationalization". To make it
timezone aware and internationalizable would have required adding some
of the functionality which can now be seen in java.util.Calendar and
some of the functionality in java.util.DateFormat. If you find the combination all of the date related classes complex, just be glad they
were separated into different classes.
|
|
Q .
I really don't need a internationalizable, timezone aware,
extra flexible formating set of date classes. Is there anything else I
can use that stores only a date, and allows me to do some date calculations?
|
Ans
: You could consider using the BigDate class written by Roedy Green,
and available in his very informative glossary (search for BigDate). If
you want to store the result in a database as a Date or TimeStamp, you
should read the section below on java.sql.Date.
|
|
Q .
Since the Date( String ) constructor is deprecated what do I use instead?
|
Ans
: The best choice is to use SimpleDateFormat.parse() to create a
java.util.Date object.
The Date constructor that accepts a string calls Date.parse( String ). The
Date.parse() function had its own rules for converting 2 digit years (it used a 1980 pivot date) and other limitiations which makes it
of limited value. Other "features" of Date.parse() that are not supported in SimpleDate have not been missed by many developers.
|
|
Q . Since Date(int year, int month, int date) and related constructors are deprecated what do I use instead?
|
Ans
: The constructor GregorianCalendar(int year, int month, int date) is
the newer replacement. Other choices are the Calendar.set( year, month,
day ) method. Note that the year in the GregorianCalendar starts at 1
A.D., not at 1901 like the old Date constructor.
|
|
Q .
How can I see if my JVM is using the right timezone?
|
Ans
: The following codes displays the ID of the current default
timezone.
System.out.println( TimeZone.getDefault().getID() );
|
|
Q .
The value of TimeZone.getDefault is not what I expected. What is the problem?
|
Ans
:
The value of the default timezone is based on the value of the
system property "user.timezone". The JVM is supposed to set this value. In releases such as JDK 1.1 the value of user.timezone was often
not set to anything, so TimeZone.getDefault() used its own built in
"fallback" value (the default when there is no default value). In later
JDK 1.1 releases and in JDK 1.2 the setting of the value of
user.timezone is much better and the "fallback" value is now GMT (Greenwich Mean Time). Up until JDK 1.1.3, the fallback value was "PST"
(North American Pacific Timezone).
|
|
Q . Do all the standard objects use the same default
timezone?
|
Ans
: Not until JDK 1.2. In JDK 1.1, Date.toString() and Calendar used
the value of TimeZone.getDefault() which could often be undefined (see
the previous question). In JDK 1.1, The Calendar in a SimpleDateFormat
was set to the 1st timezone resource for the locale (for the US this is
PST).
System.out.println( "Date format TZ = " + TimeZone.getDefault().getID() );
sdf = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG );
System.out.println( "Date format TZ = " + sdf.getTimeZone().getID() );
Calendar cal = Calendar.getInstance();
System.out.println( "Calendar TZ = " + cal.getTimeZone().getID() );
When run on a system running JDK 1.1.6, NOT in the North American Pacific Time nor in the GMT timezone results in:
Timezone default = GMT
Date format TZ = PST
Calendar TZ = GMT
This example shows two bugs, the value of user.timezone is undefined, so its defaulting to GMT (see discussion of
TimeZone.getDefault()) and it shows that the DateFormat depends on the 1st locale entry which in
this case is PST.
If you don't want the DateFormat to use the Locale timezone, see the code provided below.
|
|
Q .
If I explicitly set the default timezone, don't I need code
to choose between (a) the daylight savings version or (b) the standard
version of a timezone?
|
Ans
: No. The ID that you use to select a timezone with
TimeZone.getTimeZone refers to a predefined timezone that contains
daylight savings information (when applicable). For example, the following code selects the timezone used in New York, USA.
// Get the North American Eastern Time definition.
TimeZone theTz = TimeZone.getTimeZone( "EST" );
// get a really detailed date format and set it to the right timezone
DateFormat df = DateFormat.getDateTimeInstance( DateFormat.LONG,
DateFormat.LONG );
df.setTimeZone( theTz );
// create a date in the locale's calendar, set its timezone and hour.
Calendar day = Calendar.getInstance();
day.setTimeZone( theTz );
day.set( 1998, Calendar.FEBRUARY, 1 );
day.set( Calendar.HOUR, 12 );
// print that date/time and
// that date/time 150 full days of milliseconds later.
System.out.println( df.format( day.getTime() ) );
System.out.println( df.format(
new Date( day.getTime().getTime() + // get the millis
150L*24*60*60*1000L ) ) ); // add exactly 150 days of millis
Results in:
February 1, 1998 12:00:00 PM EST
July 1, 1998 1:00:00 PM EDT
Notice that this example selected something refered to as "EST", but that this TimeZone was aware of the daylight savings time change and
either printed as "EST" or "EDT".
The confusion is reduced in JDK 1.2, you can use longer TimeZone IDs each maps to its own set of text resources. For example the following
IDs are 5 hour West of GMT and have various DST rules:
"America/Nassau", "America/Montreal", "America/Havana", "America/Port-au-Prince", "America/Grand_Turk", "America/New_York" and
"EST".
You can look at a list of other timezone names and offsets in the file
$JAVAHOME/src/java/util/TimeZone.java
|
|
Q . How do I create my own Time Zone to apply to dates?
|
Ans
: You can create a TimeZone object with the GMT offset of your
choice. The following code creates British Time, a timezone that was
not defined in 1.1.
britTime = new SimpleTimeZone(0*ONE_HOUR, "Europe/London" /*GMT/BST*/,
Calendar.MARCH, -1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
Calendar.OCTOBER,-1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
1*ONE_HOUR),
TimeZone.setDefault( britTime );
Or you can then apply that TimeZone to a particular Calendar object like so:
Calendar myCal = Calendar.getInstance();
myCal.setTimeZone( britTime );
If you are running 1.2, You can choose this existing timezone as the default with the code:
TimeZone.setDefault( TimeZone.getTimeZone( "Europe/London" ) );
Note that BST is defined from JDK 1.1 and later, but it is Bangladesh Standard Time. For a longer example of creating and testing the British
timezone, Tony Dahlman provides a nice example in his BSumTime.java
code.
|
|
Q . How do I create the BST timezone specifically?
|
Ans
: You can create an arbitrary TimeZone object with the code below. In
most or all other timezones, daylight savings time is handled automatically and internally. But GMT is the reference for all other
timezones, and so does not have the summertime update applied automatically. The rules for BST can be found at
http://www.rog.nmm.ac.uk/leaflets/summer/summer.html
Here is the code to create a British Summer Time timezone that is offset one hour from GMT between two dates:
import java.util.*;
import java.text.*;
// create a BST timezone (code courtesy of Tony Dahlman).
public static GregorianCalendar setBritSummTime(String zoneName){
// Set up the default GMT0BST time zone
SimpleTimeZone bst_tz =
new SimpleTimeZone( 0, // no offset from GMT
zoneName, // individualized tz id
// last Sun Mar 1AM
Calendar.MARCH,-1,Calendar.SUNDAY,1*60*60*1000,
// last Sun Oct 2AM
Calendar.OCTOBER,-1,Calendar.SUNDAY,2*60*60*1000
);
SimpleTimeZone.setDefault(bst_tz);
// Apply TimeZone to create a Calendar object for UK locale
return (new GregorianCalendar(bst_tz,Locale.UK) );
}
and here is how you would print out values using BST:
// create a template for printing the date
DateFormat df = DateFormat.getTimeInstance(
DateFormat.LONG,Locale.UK);
// tell the template to use BST tz.
df.setTimeZone(TimeZone.getDefault());
System.out.println("Using British Summer Time "
+"the time is: "
+ df.format( BritishSummerTime.getTime() ) );
// Now get and compare with current time in GMT
df.setTimeZone(TimeZone.getTimeZone("GMT") );
System.out.println("\nCurrent time in GMT is: "
+ df.format(BritishSummerTime.getTime() ) );
In the winter, this BST zone is aligned with GMT; in the summer it is
one hour later (4 a.m. GMT is 5 a.m. BST).
You can look at a list of timezone names and offsets in the file
$JAVAHOME/src/java/util/TimeZone.java
java.util.Calendar and java.util.GregorianCalendar
|
|
Q .
How do I a create a specific date in the Gregorian Calendar?
|
Ans
:
If you have a Date use:
myCal.setTime( myDate );
If you have a set of integers representing the year, month and day of
month use:
Calendar myCal = Calendar.getInstance();
myCal.set( 1998, Calendar.MARCH, 15 );
Note: Months start with January = 0!
|
|
Q . How do I use a GregorianCalendar to extract a few fields from a Date?
|
Ans
: The following code shows how to get some fields from a Date.
Calendar g = Calendar.getInstance();
g.setTime( aDate );
int year = g.get( Calendar.YEAR );
int mon = g.get( Calendar.MONTH );
int date = g.get( Calendar.DATE );
mon++; // in class Calendar & GregCal, months run 0-11 ;-(
System.out.println( mon + "/" + date + "/" + year);
If you want to build a string that has a formated date consider using
SimpleDateFormat.format().
|
|
Q . Some people use Calendar.getInstance() while others use new
GregorianCalendar(). Which one is the correct way to get a Calendar?
|
Ans
:
Either way is correct, it depends on what you want to be able to
do. You should use Calendar.getInstance(), if you want your code to be
ready when the loading of other Calendars are added to the JDK and some
other calendar is the default for the locale. A particular locale might
have configured a Hebrew or Islamic Calendar as the default calendar
and you might want a user to enter a date in his own Calendar, i.e.
1-Jan-2000 (Gregorian) = 23-Tevet-576 (Hebrew) = 24-Ramadan-1420
(Islamic). If you really are trying to place a particular Gregorian date, i.e. 4-July-1776, into a Date object, you might as well create a
GregorianCalendar directly.
|
|
Q .
I changed a field using Calendar.set() and then I checked
another field. Its value is inconsistent with the value I just set. What is going on?
|
Ans
: In JDK 1.1.0 the Calendar class did not update all of its fields
until you called getTime to retrieve the Date that corresponds to the
fields in the Calendar. To get the earlier version of the Calendar to
"turn the crank" and calculate all fields you can use the trick:
myCal.setTime( myCal.getTime() ) // pull the date out and put it back in.
|
|
Q .
When I create the date July 4th, 1776 using new GregorianCalendar( 1776, 7, 4 ) the month is off by one. What is the problem?
|
Ans
:
BufferedReader pOut= new BufferedReader(
new InputStreamReader(p.getInputStream()));
try {
String s = pOut.readLine();
while (s != null) {
System.out.println(s);
s = pOut.readLine();
}
} catch (IOException e) { }
|
|
Q . Why aren't there constants for milliseconds per day, week or year?
|
Ans
: The short answer is: these values are not constants. While some date
calculations would find these useful, it is important to remember that
in areas with daylight savings time rules, there are two days per year
that are not 24 hours long, therefore not all weeks are the same length
(2 out of 52). Also, because of leap years, not all years are the same
length.
If you adding values to a calendar consider using either add or roll; for example:
myCal.add(Calendar.YEAR, 1 ); // get a value 1 year later.
|
|
Q .
By my count the week of the Year is off by one. What is the problem?
|
Ans
: The GregorianCalendar class uses the value set by
setMinimalDaysInFirstWeek() to determine if the fractional week at the
beginning of the year should be week 1 or week 0. If you don't change
it, any fractional week could be week 1, depending on the value defined for the locale.
|
|
Q .
Should I stop using Date all together and just use Calendar?
|
Ans
: Probably not. The Calendar class is a much larger than a Date
object. Many other interfaces in standard APIs are defined using a Date
object. Use Date objects to hold, store or communicate a date-time
value. Use a Calendar object to manipulate a date-time value.
|
|
Q . The GregorianCalendar will not accept a date prior to 4713 B.C. Why?
|
Ans
:
January 1, 4713 B.C. is the "epoch" date for the Julian Day calendar
which was invented in the 16th century by the Joseph Justus
Scaliger. "[T]he Julian day calendar, ... does not use individual years at all,
but a cycle of 7980 astronomical years that counts a day at a time,
with no fractional days, no mean year, and no leap years. He came up
with his number by mulitplying three chronological cycles: an 18-year
solar cycle, a 19-year lunar cycle, and the 15-year indication period
used by Romans. All three cycles began together at the same moment at
the start of the "Julian cycle. ... [This] Calendar lives on among
astronomers."
-- David Ewing Duncan, "Calendar", Avon Books, 1998; p 207
Note that the Julian Day calendar is not the same as the Julian calendar. The Julian Calendar is named for Julius Caesar. The Julian
Calendar was used in the Europe from what we now call January 1, 45
B.C. until at least October 4, 1582 and is still used today by the Eastern Orthodox Church to date holidays.
The limitation on dates prior to 4713 BC has been dropped in JDK 1.2.
|
|
Q .The Calendar class is said not to handle certain historical changes. Can you explain some of the limitations?
|
Ans
:
The date of change from the Julian to the Gregorian calendar depends
on where you lived at the time. The date can vary from 1582 (most Catholic countries, which of course followed the Papal edict) to 1949
(China). The date of the cutover from using the Julian Calendar (leap
years ever 4 years) to using the Gregorian Calendar (every 4 years,
except every 100 unless divisable by 400) is controlled by the method
GregorianCalendar.setGregorianChange(Date).
It is also the case that January 1 was not always the beginning of the year. January 1 was standardized by Julius Caesar in 45 B.C. and Pope
Gregory XIII in 1582, but others who used the Julian Calendar between
those dates used other dates for New Years Day. (Anyone who has ever
been involved in a standardization effort may find it interesting that
neither an emperor nor a pope could actually complete the standardization effort).
The Calendar class uses a TimeZone which does not handle historical changes, i.e. the SimpleTimeZone contains only two dates the "spring
forward" and "fall back" dates and a date that the DST starts (see
SimpleTimeZone.setStartYear() ). If the local definitions have changed
then a date/time may not accurately reflect the historical local time.
As noted above, the Date object does not usually include leap seconds, unless your hardware includes leap seconds.
While the Calendar class is more than useful for international business, it may not be what you want for doing UTC timebased
calculations or historical dates and times without a more careful analysis of its design limits.
java.text.DateFormat and java.text.SimpleDateFormat
|
|
Q .How do I convert a date in one format to another?
|
Ans
:
The following code illustrates the technique:
import java.text.*;
public class DateTest {
public static void main( String[] args ) {
SimpleDateFormat df1 =
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
SimpleDateFormat df2 =
new SimpleDateFormat("dd-MMM-yy");
String startdatetime = "1998-09-09 06:51:27.0";
try {
System.out.println("Date is " +
df2.format( df1.parse(startdatetime) ));
} catch (ParseException pe) {
System.out.println("ParseException " + pe );
}
}
}
When run, the program outputs "Date is 09-Sep-98"
|
|
Q . How do I use DateFormat to parse a string containing a date?
|
Ans
:
The easiest way to parse a date that is in a known format is to use
SimpleDateFormat.parse().
DateFormat df = new SimpleDateFormat( "HH:mm" );
df.setTimeZone( TimeZone.getDefault() ); // if using JDK 1.1 libraries.
df.setLenient( false ); // to not allow 26:65 etc.
Date lateLunchOnDayZero = df.parse( "12:30" );
System.out.println( lateLunchOnDayZero );
The above code would result in (when in the MST timezone).
Thu Jan 01 12:30:00 MST 1970
To parse other date and time fields, refer to the SimpleDateFormat documentation.
|
|
Q .
How do I use a DateFormat to create a text string from a Date?
|
Ans
:
The easiest way to create a string from a date is to use a
SimpleDateFormat.format(). The following code illustrates how this can
be done.
DateFormat df = new SimpleDateFormat( "yyyy.MMM.dd HH:mm:ss.SSS z" );
df.setTimeZone( TimeZone.getDefault() ); // JDK 1.1
System.out.println( df.format( d ) ); // where d is a Date
For other possible fields from the calendar, see the document for
SimpleDateFormat.
|
|
Q .
What timezone does a SimpleDateFormat use when I don't specify one?
|
Ans
: In JDK 1.1, the SimpleDateFormat uses the first timezone defined for
the locale. In JDK 1.2, it uses the default timezone. See the discussion above on how this differs from the Calendar class).
|
|
Q . I'm not yet using JDK 1.2 and I don't want the DateFormat to use the 1st timezone for the locale. How do I change the timezone in a SimpleDateFormat to use a different
timezone?
|
Ans
:
The following code sets the timezone of a DateFormat to the current
default.
DateFormat df = DateFormat.getDateInstance();
df.setTimeZone(TimeZone.getDefault());
or to set it to a timezone of your chioce.
df.setTimeZone(TimeZone.getTimeZone( "MST" ) ) // Mtn Time, Denver USA
|
|
Q . What century is assumed when I use a two digit year in a SimpleDateFormat string?
|
Ans
: In JDK 1.1, the default start for the century used by SimpleDateFormat for 2 digit years is 80 years before the current date.
This means that in 1998: 1 = 2001, 2 = 2002, ... 17 = 2017, 18 = 2018,
19 = 1919, 20 = 1920, ... 98 = 1998, 99 = 1999,
In JDK 1.2 you can change this "default century start date" with the method set2DigitYearStart( Date) and get its current value
with the method get2DigitYearStart(). One thing to note is that since
set2DigitYearStart takes a date not a year, you can have your default century begin at any day or hour.
When running under JDK 1.1, it is probably best to avoid two-digit year fields, when the dates entered could possibly fall outside of the range
-- now less 80 years and now plus 20 years. If you want to allow two-digit year fields in JDK 1.2 and beyond, consider setting the
2DigitYearStart property to something appropriate, For example, set it
to today, when all dates to be entered are in the future (i.e. an expiration date), or set it to today less 100 years, when the value is
always in the past (i.e. birthdate, death date).
|
|
Q .
Does the above mentioned limitation of 2 digit years in JDK 1.1 mean that java.text.SimpleDateFormat is not Y2K compliant?
|
Ans
:
No. It means that any code you write that (1) allows the entry of 2
digit years and (2) does not make sure they are in an appropriate century, would not pass a careful Y2K analysis. This code was put here
so you could sensibly read old files with non-Y2K compliant dates, not
so you could create new ones. Once you are using JDK 1.2 it is better
to set the 2DigitYearStart property to something appropriate for any
two-digit year field which you are parsing.
java.sql.Date and java.sql.TimeStamp
|
|
Q . What timezone does a java.sql.date use when converting to an SQL DATE?
|
Ans
: This is another hidden use of the default java.util.TimeZone. If you
have carefully set every timezone in every Calendar and DateFormat you
are using, but you don't set the default in java.util.TimeZone when a
java.util.Date is converted to a java.sql.Date you may not end up with
the value you expected in your database.
|
|
Q . When I print a jave.sql.Timestamp it doesn't include any milliseconds. What is the problem?
|
Ans
:
If you print the java.sql.Timestamp directly you will see this
problem. The following code demonstrates this surprising behavior.
// incorrect use of java.sql.Timestamp
DateFormat df = new SimpleDateFormat( "MM/dd/yy hh:mm:ss.SSS a" );
df.setTimeZone( TimeZone.getDefault() ); // needed in JDK 1.1
java.sql.Timestamp t = new java.sql.Timestamp( 94, Calendar.JANUARY, 1,
13, 45, 59, 987654321 );
System.out.println( df.format( t ) ) ; // Wrong! no fractions of a second.
The results of the above code are:
01/01/94 01:45:59.000 PM
The above code is using whatever is in the super class (java.util.Date) and assumes all of those parts are filled in. java.sql.Timestamp could
have stored the whole milliseconds in the millisecond part of a
java.util.Date, and stored the nanoseconds that are not whole milliseconds in an additional field. They chose to ignore the fractions
of a second in the java.util.Date and put all fractional parts in an
additional nanosecond field.
The following code shows how to convert a java.sql.timestamp to a
java.util.Date.
Date d = new Date(t.getTime() + (t.getNanos() / 1000000 ));
// 1 Milli = 1x10^6 Nanos
System.out.println( df.format( d ) ) ; // Right! At least we have the millis
The result of the above code is a better approximation of the timestamp value:
01/01/94 01:45:59.987 PM
|
|
Q . How do I calculate the number of days between two dates?
|
Ans
:
There is no API for this (there should be), but you can calculate
it by hand like this:
static final long ONE_HOUR = 60 * 60 * 1000L;
Calendar earlierDate = new GregorianCalendar();
Calendar laterDate = new GregorianCalendar();
earlierDate.set(1997, 1, 5, 0, 0, 0); // FEB!! 05, 1997
laterDate.set(1998, 1, 5, 0, 0, 0); // Feb 05, 1998
// the first getTime() returns a Date, the second takes
// that Date object and returns millisecs since 1/1/70.
// The API has misleading and horrible naming here, sorry.
long duration = laterDate.getTime().getTime() -
earlierDate.getTime().getTime();
// Add one hour in case the duration includes a
// 23 hour Daylight Savings spring forward day.
long nDays = ( duration + ONE_HOUR ) / (24 * ONE_HOUR);
System.out.println("difference in days: " + nDays);
Note: this method works only if the two times are both created to be exactly midnight. Otherwise you might end up finding that for example,
11 PM tonight is 0 days away from 6 AM tomorrow, instead of 1 day as
many applications expect. This is because 24 hours haven't elapsed
between 11pm on one day and 6am on the next.
Or, use int julian = myCalendar.get(Calendar.DAY_OF_YEAR); and subtract, making sure to subtract the years too. Alternatively, use
BigDate at http://mindprod.com.
For the ultimate in generality, you could get ACM's Collected Algorithm 199, recode it in Java (takes about 30 minutes), compute the Julian
date for each end point, and subtract the two numbers. Here is the code
in Java to get the GMT Julian day number and a "local Julian Day" that
leverages the existing algorithms in the GregorianCalendar.
import java.util.*;
import java.text.*;
/**
* This Calendar provides Julian Day and "Calendar Day" methods,
* The Calendar Day starts at _local_ midnight.
*
* @author Paul A. Hill
* @version 1.1
* @since JDK 1.1.7 3/99
* @see java.util.Calendar
*/
public class FAQCalendar extends GregorianCalendar implements Cloneable {
/**
** this constant and the ones that follow are actually private
** in the GregorianCalendar, so we'll redefine them here.
**/
public static final long
ONE_SECOND = 1000,
ONE_MINUTE = ONE_SECOND * 60,
ONE_HOUR = ONE_MINUTE * 60;
/**
* this next constant and the others with it have their uses,
* but watch out for DST days and the weeks that contain them.
* Note also that 1/1/1970 doesn't start on the first day of the week.
*/
protected static final long
ONE_DAY = ONE_HOUR * 24,
ONE_WEEK = ONE_DAY * 7;
/** The number of days from Jan 1, 4713 BC (Proleptic Julian)
** to 1/1/1970 AD (Gregorian). 1/1/1970 is time 0 for a java.util.Date.
**/
public static final long JULIAN_DAY_OFFSET = 2440588L;
/**
* Same as GregorianCalendar(). Creates a calendar with the time set to
* the moment it was created.
*
Note: for Brevety I have not provided all of the other
* constructors that you can find in GregorianCalendar.
*
* @see java.util.GregorianCalendar#GregorianCalendar
*/
public FAQCalendar() {
super();
}
/**
* A calendar day as defined here, is like the Julian Day but it starts
* and ends at _local_ 12 midnight, as defined by the timezone which is
* attached to this calendar. This value is useful for comparing
* any date in the calendar to any other date to determine how many days
* between them, i.e. tomorrow - today = 1
*
* @return the calendar day (see above).
* @see #getCalendarDay
*/
public long getCalendarDay() {
TimeZone tz = getTimeZone();
// Figure the exact offset for the exact time of day.
int offset = tz.getOffset( get( ERA ), get( YEAR ),
get( MONTH ), get( DAY_OF_MONTH ), get( DAY_OF_WEEK ),
(int)((long)get( HOUR_OF_DAY ) * ONE_HOUR +
get( MINUTE ) * ONE_MINUTE +
get( SECOND ) * ONE_SECOND ) );
return round( ONE_DAY, getTime().getTime() + offset ) + JULIAN_DAY_OFFSET;
}
/**
* Sets the date in the calendar to 00:00 (midnight) on the local calendar day.
* See getCalendarDay for the definition of calendar day as used in this class.
*
* @param calendarDay the day to set the calendar to.
* @see #setCalendarDay
* @see java.util.TimeZone#getRawOffset
*/
public void setCalendarDay( long calendarDay ) {
// Set to the beginning of the Julian day.
// Then add in the difference to make it 00:00 local time.
setJulianDay( calendarDay );
setTimeInMillis( getTime().getTime() - getTimeZone().getRawOffset() );
// we may have gone slightly too far, because we used the
// raw offset (diff between Standard time to GMT/UT, instead of the
// actual value for this day, so during DLS we may be at 1 AM or whatever
// the local DLS offset is), so we'll just drop back to midnight.
set( HOUR_OF_DAY, 0 );
}
/**
* Finds the number of days after 12/31/4312 BC 24:00 GMT on a proleptic
* Julian Calendar (i.e. extending the Julian Calendar into pre-history)
* to the current time.
*
The Astronomers Julian Day begins at noon. The Julian Day used here
* sometimes called the Chronologists or Historians Julian Day
* starts at midnight. For more information see
* http://www.magnet.ch/serendipity/hermetic/cal_stud/jdn.htm#astronomical
*
Note: This routine does NOT take into consideration
* leap seconds.
*
* @return the day number of the current time from 1/
* @see #getCalendarDay
*/
public long getJulianDay() {
return round( ONE_DAY, getTime().getTime() ) + JULIAN_DAY_OFFSET;
}
/**
* Sets the current date contained in this calendar to exactly
* 00:00 GMT on the date defined by the Julian Day provided.
*
* @param julianDay the Julian Day to set the calendar to
* @see #setCalendarDay
*/
public void setJulianDay( long julianDay ) {
setTimeInMillis( ( julianDay - JULIAN_DAY_OFFSET ) * ONE_DAY );
}
/**
* This is a utility routine for rounding (toward negative) to the nearest
* multiple of the conversion factor.
*
BUG? Why is this different than the formula given in
* java.util.GregorianCalendar private millisToJulianDay?
*
* @param conversion typically one of the constants defined
* above ONE_MINUTE, ONE_DAY etc.
* @param fractions the value to convert expressed in the same units
* as the conversion factor (i.e milliseconds).
*
* @return the value divided by the conversion factor, rounded to the negative.
* @see java.util.Calendar
*/
protected static final long round( long conversion, long fractions ) {
long wholeUnits;
// round toward negative:
// For secs rounded to minutes -61/60=-1, -60/60=-1, -59/60=0,
// but we want -2, -1, -1 not -1,-1,0
// or month 0..11 => year 1; -12..-1 => 0; -24..-13 => -1
if ( fractions >= 0 ) {
wholeUnits = fractions / conversion;
}
else {
wholeUnits = ( fractions + 1 )/ conversion - 1;
}
return wholeUnits;
}
} // FAQCalendar
|
|
Q . How to get number of the days in a month?
|
Ans
: Date myDate;
...
...
// add one month to existing month
myDate.setMonth(myDate.getMonth()+1);
// set day to one
myDate.setDate(1);
// sutract a day
myDate.setDate(myDate.getDate()-1);
// we will get the last day of the month
days = myDate.getDate();
This is not recomended to use because these methods are deprecated.
You can also get by using GregorianCalendar class in similar way.
Date trialTime = new Date();
calendar.setTime(trialTime);
|
|
|