There is an anomaly I have observed while setting dates in Java.
I am trying the following:-
Date date1 = new Date("10/12/2018");
So when I am printing the date, it is coming of future
It was printing this date:- 14 June 2019.
When I am doing the following:-
Date date1 = new SimpleDateFormat("dd/MM/yyyy").parse("10/12/2018");
It is showing the exact date. Can anyone please explain why this happened?
Thanks in advance.
java.time
To hardcode a date use the following:
LocalDate date2 = LocalDate.of(2018, Month.OCTOBER, 12);
System.out.println("Harcoded date: " + date2);
You will never get in doubt which is month, day and year. Output is:
Harcoded date: 2018-10-12
You should avoid the poorly designed and long outdated Date class and even more its deprecated constructors. Instead I am using LocalDate from java.time, the modern Java date and time API. Also a LocalDate represents a calendar date (without time of day), contrary to Date, which despite its name represents a point in time.
BTW I could not reproduce your problem. I get Fri Oct 12 00:00:00 CEST 2018 (which also agrees with the documentation, though this part of the documentation is very hard to read and understand).
Link: Oracle tutorial: Date Time explaining how to use java.time.
The Date() constructor (Note: it's deprecated !) doesn't know what is month and year.
USA: MM/dd/yyyy while Europe it's dd/MM/yyyy.
In the second form you are explicit. In the the first form it picks the wrong one.
Related
I am having an issue parsing DialogFlow dates in Java.
DialogFlow allows us to use words to describe date period entities like "Christmas Eve", "afternoon", "next week", etc. (See https://cloud.google.com/dialogflow/docs/reference/system-entities)
However, when I use a term like "Christmas Eve", Dialogflow v2 returns the following object:
{"startDate": "2019-12-25T12:00:00-05:00", "endDate" : "2019-12-18T12:00:00-05:00"}.
Why does DialogFlow return that period for "Christmas Eve"?
With that, what is the best way to parse a date without the offset using LocalDateTime?
For example, given "2019-12-25T12:00:00-05:00", I would like the time to remain as "12:00:00"
I tried using the following code:
DateTimeFormatter isoDateFormatter = DateTimeFormatter.ISO_DATE_TIME;
LocalDateTime date = LocalDateTime.parse(dateStr, isoDateFormatter);
Date myDate = Date.from(date.atZone(ZoneId.of("UTC")).toInstant());
However, the new date is adjusted to return "Wed Dec 25 07:00:00 EST 2019"
How do I fix this to remove the offset without specifying a specific timezone?
You’re already there
Your parsing into LocalDateTime is correct. And a LocalDateTime is just that: a date and time without time zone. Isn’t that exactly what you want? Then just keep that and forget everything about the Date class. It’s poorly designed and long outdated anyway.
If you need an old-fashioned java.util.Date for a legacy API
Sometimes we do need a Date for a legacy API not yet upgraded to java.time, the modern Java date and time API. Unfortunately a Date isn’t a date and time without time zone. Instead it is a point in time (but without time zone alright). We can only pretend. And we do need to specify a time zone or offset for the conversion.
Instant myInstant = date.atZone(ZoneId.systemDefault()).toInstant();
Date myDate = Date.from(myInstant);
System.out.println(myDate);
Example output:
Wed Dec 25 12:00:00 EST 2019
date is the LocalDateTime from the code from the question.
I am exploiting the fact that a Date grabs the JVMs default time zone and uses it for rendering the string it returns from toString(), which is implicitly called when we print the Date. Many find this behaviour quite confusing. But while you didn’t get the result you asked for, it at least looks like you did. Except the time zone abbreviation is still printed.
My code:
DateFormat format = new SimpleDateFormat("dd/MM/YYYY");
Date Today = format.parse(today);
Date Date = format.parse(date);
difference = (Date.getTime() - Today.getTime()) / 86400000;
Math.abs(difference);
System.out.println(String.valueOf("date" + date));
System.out.println(String.valueOf("date" + Date));
System.out.println(String.valueOf("date" + today));
System.out.println(String.valueOf("date" + Today));
The output:
date29/11/2016
dateSun Dec 27 00:00:00 GMT+08:00 2015
date20/11/2016
dateSun Dec 27 00:00:00 GMT+08:00 2015
I have problems while parsing the date, the original date is 29/11/2016, however when parsed, the date becomes Sun Dec 27 00:00:00 GMT+08:00 2015.
This problem appears in my whole program whenevr it's related to date.
Format dd/MM/YYYY should be dd/MM/yyyy. See javadoc of SimpleDateFormat: y = Year, Y = Week year. – Andreas 12 mins ago
Thanks resolved.
I know you got your solution from Andreas’ comment already. What I want to do here is take a step back and suggest a few improvements to your code. Feel free to ignore.
Most importantly I suggest you throw the long outdated classes Date, DateFormat and SimpleDateFormat overboard and start using their modern replacements. These came out in the java.time package early in 2014. These also offer a much more straightforward and clear way of calculating the difference.
Follow the convention that says that a variable name begins with a lowercase letter. Specifically, in the same source file to use a class called Date and two variable called date and Date is bound to cause confusion.
Like Henry I also think you intended difference = Math.abs(difference);.
Your calls to String.valueOf() are superfluous and just seem to make the code a bit harder to read. Drop them.
For the sake of the example, in the code I suggest below, I am deliberately using your incorrect date format pattern string, dd/MM/YYYY.
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/YYYY");
LocalDate todayAsLocalDate = LocalDate.parse(today, format);
LocalDate dateAsLocalDate = LocalDate.parse(date, format);
difference = ChronoUnit.DAYS.between(todayAsLocalDate, dateAsLocalDate);
difference = Math.abs(difference);
System.out.println("date " + date);
System.out.println("date " + dateAsLocalDate);
System.out.println("date " + today);
System.out.println("date " + todayAsLocalDate);
System.out.println(difference);
As the code stands now, it throws a java.time.format.DateTimeParseException: Text '20/11/2016' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {WeekBasedYear[WeekFields[SUNDAY,1]]=2016, MonthOfYear=11, DayOfMonth=20},ISO of type java.time.format.Parsed. When the code is incorrect, I much prefer an exception over an incorrect result that might go unnoticed. So this is better than what SimpleDateFormat gave you.
While the message is not easy to read, the bit to notice is WeekBasedYear. Week-based years are only useful with week numbers, you intended none of that. If you compare with the documentation, you will see that uppercase Y in the pattern is week-based-year while lowercase y is year-of-era. So let’s correct:
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy");
Now the code prints:
date 29/11/2016
date 2016-11-29
date 20/11/2016
date 2016-11-20
9
We note one final advantage of the modern classes: you can have a date without a time-of-day when this is what you need, again giving code that models your requirements more precisely and thereby leaves less room for confusion.
Question: can I use the modern classes with my Java version?
If using at least Java 6, you can.
In Java 8 and later the new API comes built-in.
In Java 6 and 7 get the ThreeTen-Backport library, the backport of the new classes (that’s “ThreeTen” for JSR 310, where the modern API was first defined).
On Android, use the Android edition of ThreeTen-Backport. It’s called ThreeTenABP, and I think that there’s a wonderful explanation in this question: How to use ThreeTenABP in Android Project.
What is the difference between the two dates below in practice?
Date date = new Date();
Date date = Calendar.getInstance().getTime();
What I understand is that new Date() is a UTC/GMT based date while calendar's getTime() is based on TimeZone & System time. Am I right? Do I miss something still?
Moreover, if my above understanding is correct, can I say that the end results of the following two functions are exactly the same ?
1.
public String getDate1(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//I set the time zone & pass the new Date()
sdf.setTimeZone(TimeZone.getDefault());
return sdf.format(new Date());
}
2.
public String getDate2(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//I didn't set the time zone because I think calendar instance will handle timezone change
return sdf.format(Calendar.getInstance().getTime());
}
I appreciate if you could point out where I understand wrongly & explain to me clearly. Because I feel this thing is confused to me. Thanks!
Practical info about Java Calendar and Date
If you want to operate with different dates in your Java program you will use Java Calendar class.
I will try to give you some overview of not widely known facts about Java Calendar and Date classes, working code examples, which you can try right away.
The basic information about Calendar class is provided by Java API. The Calendar class is about days, months and years. One could ask: is not Date class about the same? Not exactly...
What is difference between Java Date and Calendar classes?
The difference between Date and Calendar is that Date class operates with specific instant in time and Calendar operates with difference between two dates. The Calendar class gives you possibility for converting between a specific instant in time and a set of calendar fields such as HOUR, YEAR, MONTH, DAY_OF_MONTH. You can also manipulate with the calendar fields, for example getting the date of your grandmother birthday :).
I would like to point some things about Calendar and Date which you should know and which are not obvious...
Leap seconds.
Years, months, dates and hours are in "normal" range like:
A year y - 1900.
A month from 0 to 11
A date (day of month) from 1 to 31 in the usual manner. calendar leap seconds
An hour 0 to 23.
A minute from 0 to 59 in the usual manner.
But, attention!! A second is represented by an integer from 0 to 61. Looks strange - 61 second, but do not forget about leap second. About once every year or two there is an extra second, called a "leap second." The leap second is always added as the last second of the day, and always on December 31 or June 30. For example, the last minute of the year 1995 was 61 seconds long, thanks to an added leap second.
Lenient fields.
Another funny feature is lenient and non-lenient fields in calendar. What is that? Example:
32 January 2006. Actually if you set your calendar lenient it will be 1 February 2006 and no problem for your program :). If it is non-lenient ArrayIndexOutOfBoundsException exception will be thrown.
Another question is 00:00 end or beginning of day? Is 00:00 A.M. or P.M.? Are midnight and noon A.M. or P.M?
Answer: 23:59 is the last minute of the day and 00:00 is the first minute of the next day. Midnight belongs to "am", and noon belongs to "pm", so on the same day, 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm.
And probably last question: what is epoch? and why this Epoch since January 1, 1970 00:00:00.000 GMT.
Actually it is Unix time, or POSIX time, is a system for describing points in time: it is the number of seconds after 00:00:00 UTC, January 1, 1970.
Wait, one question more!
"If we use the time which is counted since Epoch, how can I know which years had leap seconds and which not?"
Answer: To make life easier leap seconds are not counted. Java Date class takes actual time from OS and most of modern computers can not use leap seconds, their's internal clocks are not so precised. That's why periodical time synchronization is required.
There is no difference between at all between those two dates. (The second one is of course a bit wasteful in allocating a Calendar object that you don't use.)
An instance of java.util.Date is an absolute point in time. It has no knowledge of time zones. Setting the Default timezone on the SimpleDateFormat similarly does nothing, it uses the default by.... default!
To try to explain in different terms, the java.util.Date for
10:49 pm Dec 19, 2013 UTC
And
5:49 pm Dec 19, 2013 US Eastern Time
Is exactly the same object. The exact same java.util.Date represents both of those human-readable representations of time. The human-readable considerations only come into play when you use the formatter to turn it back and forth. (Hence why you set the timezone on the formatter, not on the date, date has no knowledge of what a timezone means.)
In 2022, you MUST use java.time classes and you can refer here to know almost everything that needs to be known about time. But if you are using Java versions older than 8, or if you are curious, read on for some high-level overview.
1. Date date = new Date(); //Thu Mar 24 04:15:37 GMT 2022
2. Date date = Calendar.getInstance().getTime(); //Thu Mar 24 04:15:37 GMT 2022
Date(Does not have a notion of timezone, and is mutable, i.e not thread-safe)
Date is sufficient if you need only a current timestamp in your
application, and you do not need to operate on dates, e.g., one-week
later. You can further use SimpleDateFormat to control the date/time
display format.
Calendar(Abstract class, concrete implementation is GregorianCalendar)
Calendar provides internationalization support. Looking into the
source code reveals that: getInstance() returns a GregorianCalendar
instance for all locales, (except BuddhistCalendar for Thai ("th_TH")
and JapaneseImperialCalendar for Japanese ("ja_JP")).
Trivia
If you look at the Date java documentation, you will see many deprecated methods and the note:As of JDK version 1.1, replaced by Calendar.XXX. This means Calendar was a failed attempt to fix the issues that Date class had.
Bonus
You might want to watch this to get some more insights of Date vs Calendar
I need to generate a new Date object for credit card expiration date, I only have a month and a year, how can I generate a Date based on those two? I need the easiest way possible. I was reading some other answers on here, but they all seem too sophisticated.
You could use java.util.Calendar:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.YEAR, year);
Date date = calendar.getTime();
java.time
Using java.time framework built into Java 8
import java.time.YearMonth;
int year = 2015;
int month = 12;
YearMonth.of(year,month); // 2015-12
from String
YearMonth.parse("2015-12"); // 2015-12
with custom DateTimeFormatter
import java.time.format.DateTimeFormatter;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM yyyy");
YearMonth.parse("12 2015", formatter); // 2015-12
Conversions
To convert YearMonth to more standard date representation which is LocalDate.
LocalDate startMonth = date.atDay(1); //2015-12-01
LocalDate endMonth = date.atEndOfMonth(); //2015-12-31
Possibly a non-answer since you asked for a java.util.Date, but it seems like a good opportunity to point out that most work with dates and times and calendars in Java should probably be done with the Joda-Time library, in which case
new LocalDate(year, month, 1)
comes to mind.
Joda-Time has a number of other nice things regarding days of the month. For example if you wanted to know the first day of the current month, you can write
LocalDate firstOfThisMonth = new LocalDate().withDayOfMonth(1);
In your comment you ask about passing a string to the java.util.Date constructor, for example:
new Date("2012-09-19")
This version of the constructor is deprecated, so don't use it. You should create a date formatter and call parse. This is good advice because you will probably have year and month as integer values, and will need to make a good string, properly padded and delimited and all that, which is incredibly hard to get right in all cases. For that reason use the date formatter which knows how to take care of all that stuff perfectly.
Other earlier answers showed how to do this.
Like
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM");
Date utilDate = formatter.parse(year + "/" + month);
Copied from Create a java.util.Date Object from a Year, Month, Day Forma
or maybe like
DateTime aDate = new DateTime(year, month, 1, 0, 0, 0);
Copied from What's the Right Way to Create a Date in Java?
The most common sense approach would be to use the Date("YYYY-MM-DD") constructor even though it is deprecated. This is the easiest way to create a date on the fly. Screw whoever decided to deprecate it. Long live Date("YYYY-MM-DD")!!!
Don’t use this answer. Use the answers by Przemek and Ray Toel. As Przemek says, prefer to use a YearMonth for representing year and month. As both say, if you must use a date, use LocalDate, it’s a date without time of day.
If you absolutely indispensably need an old-fashioned java.util.Date object for a legacy API that you cannot change, here’s one easy way to get one. It may not work as desired, it may not give you exactly the date that you need, it depends on your exact requirements.
YearMonth expiration = YearMonth.of(2021, 8); // or .of(2021, Month.AUGUST);
Date oldFashionedDateObject = Date.from(expiration
.atDay(1)
.atStartOfDay(ZoneId.systemDefault())
.toInstant());
System.out.println(oldFashionedDateObject);
On my computer this prints
Sun Aug 01 00:00:00 CEST 2021
What we got is the first of the month at midnight in my local time zone — more precisely, my JVM’s time zone setting. This is one good guess at what your legacy API expects, but it is also dangerous. The JVM’s time zone setting may be changed under our feet by other parts of the program or by other programs running in the same JVM. In other words, we cannot really be sure what we get.
The time zone issue gets even worse if the date is transmitted to a computer running a different time zone, like from client to server or vice versa, or to a database running its own time zone. There’s about 50 % risk that your Date will come through as a time in the previous month.
If you know the time zone required in the end, it will help to specify for example ZoneId.of("America/New_York") instead of the system default in the above snippet.
If your API is lenient and just needs some point within the correct month, you’ll be better off giving it the 2nd of the month UTC or the 3rd of the month in your own time zone. Here’s how to do the former:
Date oldFashionedDateObject = Date.from(expiration
.atDay(2)
.atStartOfDay(ZoneOffset.UTC)
.toInstant());
This question already has answers here:
Convert GMT to IST in java?
(5 answers)
Closed 6 years ago.
I am trying to convert time zone from UTC to GMT in java. I have tried several times and even used your guided method too. I am getting my output with correct timing in GMT format but along with "PDT 2012" written with it. Why so..?? I have tried hundreds of methods but can't get rid of it.
Please help me.
Thanks
For all Date / or DateTime related operations in Java I would recommend to use JodaTime Library
It is very useful to use Date/time with different point of views (calendar, timezone) and for computation as well: adding/substracting months, years, days and so on...
Since Java 8, an equivalent (improvement) of JodaTime is included in the JDK under the new package java.time (JSR-310) and no more needed to add it as dependency.
The author of JodaTime explains in his blog the difference between JodaTime and JSR-310.
Perhaps the following will be a starting point. It converts your current date to GMT:
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Calendar cal = Calendar.getInstance();
System.out.println(cal.getTime());
TimeZone currentTimeZone = cal.getTimeZone();
int offset = currentTimeZone.getOffset(cal.getTimeInMillis());
Date adjustedTime = new Date(cal.getTimeInMillis() - offset);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormat.format(adjustedTime));
A couple of notes:
You are probably not able see the PST change to UTC because you don't set the timezone on the date format
You shouldn't really use the abbreviations like "GMT" anymore. It is better to use the full name in the id field.
You'll have to be a bit more creative if you happen to run the above code on a system that has its default time already set to GMT.