I came to know that DateTimeFormatter has two implementation for formatting the date.
Pattern.format(date)
Date.format(pattern)
public static void main(String[] args) {
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate date = LocalDate.now();
String dateFormatText = date.format(pattern);
String patternFormatText = pattern.format(date);
System.out.println(dateFormatText);
System.out.println(patternFormatText);
}
Both the SysOut prints the same value.
The Oracle docs examples uses Date.format method, whereas I can see many tech blogs using the Pattern.format method.
Can anyone explain me what is the difference and which is best to use?
Source Code Demo : Here
Though opinion-based I will try an answer.
As Stephen C has already documented, the two forms are equivalent.
Which is best? As so often in programming the answer is: It‘s best to write what will be least surprising to those reading your code.
So what will be least surprising? I am sure that the answer varies. Your organization will — consciously or unconsciously — build a tradition for what you are doing, and the least surprising will be to follow that tradition.
Points of each option
I’d also like to take a look at some thinkable reasons why both options have crept into java.time. This may give us some further thoughts on advantages of one or the other.
And since I don’t do mind reading, it’s guesswork. I think that the form date.format(formatter) was formed with inspiration from at least two sides:
It’s parallel to date.toString(), which with java.time we also often use for formatting a date-time object to a string. In Joda-Time, the predecessor of java.time, we even had the same method name: date.toString(formatter).
It’s somehow parallel to DateType.parse(string, formatter), which is what we use for the opposite operation, converting the string to a date-time object. For example LocalDate.parse("08/04/2021", pattern). This form in turn is necessary with the design of java.time. formatter.parse(string) wouldn’t know whether to parse into a LocalDate, an Instant, a ZonedDateTime or one of the many other date-time types of java.time. (The form pattern.parse("08/04/2021", LocalDate::from) exists as an alternative, though, and is sometimes necessary, but not often used.)
And I may be missing something, but one reason why many tech blogs use formatter.format(date) is inspiration from the now obsolete SimpleDateFormat that consistently used format.format(date). I cannot completely escape the thought that maybe those bloggers have not fully gone into the java.time way of thinking.
Can anyone explain me what is the difference?
There is no significant difference.
The javadoc for LocalDateTime.format says:
public String format(DateTimeFormatter formatter)
Formats this date-time using the specified formatter.
This date-time will be passed to the formatter to produce a string.
In other words, LocalDateTime.format calls DateTimeFormatter.format.
... and which is best to use?
Neither is "best".
It is up to you decide which form expresses your intention more clearly. Do you want to say:
"LocalDateTime: format yourself with this formatter", or
"DateTimeFormatter: format this temporal value".
Related
I need to implement a labor calendar able to count working days and, of course, natural days. The calendar must be able to handle national holidays and these days must be submitted by the user.
So, if I need to calculate the difference between two days the counting must ignore Saturdays, Sundays, and Holidays.
The Java class Calendar, doesn't handle holidays or working days, so I need to make it by myself. I have think two possible ways:
First way:
I could implement a new Day class which would have a boolean isHoliday to check if that is a working day or not, then create a new class with all the methods I'd need to handle/count the days.
Pros:
Easy to handle
I can override/create methods like toString, toDate, etc...
Cons:
Heavy (Maybe?)
My doubt about this approach is how to store it. It'd mean to make 365 objects and store them in a Listor Linked List and that's a lot of data to handle.
Second way:
My second idea is to make it more simple. Create an array of Strings or Dates where I'd store the holidays.
Example new ArrayList<String> freeDays = ["01/01/2019", "05/01/2019", "06/01/2019"...] and with work with it using a new CalendarUtils class or something like that.
Pros:
More readable
Light
Cons:
Hard to work with
For me the first option looks better, however, I don't want to waste memory or use bad practices.
Which option looks better? Are there any third option?
Avoid legacy date-time classes
Never use Date or Calendar classes. Those terribly troublesome old classes are now legacy, supplanted by the java.time classes, specifically Instant and ZonedDateTime. You may find LocalDate helpful too.
Smart objects, not dumb strings
Never use strings to represent date-time within your Java code. Use objects, the java.time classes.
When exchanging date-time values as text, always use the standard ISO 8601 formats. The java.time classes use these formats by default when parsing/generating strings. For a date that would be YYYY-MM-DD such as 2018-01-23.
TemporalAdjuster interface
To skip weekends, use the TemporalAdjuster implementation found in the ThreeTen-Extra project.
nextWorkingDay
previousWorkingDay
Example:
LocalDate // Represent a date-only value, without a time-of-day and without a time zone.
.now( // Capture the current date.
ZoneId.of( "Africa/Tunis" ) // Time zone required. For any given moment the date varies around the globe by zone.
)
.with( // Invoke a `TemporalAdjuster` implementation.
org.threeten.extra.Temporals.nextWorkingDay()
) // Returns a `LocalDate`. Using immutable objects pattern, producing a fresh object based on the values of another while leaving the original unaltered.
To skip holidays, you must write your own code. No two people, companies, or countries share the same definition of holidays.
You’ll need to define your own list of holidays. I suggest writing that as an implementation of TemporalAdjuster for working neatly with the java.time classes. Perhaps nextBusinessDay and previousBusinessDay. That ThreeTen-Extra project mentioned above is open-source, so look to there for code to guide you. And I vaguely recall posting one or more implementations of TemporalAdjuster myself here on Stack Overflow.
You might store those holiday dates in a database for persistence. And represent them at runtime in chronological order as a List< LocalDate >, sorted with Collections.sort and searching with Collections.binarySearch. But beware of thread-safety. You’ll likely need to update that list during runtime. Writing while reading must be protected. Search for more info. And read the excellent book, Java Concurrency in Practice by Brian Goetz et al.
You can combine your holiday-skipping code with weekend-skipping code. Use a search engine to find my Answers on weekend-skipping using EnumSet and DayOfWeek enum. (The search feature built into Stack Overflow unfortunately skews towards Questions while ignoring Answers.)
Search Stack Overflow. All of this has been asked and answered before.
i have a string like this on my java code:
17:00
I want to make a subtraction using a constant integer
public static final int MAX_DUREE_TRAVAIL_JOUR = 10;
When i do this:
Integer.parseInt("17:00") - ConstantesIntervention.MAX_DUREE_TRAVAIL_JOUR
I have this error:
java.lang.NumberFormatException: For input string: "17:00"
Thx.
What are you expecting to happen? 17:00 is not a valid string representation of an integer.
You probably want to use a SimpleDateFormat to parse the string as a Date and do the time arithmetic on that.
Alternatively, take a look at the JodaTime library which provides much better handling of dates/times.
17:00 cant be to converted to an integer.
Because 17:00 is not a Correct integer.You should divide the string and use Integer.parse() then according to your business logic use those integers.
The answer by Ajai is correct.
Some advice: When working with dates and times, work with dates and times (not strings and integers). Meaning use date-time classes.
Use a good date-time library (not the mess that is java.util.Date/Calendar).
Use Joda-Time 2.3 now.
In the future, with Java 8, consider moving to JSR 310: Date and Time API which supplants the Date/Calendar classes and is inspired by Joda-Time.
P.S. Mercer, Joda-Time even knows how to speak français. See another answer of mine today for an example.
When you look at the javadoc of the java.util.Date class, most of the methods are deprecated. Why was this done?
Well, for two related reasons. It was a very poor implementation of the concept of Dates and Times and it was replaced by the Calendar class.
The Calendar class, although an improvement, leaves a lot to be desired as well, so for serious Date/Time work, everyone recommends Joda-Time. Java 8 brings the new java.time.* package, inspired by Joda-Time, defined by JSR-310, and intended to supplant the old Date/Calendar classes.
Edit: In response to the specific question of why the implementation is poor, there are many reasons. The JavaDoc sums it up as follows:
Unfortunately, the API for these functions was not amenable to internationalization.
In addition to this general deficiency (which covers issues like the lack of a Time Zone component as well as the date formatting which is better handled in DateFormat and the inability to have a non-Gregorian calendar representation), there are specific issues which really hurt the Date class, including the fact that year is presented in an offset of 1900 from Common Era year.
Calendar has its own problems, but even as early as JDK 1.1 it was obvious that java.util.Date was not going to cut it. Even though Calendar is arguable the worst JDK API, it has taken until version 7 to attempt to address it.
Date is mutable
Date doesn't have support for time zones
The latter led to it being replaced by Calendar. And the former, combined with the ease-of-use, lead to both being replaced by Joda-Time / JSR-310 (java.time.* package)
They're deprecated because Date was written as fast as possible back in the day when they wanted to rush the JDK out the door.
It turns out the Dates and Calendars are Hard. So, they created the Calendar class, which much more thought, in order to handle the Hard Parts of working with calendars.
They deprecated the Date methods and delegated to Calendar because they didn't want to change the behavior of the existing Date methods, and possibly break existing applications.
Here's a good answer straight from Oracle: http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html
A long-standing bugbear of Java developers has been the inadequate support for the date and time use cases of ordinary developers.
For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe, leading to potential concurrency issues for users—not something the average developer would expect to deal with when writing date-handling code.
Some of the date and time classes also exhibit quite poor API design. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive.
... java.util.Date represents an instant on the timeline—a wrapper around the number of milli-seconds since the UNIX epoch—but if you call toString(), the result suggests that it has a time zone, causing confusion among developers.
I don't know the official reason why it has been deprecated, but as far as I can tell GregorianCalendarand Joda-Time support operations on dates, meaning that you can add, for instance, a day to a date and have its month and year updated accordingly.
For instance, say you want to compute the day after the current date and today is May 31st; with java.util.Date, you just have getDays() +1, which returns 32, and you have to handle the knowledge that the current month doesn't have 32 days by yourself; with GregorianCalendaror Joda.time, adding a day to May 31st results in an object representing June 1st, hiding the complexity from your sight.
Well aware of performance and thread issues with SimpleDateFormat, I decided to go with FastDateFormat, until I realized that FastDateFormat is for formatting only, no parsing!
Is there an alternative to FastDateFormat, that is ready to use out of the box and much faster than SimpleDateFormat?
I believe FastDateFormat is one of the faster ones, so anything that is about as fast would do.
Just curious , any idea why FastDateFormat does not support parsing? Doesn't it seriously limit its use?
Note that since commons-lang 3.2, FastDateFormat supports parsing as well as printing.
See: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html
At a best guess, it's to keep FastDateFormat... well... fast, by limiting it to display only.
Apache Commons DateUtils has a parseDate function, but that uses SimpleDateFormat internally.
An alternative is to use the JodaTime library. It's a complete replacement for dealing with DateFormat, Date, and Calendar objects.
JodaTime has a DateTimeFormatter that can be used to create DateTime objects (JodaTime's equivalent of Java's Date objects) from strings.
An example of how to use it is like this:
String strInputDateTime = "2010-12-27"; // An example, this would really come from outside
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime dt = fmt.parseDateTime(strInputDateTime);
I don't know if this is really any faster than SimpleDateFormat, though.
Found something interesting here of this case in Android:
http://andmob.wikidot.com/faq-simpletimeformat
SimpleDateFormat, the first time you
try parsing (or, presumably,
formatting) a date, will load in all
the timezone data for your locale.
This will take 2-3 seconds. It is
hoped that this will be fixed in some
future edition of Android.
In the interim, consider using
AsyncTask to "warm up"
SimpleDateFormat in your process
before you need it. Just parse some
date in the AsyncTask doInBackground()
to get it to load the timezones
sometime when it will not impact the
user so much. Once initialized in your
process, SimpleDateFormat will run
quickly until your process is
terminated.
As of Java 8, one can use DateTimeFormatter along with the the Java 8 Time API to both parse and format dates. From the documentation:
This class is immutable and thread-safe.
It's recommended to use this class if possible for new work going forward instead of using SimpleDateFormat.
The 'problem' with SimpleDateFormat is not performance, its thread safety.
If you have thousands of threads and synchronizing is not an issue use synchronized (you can also pool the instances to alleviate this a little)
If you have a reasonable amount of threads the recommended way is to have a separate instance for each SimpleDateFormat.
UPDATE
As of Java 8, just use DateTimeFormatter. It is immutable, thread safe, faster, and more flexible. (It also offers nice features like default patterns for ISO-8601 date/time strings.)
Do you really need to parse dates that quickly? Have you tested SimpleDateFormat and found it too slow for your needs?
Note, there are a variety of ways to cache slow-to-construct, non-thread-safe class instances (e.g. ThreadLocal, pools).
Every time I need to work with date and/or timstamps in Java I always feel like I'm doing something wrong and spend endless hours trying to find a better way of working with the APIs without having to code my own Date and Time utility classes. Here's a couple of annoying things I just ran into:
0-based months. I realize that best practice is to use Calendar.SEPTEMBER instead of 8, but it's annoying that 8 represents September and not August.
Getting a date without a timestamp. I always need the utility that Zeros out the timestamp portion of the date.
I know there's other issues I've had in the past, but can't recall. Feel free to add more in your responses.
So, my question is ... What third party APIs do you use to simplify Java's usage of Date and Time manipulation, if any? Any thoughts on using Joda? Anyone looked closer at JSR-310 Date and Time API?
java.time
Java 8 and later now includes the java.time framework. Inspired by Joda-Time, defined by JSR 310, extended by the ThreeTen-Extra project. See the Tutorial.
This framework supplants the old java.util.Date/.Calendar classes. Conversion methods let you convert back and forth to work with old code not yet updated for the java.time types.
The core classes are:
InstantA moment on the timeline, always in UTC.
ZoneIdA time zone. The subclass ZoneOffset includes a constant for UTC.
ZonedDateTime = Instant + ZoneIdRepresents a moment on the timeline adjusted into a specific time zone.
This framework solves the couple of problems you listed.
0-based months
Month numbers are 1-12 in java.time.
Even better, an Enum (Month) provides an object instance for each month of the year. So you need not depend on "magic" numbers in your code like 9 or 10.
if ( theMonth.equals ( Month.OCTOBER ) ) { …
Furthermore, that enum includes some handy utility methods such as getting a month’s localized name.
If not yet familiar with Java enums, read the Tutorial and study up. They are surprisingly handy and powerful.
A date without a time
The LocalDate class represents a date-only value, without time-of-day, without time zone.
LocalDate localDate = LocalDate.parse( "2015-01-02" );
Note that determining a date requires a time zone. A new day dawns earlier in Paris than in Montréal where it is still ‘yesterday’. The ZoneId class represents a time zone.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
Similarly, there is a LocalTime class for a time-of-day not yet tied to a date or time zone.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
This post has a good discussion on comparing the Java Date/Time API vs JODA.
I personally just use Gregorian Calendar and SimpleDateFormat any time I need to manipulate dates/times in Java. I've never really had any problems in using the Java API and find it quite easy to use, so have not really looked into any alternatives.
The Apache Commons Lang project has a DateUtils class that performs helpful Date operations.
I use DateUtils.truncate() a lot, which will "zero out" parts of the Date for you (helpful if you want your Date object to, say, represent a date and not include any time information). Each method works for both Date and Calendar objects too.
http://commons.apache.org/lang/
I've been using Joda exclusively for three years now and would definitely recommend it - it has the whole area covered with an interface that 'does what it says'.
Joda can look complex when you start, as eg it has concepts of periods, duration and intervals which look sort of similar, but you can start off simply by substituting org.joda.time.DateTime (or org.joda.time.DateMidnight) for java.util.Date in your code, and sticking with the many useful methods that those classes contain, before understanding the other areas.
Im using GregorianCalendar - always and everywhere. Simple java.util.Date is too complex, yeah.
So, my advice is - use GC, its simple
It's the same in javascript. Someone must have been smoking something when they think it's a good idea to let 2008 mean the year 2008, 31 to mean the 31st day in the month, and - this is the best part - 11 to mean the 12th month.
On the other hand, they got it right on two out of three.
The thing that always gets me with Java is the date time library. I've never used Joda, just briefly look at it, looks like its a pretty good implementation, and if I understand JSR-130 correctly its taking knowledge from Joda and eventually having it included in JavaSE.
Quite often for past projects I've wrapped the Java date time objects, which in itself was quite a task. Then used the wrappers for date manipulation.
Date APIs are very difficult to design, especially if they have to deal with localization. Try to roll your own and see, it's worth doing at least once. The fact that Joda was able to do such a good job is a real credit to its developers. To answer your question, I've heard nothing but good things about that library, though I have never played around with it myself.
A lot of programmers begin by using Date, which has numerous deprecated overloaded constructors (making it difficult to use), but once you figure out GregorianCalendar it becomes a little bit easier to manage. The example here is pretty helpful:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/GregorianCalendar.html
It's really simple to write your own date API which sits on top of the raw Java classes, Date and Calendar. Basically both date and Calendar suffer from the fact that they are trying to cram two concepts into one class:
Date (i.e. Year-Month-Day)
Instant (i.e. currentTimeMillis)
When you understand this, it will just revolutionize how you handle date-like concepts in your code. Things will be simpler, clearer, better. In every sense!
For me, Joda is over-complicated, at least for the overwhelming majority of purposes and I particularly don't like the fact that they have gone against standard Java forms, one example being how they parse and format dates. Stephen Colebourne, the guy behind JODA, is the spec lead of JSR-310 and this suffers from the same problems imho (I've followed and contributed to the discussions for the last few years).
Do it yourself; it's easy. Just fill in the following classes: MyDate (wrapping year-month-day), Month (an enum), TimeOfDay (hour-min-sec-millis), DayOfWeek (enum), Instant (wrapping a long). Always consider time-zones when converting between Instants and Dates.
If this seems daunting, you can use Calendar and SimpleDateFormat under the hood. You'll do this in a day and never regret it.