28

What can I use to replace this, new Date(2009, 12, 9)?

Thanks for your help.

Tiny
  • 27,221
  • 105
  • 339
  • 599
Tim
  • 2,887
  • 10
  • 33
  • 33
  • 10
    And for good reason, if you want December 12th, 2009, you need `new Date(109, 11, 9)`. – Yishai Dec 09 '09 at 14:39
  • 3
    @Yishai: I dispute that the reasons are "good". – Jon Skeet Dec 09 '09 at 14:39
  • 2
    @Yishai: That seems to be more of an arbitrary obfuscation than helpful. – Sukasa Dec 09 '09 at 14:43
  • 6
    It surprises me how trivial questions like this which are already answered in API docs (and asked countless times in SO before) get quickly upvoted while tough and more interesting questions doesn't get much votes. – BalusC Dec 09 '09 at 14:54
  • @Jon, so much for being friendly to C programmers... – Thorbjørn Ravn Andersen Dec 09 '09 at 14:55
  • @BalusC, perhaps the tough and more interesting questions are not being asked in a way that leads people to want to view them? – Thorbjørn Ravn Andersen Dec 09 '09 at 14:56
  • @Thorbjørn: Copying the mistakes of another API doesn't count as a good reason, IMO :) – Jon Skeet Dec 09 '09 at 15:04
  • 2
    Better idea would be to look at the java docs first. Any core class like that will have an explanation what to use instead of the deprecated method. A handy trick if using Eclipse is to click the deprecated method, hold down 'Shift' and press 'F2' this will open the method in the java docs in your browser. You might need to set up the java docs url first. – Gordon Dec 09 '09 at 15:10
  • The constructor was deprecated because it works unreliably across time zones, which on one hand I consider a good reason, on the other hand not very relevant anymore since no one should want to use the `Date` class at all any longer. Use java.time, the modern Java date and time API. See the answer by Arvind Kumar Avinash below, – Ole V.V. Jun 04 '21 at 20:28

8 Answers8

26

Note: this answer was written in 2009. Since then, java.time has become the preferred date/time API in Java.


Ideally, use Joda Time instead. It's an infinitely superior API to the built-in one. You'd then want to choose between LocalDateTime and DateTime depending on your exact requirements (it's a complicated area - I'm not going to try to summarise in a sentence or two, but the docs do a good job).

If absolutely necessary, use a java.util.Calendar and convert that to a Date when you need to.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
25

Calendar !

Calendar cal = Calendar.getInstance();
cal.set(2009, Calendar.DECEMBER, 12);

Notice that i didn't put 12 for december because it's actually 11 (january is 0).

Then, you can add or remove seconds, minutes, hours, days, months or year easily with :

cal.add(Calendar.HOUR, 2);
cal.add(Calendar.MONTH, -5);

And finally, if you want a Date :

cal.getTime();
Maxime ARNSTAMM
  • 5,274
  • 10
  • 53
  • 76
  • 2
    Note that with this solution, hours, minutes, seconds (and fractions) are set to their current value. This is not really clean. – tos Apr 11 '13 at 07:08
17

If you look at the Javadoc it points you towards using Calendar.

As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date, hrs, min) or GregorianCalendar(year + 1900, month, date, hrs, min).

If you look at the Date constructor params you'll see why it was deprecated:

Parameters:

year - the year minus 1900.
month - the month between 0-11.
date - the day of the month between 1-31.
hrs - the hours between 0-23.
min - the minutes between 0-59.

year isn't what you expect and neither is month.

To represent the date you have mentioned you need to call Date like this (not recommended)

new Date(2009-1900, 12-1, 9)

The alternative using Calendar is

Calendar cal = Calendar.getInstance();
cal.set(2009, 11, 9); //year is as expected, month is zero based, date is as expected
Date dt = cal.getTime();
Community
  • 1
  • 1
pjp
  • 17,039
  • 6
  • 33
  • 58
  • 2
    Calendar's month is still zero based. – BalusC Dec 09 '09 at 14:52
  • actually, month is what I'd expect. It's date that drive me nuts. Everything in Java is zero based, except the date! – David Dec 09 '09 at 15:06
  • @BlausC: So it is. No wonder people prefer to use Joda date time instead of this poor Calendar API. – pjp Dec 09 '09 at 15:47
  • 1
    Update: These terrible date-time classes have been supplanted by the *java.time* classes defined in JSR 310. See the modern solution in [Answer by Arvind Kumar Avinash](https://stackoverflow.com/a/67842678/642706). – Basil Bourque Jun 05 '21 at 03:29
8

You can also use the SimpleDateFormat object:

import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.ParseException;


public class DateTest {
    public static void main( String [] args ) throws ParseException {
        SimpleDateFormat sdf =  new SimpleDateFormat("yyyy, MM, dd");
        Date date = sdf.parse("2009, 12, 9");
        System.out.println( date );
    }
}
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • 2
    Just be careful not to make the `SimpleDateFormat` a `static` instance as it is not thread safe. See http://www.ibm.com/developerworks/java/library/j-jtp09263.html – pjp Dec 09 '09 at 14:48
  • :-o I didn't knew it was not thread safe. Fortunately most of the times I have used it ( although declared as class member ) was in a thread safe context :) – OscarRyz Dec 09 '09 at 15:00
  • 1
    Use the *java.time* classes for thread-safety and many other benefits. See the modern solution in [Answer by Arvind Kumar Avinash](https://stackoverflow.com/a/67842678/642706). – Basil Bourque Jun 05 '21 at 03:30
4

Tim, in your comments you mentioned that you are doing this in a GXT context - i.e. in GWT client code. GWT does not support GregorianCalendar and you will most likely not be able to put JodaTime through the GWTCompiler (you may be able to, but do you really want to).

I think you are left really with the option to using JNSI if you want to do calendar operations in GWT. See the Date class in JavaScript.

Nick Hristov
  • 905
  • 1
  • 8
  • 17
3

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Also, quoted below is a notice at the Home Page of Joda-Time:

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.

Solution using java.time, the modern API:

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = LocalDate.of(2009, 12, 9).atStartOfDay(ZoneId.of("Etc/GMT"));
        System.out.println(zdt);
    }
}

Output:

2009-12-09T00:00Z[Etc/GMT]

The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).

For any reason, if you need to convert this object of ZonedDateTime to an object of java.util.Date, you can do so as follows:

Instant instant = zdt.toInstant();
Date date = Date.from(instant);

ONLINE DEMO

Like java.util.Date, an Instant represents an instantaneous point on the timeline in UTC, but unlike java.util.Date, which does not represent a real Date-Time object (a java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT), it represents a real Date-Time object.

Learn more about java.time, the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
2
GregorianCalendar(year + 1900, month, date)

https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Date.html

fospathi
  • 537
  • 1
  • 6
  • 7
Dave
  • 5,133
  • 21
  • 27
2

Unfortunately date support in Java is completely awful. Officially, you'd probably have to do this with Calendar, but that shouldn't be necessary in my opinion. Like others have mentioned, Joda time is a lot better, but still not quite as easy to use as dates in Ruby on Rails.

I'm not aware of any Java package that gives you quite that amount of date support (Joda falls short a bit, but comes close), but in Groovy, using TimeCategory gives you very Ruby on Rails-like date support.

mcv
  • 4,217
  • 6
  • 34
  • 40
  • Much has changed since this post, with the arrival of the *java.time* classes defined in JSR 310 and built into Java 8 and later. See the modern solution in [Answer by Arvind Kumar Avinash](https://stackoverflow.com/a/67842678/642706). – Basil Bourque Jun 05 '21 at 03:31