Since Joda-Time time version 2.0 the static method org.joda.time.DateTime#now() was introduced.
To me it is not clear what is the benefit over the use of new DateTime() (as the code just delegates anyway).
public static DateTime now() {
return new DateTime();
}
Also from the java doc it is not clear to me which one I should prefer.
new DateTime
Obtains a {#code DateTime} set to the current system millisecond time using ISOChronology in the default time zone.
DateTime#now()
Constructs an instance set to the current system millisecond time using ISOChronology in the default time zone.
Can someone explain in which use case which one should be preferred?
new DateTime() requires that a new object be allocated. DateTime.now can reuse a single object across requests, since DateTime instances are immutable. That may cause less memory churn.
But largely I doubt it matters which you use.
The now() method was added to make Joda-Time a little bit closer to java.time.* in Java 8, making the process of conversion a little bit easier. The two methods have exactly the same behaviour.
I don't think there is any difference. Using DateTime.now() looks more elegant than new DateTime() in your code. Here is DateTime.now() source code.
public static DateTime now() {
return new DateTime();
}
Related
Should org.joda.time.DateTimeZone be defined as static in a class instead of creating a new instance each time it's needed, specially when we're always using the same time zone.
DateTimeZone is thread-safe and immutable so it does not make sense to create a new instance each time. Is my thinking correct?
To add more details, currently my class creates a DateTimeZone object in the constructor of my class, always for the same time zone, so I thought why not make it static instead of creating a new object each time.
DateTimeZone is thread-safe and immutable, and all subclasses must be as well.
See api
So yes. It can be declared as static field.
Should you do it or not, it depends on your class and overall project design. See here why static fields may be evil.
Yes, I think you can create is as a static field - and the link in #Mike's answer tells you about the possible drawbacks of doing so (like possible problems if you want to test your code in a different timezone and so on).
But if your concerns are about performance and memory usage, I wouldn't worry too much about that. It seems that Joda-Time uses an internal cache of DateTimeZone objects:
DateTimeZone zone = DateTimeZone.forID("Europe/London");
DateTimeZone other = DateTimeZone.forID("Europe/London");
System.out.println(zone == other); // true
The code above prints true, which means that both are the same object.
Of course this is an implementation detail (I'm using Joda-Time 2.9.9) and it's not good to rely on such details as these things can change.
Anyway, if you're sure that this timezone will never change, you can make it static. If there's a possibility of having more than one in the future, don't (I wouldn't).
I'm new to Java. I know the concept of static and non static method.
I'm wondering if it's possible to use non static methods of a class without having to create a reference to it.
Like for example, for my program I'm working with Date objects, and I need to get yesterday's date in one of them. I know one possible way is like the following:
Calendar cal= Calendar.getInstance();
cal.add(Calendar.DATE,-1);
Date yesterdayDate = new Date();
yesterdayDate = cal.getTime();
Is there a way to do that without having to create the cal reference that I will be using just once in the whole program?
Something like this (I know this is by no means a correct syntax):
Date yesterdayDate = new Date();
yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime();
If Calendar was following a fluent builder pattern, where i.e. the add method was adding, then returning the mutated instance, you would be able to.
You're not, because Calendar#add returns void.
But don't be fooled: Calendar.getInstance() does create an instance as indicated - you're just not assigning it to a reference.
What you are referring to is the known Builder pattern.
The Calendar class isn't build to support the builder pattern, but there are many other classes / apis where it is.
For example, DateTimeFormatterBuilder from joda time.
DateTimeFormatter monthAndYear = new DateTimeFormatterBuilder()
.appendMonthOfYearText()
.appendLiteral(' ')
.appendYear(4, 4)
.toFormatter();
You can always go ahead and create your own builders. (In your example, CalendarBuilder).
But you should be aware that the Calendar class is generally regarded as evil - it's not thread safe, for one. Newer alternatives are joda time and the java 8 api's.
if method return type is instance of any class, you should chain calls on it and you dont need to create named variable.
This is used in Fluent interface api, where every method returns instance of "this" class.
Note:
Be careful if you call many chained methods on different objects like:
collection.get(0).getAddress().getStreet().length();
because of possible NullPointerExceptions.
On the other hand, use of fluent api should be safe, because you always call it on "this" instance, so if api has not some strange bugs, it is safe and NPE should not occur.
The general answer is no, because classes like Calendar are stateful and therefore require an initialized instance to be able to operate. If you do:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE,-1);
You are first calling a factory method getInstance() to create an instance of GregorianCalendar, which is the default concrete implementation of Calendar. It is initialized to the default timezone and locale and set to the current system time. This means it is different than another instance you create some milliseconds later.
Then, calling add(...) or other manipulation methods on your instance affects the calendar state, following the programmed calendar logic. If this was not a discrete instance but global (static) state, multiple threads would interfere with each other and cause very confusing results.
The same holds for example for the SimpleDateFormat class. It is often incorrectly set up as a field and re-used for formatting dates in a multi-threaded context (e.g. the handle method of a servlet). This will now and then cause erratic behavior because SimpleDateFormat is also stateful.
So the conclusion is: you need to create isolated instances of classes like Calendar and SimpleDateFormat because they are stateful and thus not thread-safe.
Bear in mind that sometimes you can optimize a bit by declaring your instance before any iterations you are doing, and then re-setting its state instead of creating a new instance on each iteration (after all, creating an instance of Calendar is indeed a bit expensive).
The other answers all correct, but I think they miss one crucial point: if you are new to Java ... don't waste your time thinking about such questions.
Don't get me wrong: it is always good to understand the programming language you are using in great depth; and it is also important to have some common sense to avoid "really stupid performance" mistakes.
But: don't worry about "performance" and spent hours to reduce the number of objects your program is dealing ... from 100 to 95. That is a complete waste of time.
If you intend to write programs that are used for a longer period of time, and by more than one person (and "good" programs tend to get there pretty fast) then it is much more important that your program is easy to read, understand, and change.
The only valid reasons to look into "performance" are:
You are in the design phase; and as mentioned before one should avoid stupid mistakes that render your end-product "unusable" because of performance issues.
You are actually confronted with "performance" issues. Then you should start profiling your application; and then, based on that analysis improve the "slow" parts.
In other words: don't try to solve "non-existing" problems. And unless your application is running in an embedded environment where every byte of memory and every CPU cycle can come at a certain prize ... don't worry about creating those Calendar objects 10, 100 or 500 times.
It is not only because method is not static. Understand that you cannot chain like this -- yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime(); because add() method does not return anything. If that method would have returned you the same calendar object, you could chain them without creating a reference.
Just to understand how chaining works, you can try creating your own methods those return objects and call other methods on them.
First, please note that this question is not a duplicate of this Question:
Java Date vs Calendar. My question is much more specific. The referenced question asks "what" (or "which"), but I already know the "what" and am asking the "why".
I am on a team working on enhancements to an existing Java project for a client. This Java project uses java 6, and does not have Joda Time as a dependency. After inquiring, it looks like adding Joda Time or upgrading to Java 8 are not options.
So, when it comes to representing date/time as a field in an object, we have to use either Calendar or Date for property typing. The legacy code of this project is littered with Objects that use Calendar to represent date/time fields -- fields that we would never have cause to manipulate (as in add or subtract units of time, etc). I know that this is bad practice, as Calendar is a more complex object, while Date is simpler and would work just as well. (And granted, I know that both are fundamentally wrappers for a long of epoch millis, are mutable, and are poorly designed, but again these are our only two options.)
In other words, an object like this:
public class Reservation {
private Guest guest;
// Set only once, never used for calculations
private Calendar dateReserved;
...
}
Should be this instead:
public class Reservation {
private Guest guest;
// Set only once, never used for calculations
private Date dateReserved;
...
}
I then noticed that when adding new Objects for new features, my team was following the same convention of using Calendar instead of Date. When I brought this up, the reply was that it's better to use Calendar because it can do more and doesn't have all these deprecated methods like Date does.
I know that this reasoning is oversimplified. I also see that this answer to the broader question of usage expresses the same view, namely that Calendar should not be used for property typing. However, the answer doesn't contain much explanation as to why Calendar should not be preferred.
So I already know the "What". But I'm trying to make the case to my team, so my question is, "Why"? Why, when property typing, should Date be preferred to Calendar? What are the disadvantages of using Calendar instead of Date for property typing?
I agree with Jon Skeet's comment regarding calendar systems and time zones, and I think your premise is fundamentally flawed. Dates aren't better than Calendars. If you're never ever ever going to compare times, or never ever ever have two dates in different time zones, then sure, the smaller footprint can be nice, I guess, but at that point, just use longs and Unix timestamps. Calendars are by far the better object model, and after all, if you absolutely need it, you can get a Date object from it.
If you are stuck having to choose between Date and Calendar when property typing:
Use Calendar if either one of these is true:
You need to be able to adjust the date/time after it is initially set
(such as changing the month while leaving the day and hour the same).
You need to be aware of timezone.
Otherwise, use Date for the following reasons:
Expressing your intentions accurately. If you use Calendar, you are implying that you want a certain functionality that you don't actually intend to use (timezones, changing the day or month, etc).
Less hassle with String representations. For example, consider this class:
public class Reservation {
private Guest guest;
private Calendar dateReserved;
#Override
public String toString() {
return String.format("Reservation{guest=%s,dateReserved=\"%s\"}",
guest, dateReserved);
}
}
Now if you print out an instance of this class, you'll get something hideous:
Reservation{guest=Guest{id=17,name="John Smith"},dateReserved="java.util.GregorianCalendar[time=1426707020619,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=77,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=30,SECOND=20,MILLISECOND=619,ZONE_OFFSET=-28800000,DST_OFFSET=3600000]"}
Whereas if you had used Date instead, you'd get this:
Reservation{guest=Guest{id=17,name="John Smith"},dateReserved="Wed Mar 18 12:34:26 PDT 2015"}
So if you use Calendar and you want your toString() to be usable, you would need to call dateReserved.getTime() -- which means you'd need to add a null check. This goes for whether or not you end up using a DateFormat object.
Date is a smaller object, quicker to instantiate and with less overhead.
Date is practically immutable -- meaning that the only way to change a date object is to use deprecated methods. So, as said in point 1, expressing your intentions matters. If your date field should be immutable, don't confuse developers who will touch your code in the future by using Calendar (unless of course you need timezone awareness).
"Date" is a more intuitive name than "Calendar" for the type of a field that represents a single point in time.
Date object has fewer fields and occupies less memory than Calendar object and is also faster to instantiate.
I am just going through a tutorial and the instructor seemed to gloss over something which didn't make sense
In Java if I am looking to instantiate a new Gregorgian Date Object I would use:
GregorianCalendar gc= new GregorianCalendar (2010,1,14);
but if I am looking to use the Data Format object I would use:
DateFormat df = DateFormat.getDateInstance();
I would really like to understand why dateformat doesn't follow the first way of instantiating the class?
How would I know to lookout in future for a similar gotcha?
You should always consult the API documentation to see how you are to use it.
A new X() always create a new object so if you have multiple places you need it, you end up with multiple X'es which may be inefficient if a single X would do.
The .getDateInstance() call is a Factory that allow the API to decide by itself whether to return the same X even to multiple callers or a new one to each. For very expensive but reusable/sharable objects this is the typical way you get them.
The Calendar API was donated to Java a very long time ago and is not as well designed as could be. These days the typical response to "I have problem X with Calendar and/or java.util.Date" in java is to use the Joda library which is well designed. For new code using Java 8 or later, use the new java.time classes as commented by Basil Bourque.
The short answer is that the core Java API is poorly designed and inconsistent. There's often no good reason for these inconsistencies, you just need to live with them.
More generally, factory methods like DateFormat.getDateInstance() allow the API to select different implementation classes depending on the situation, whereas using a constructor directly means there's no such flexibility.
Incidentally, unless you specifically want a GregorianCalendar, then the recommended method for obtaining one is Calendar.getInstance(), which will return you a GregorianCalendar if your locale is appropriate. Other locales will return different Calendar implementations. This would be consistent with your DateFormat example.
this is because it's an abstract class more info on that can be found here: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
same, look if a class is abstract or not.
The Answer by Thorbjørn Ravn Andersen is correct. Here are some more thoughts.
Avoid legacy date-time classes
GregorianCalendar is one of the terrible date-time classes bundled with the earliest versions of Java, designed by people who did not understand date-time handling.
These classes were years ago supplanted by the modern java.time classes. The GregorianCalendar class is specifically replaced by ZonedDateTime.
Immutable classes
The java.time classes are designed to be immutable, making them thread-safe.
This means you never use new. Instead, call factory methods. Read about the naming conventions on such methods.
Let’s capture the current moment as seen through the wall-clock time used by the people of a particular region (a time zone). We call ZonedDateTime.now to capture the current moment. As you can see in the source code, the constructor of ZonedDateTime is marked private to prevent us from instantiating via new. Internally to that class, the factory method performs the new. You can see for yourself, searching that source code for new ZonedDateTime.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
By the way, if you must use a GregorianCalendar to interoperate with old code not yet updated to java.time, you can convert. See new conversion methods added to the old classes.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
…and…
GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;
In unit tests I often have methods that return a DateTime on or about now(). Is there a way to say that the actual DateTime is within a few seconds of the actual DateTime?
That sounds like a bad idea. Unit tests should not depend in any way on the real current time... this is why it's a good practice to inject some interface, called Clock perhaps, in your class's constructors and use that as the source for the current time. Then in your unit tests you can use a special implementation of that for which you can control the time it returns, making your tests deterministic.
That said, I'm sure you could easily write a method that checks that a DateTime is within a certain range of another DateTime by creating new DateTimes by adding and subtracting the desired number of seconds and then comparing.
Turns out, this is pretty easy with Joda Time:
Duration dur = new Duration(sender.getStartTime(), new DateTime());
assertTrue(5000 > dur.getMillis());