This question already has answers here:
How to compare LocalDate instances Java 8
(3 answers)
Number format exception while parsing the date to long
(3 answers)
Closed 4 years ago.
I'd like to check if the system date (e.g. the current date) is before an expiry date before opening my software.
I have written the following code, however it throws a NumberFormatException. Why might this be happening?
public class dateController implements Initializable {
#FXML Label lblDate;
Alert alert = new Alert(AlertType.INFORMATION);
#Override
public void initialize(URL location, ResourceBundle resources) {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = new Date();
lblDate.setText(dateFormat.format(date));
String a ="19/09/2018";
String currentdate = lblDate.getText();
String LastRunDate = currentdate;
if(Integer.parseInt(currentdate) < Integer.parseInt(a)) {
alert.setHeaderText(null);
alert.setContentText("Successfull");
alert.show();
}
}
}
Why might this be happening?
Integer.parseInt is fine for parsing a string like 42 into an int. You are trying to parse a string like 17/09/2018 using that method. Your string does not represent a valid int value (and frankly I don’t know which integer you had expected to come out of it?) Therefore the parseInt method throws the NumberFormatException.
Then what to do instead?
Use LocalDate for representing a date and its isBefore (or isAfter) to compare with another date.
LocalDate expirationDate = LocalDate.of(2018, Month.SEPTEMBER, 19);
LocalDate today = LocalDate.now(ZoneId.systemDefault());
if (today.isBefore(expirationDate)) {
alert.setHeaderText(null);
alert.setContentText("Successful");
alert.show();
}
Notice how much simpler it is compared to your code in the question. In this case you need no formatting or parsing. I am using the JVM’s time zone setting to get today’s date (which you also did in the question). So a user may possibly push the expiration by a couple of hours by changing time zone. If you want to avoid it, you can also hardcode the time zone as for example ZoneId.of("Asia/Ust-Nera")
If you do need to parse a string like 19/09/2018:
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("dd/MM/uuuu");
String a ="19/09/2018";
LocalDate expirationDate = LocalDate.parse(a, dateFormatter);
System.out.println("Expiration date is " + expirationDate);
This snippet outputs:
Expiration date is 2018-09-19
Stay away from Date, DateFormat and SimpleDateFormat. They are long outdated, and the last two in particular notoriously troublesome. Use java.time, the modern Java date and time API, instead.
Link: The Java™ Tutorials: Trail: Date Time
Related
This question already has answers here:
Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST
(9 answers)
How to validate the DateTime string format "2018-01-22T18:23:00.000Z" in Java?
(2 answers)
parsing date/time to localtimezone
(2 answers)
Closed 3 years ago.
I am having Input Date as "2020-10-31T00:00:00Z". i want to parse this Date to get Long milliseconds.
Note: Converted milliseconds should be in Sydney Time (ie GMT+11).
FYI,
public static long RegoExpiryDateFormatter(String regoExpiryDate)
{
long epoch = 0;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(TimeZone.getTimeZone("GMT+11"));
Date date;
try {
date = df.parse(regoExpiryDate);
epoch = date.getTime();
} catch (ParseException e) {
System.out.println("Exception is:" + e.getMessage());
e.printStackTrace();
}
System.out.println("Converted regoExpiryDate Timestamp*************** " + epoch);
return epoch;
}
Output: 1604062800000 which gives Date as 30/10/2019 by using Epoch Converter, but in input i'm passing 31st as Date.
Can anyone please clarify this?
By doing df.setTimeZone(TimeZone.getTimeZone("GMT+11"));, you are asking the date formatter to interpret your string in the GMT+11 time zone. However, your string shouldn't be interpreted in that timezone. See that Z in the string? That stands for the GMT time zone, so you should have done this instead:
df.setTimeZone(TimeZone.getTimeZone("GMT"));
In fact, your string is in the ISO 8601 format for an Instant (or a "point in time", if you prefer). Therefore, you could just parse it with Instant.parse, and get the number of milliseconds with toEpochMilli:
System.out.println(Instant.parse("2020-10-31T00:00:00Z").toEpochMilli());
// prints 1604102400000
Warning: you shouldn't really use SimpleDateFormat anymore if the Java 8 APIs (i.e. Instant and such) are available. Even if they are not, you should use NodaTime or something like that.
This question already has answers here:
How to format date and time in Android?
(26 answers)
Closed 3 years ago.
I was building an android app and i was using Date class in my project to get the current date. I formatted the date with simpledateformatter and displayed it like dd-mm-yyyy (i.e. day month year) .
Now i also want to get the time in format of hh:MM:ss a (hours minutes seconds AM/PM)
As i was using date's instance i saw that it displays date and time also ( in default format). So i tried to fetch time from the date's instance.(let's say d is date class instance). I also found getTime() method of date class and performed d.getTime() but it returned me a long (which is duration from some fixed time from past to current time). Now i want time in desired format but this getTime() method is giving me long.
May you provide me some way on how to process this long value to get the desired format of time out of it. For example , d.getTime() return me some value( say 11233) and i want in format like this (11:33:22).
You can make that
private final String DATE_FORMAT = "dd.MM.yyyy HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
Date got = sdf.parse(date);
It returns Date with time to you
Use this snippet to get the date and time both.
public String currentDateTime() {
Calendar c = Calendar.getInstance();
SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss aa"); //it will give you the date in the formate that is given in the image
String datetime = dateformat.format(c.getTime()); // it will give you the date
return datetime;
}
Note: Take a look in the image .
Date().getTime() is providing you the timestamp
Change the format to your requirement like mm:hh:ss a
Kotlin
fun getDateTime():String {
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
val date = Date()
return inputFormat.format(date.time)
}
JAVA
private String getDateTime(){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
return format.format(new Date().getTime());
}
This question already has answers here:
SimpleDateFormat parsing date with 'Z' literal [duplicate]
(12 answers)
Closed 4 years ago.
I am using the below code to format millisecond resolution date strings. It works for 2018-09-14T13:05:21.329Z but not 2018-09-14T13:05:21.3Z. Can anybody suggest the reason and how to correct it?
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date parsedDate = formatter.parse(date);
String destDate = sdfDestination.format(parsedDate);
return destDate;
} catch (java.text.ParseException parseException) {
logger.error("Parse Exception occured while converting publication time to date "
+ "format 'yyyy-MM-dd HH:mm:ss'", parseException);
}
I get below exception:
java.text.ParseException: Unparseable date: "2018-09-14T13:05:21.3Z"
at java.text.DateFormat.parse(Unknown Source) ~[na:1.8.0_181]
at com.noordpool.api.implementation.utility.Utility.parseDate(Utility.java:136) [classes/:na]
at com.noordpool.api.implementation.utility.Utility.parseMessage(Utility.java:77) [classes/:na]
Your only problem is that you are using a wrong pattern for SimpleDateFormat, you need to change:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
To:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Because the Z used in the date string means "zero hour offset" so you just need to pass it as 'Z' in your pattern.
This is a working demo with the right pattern.
Edit:
And to make things work with different Locales and Timezones, you need to use the appropriate Locale when you are creating the SimpleDateFormat instance, this is how should be the code:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
The only possible issue I can see is that you're passing in milliseconds incorrectly and the program doesn't know what to do about it.
So the last part of the formatter indicates with milliseconds and a timezone as .SSSX
But how does it evaluate 3Z for the input into this? I mean, do you say it's 300 timezone Z, or say it's 003 timezone Z, or worse, try and parse it as 3Z, which hopefully you see that you cannot turn '3Z' into a number.
To remedy this, I'd validate your input 'date' and ensure the milliseconds part is always 3 digits long, this removes the ambiguity and the program always knows that you mean '300 milliseconds, timezone Z'.
There is a problem in java 8 where the number of characters that you specified with the formatter should be an exact match (which is not specified in the documentation).
You can use three different Formatters and use nested exception as follows:
DateFormat format1 = new SimpleDateFormat("y-M-d'T'H:m:s.SX");
DateFormat format2 = new SimpleDateFormat("y-M-d'T'H:m:s.SSX");
DateFormat format3 = new SimpleDateFormat("y-M-d'T'H:m:s.SSSX");
Date parsedDate;
try {
// Parsing for the case - 2018-09-14T13:05:21.3Z
parsedDate = format1.parse(date);
} catch (ParseException e1) {
try {
// Parsing for the case - 2018-09-14T13:05:21.32Z
parsedDate = format2.parse(date);
} catch (ParseException e2) {
try {
// Parsing for the case - 2018-09-14T13:05:21.329Z
parsedDate = format3.parse(date);
} catch (ParseException e2) {
//The input date format is wrong
logger.error("Wrong format for date - " + date);
}
}
}
java.time
DateTimeFormatter dtfDestination
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String date = "2018-09-14T13:05:21.3Z";
String destDate = Instant.parse(date)
.atZone(ZoneId.of("Indian/Comoro"))
.format(dtfDestination);
System.out.println(destDate);
Output from this snippet is:
2018-09-14 16:05:21
Please substitute your correct time zone if it didn’t happen to be Indian/Comoro, since correct output depends on using the correct time zone. If you want to use your JVM’s default time zone, specify ZoneId.systemDefault(), but be aware that the default can be changed at any time from other parts of your program or other programs running in the same JVM.
I am exploiting the fact that your string, "2018-09-14T13:05:21.3Z", is in ISO 8601 format, the format that the classes of java.time parse as their default, that is, without any explicit formatter. Instant.parse accepts anything from 0 through 9 decimals on the seconds, so there is no problem giving it a string with just 1 decimal, as you did. In comparison there is no way that an old-fashioned SimpleDateFormat can parse 1 decimal on the seconds with full precision since it takes pattern letter (uppercase) S to mean milliseconds, so .3 will be parsed as 3 milliseconds, not 3 tenths of a second, as it means.
Jahnavi Paliwal has already correctly diagnosed and explained the reason for the exception you got.
The date-time classes that you used, DateFormat, SimpleDateFormat and Date, are all long outdated and SimpleDateFormat in particular is notoriously troublesome. Since you seem to be using Java 8 (and even if you didn’t), I suggest you avoid those classes completely and use java.time instead.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
This question already has answers here:
Java Date Error
(8 answers)
Closed 4 years ago.
I want to convert String values in the format of mm/dd/yy to YYYY-MM-DD Date. how to do this conversion?
The input parameter is: 03/01/18
Code to convert String to Date is given below
public static Date stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
try {
date = formatter.parse(dateVlaue);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
When tried to convert using this method it shows the following error
java.text.ParseException: Unparseable date: "03/01/18"
As you say the input is in a different format, first convert the String to a valid Date object. Once you have the Date object you can format it into different types , as you want, check.
To Convert as Date,
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
date = formatter.parse(dateVlaue);
To Print it out in the other format,
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
dateString = formatter1.format(date)
You are writing it the wrong way. In fact, for the date you want to convert, you need to write
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
The format you are passing to SimpleDateFormat is ("yyyy-MM-dd") which expects date to be in form 2013-03-01 and hence the error.
You need to supply the correct format that you are passing your input as something like below
public static Date stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yy");
try {
date = formatter.parse(dateVlaue);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
The solution for the above problem
Convert the String date value in the Format of "dd/mm/yy" to Date.
By using the converted Date can able to frame the required date format.
The method has given below
public static String stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd/mm/yy");
String dateString = null;
try {
// convert to Date Format From "dd/mm/yy" to Date
date = formatter.parse(dateVlaue);
// from the Converted date to the required format eg : "yyyy-MM-dd"
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
dateString = formatter1.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return dateString;
}
EDIT: Your question said “String values in the format of mm/dd/yy”, but I understand from your comments that you meant “my input format is dd/mm/yy as string”, so I have changed the format pattern string in the below code accordingly. Otherwise the code is the same in both cases.
public static Optional<LocalDate> stringToDateLinen(String dateValue) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yy");
try {
return Optional.of(LocalDate.parse(dateValue, dateFormatter));
} catch (DateTimeParseException dtpe) {
return Optional.empty();
}
}
Try it:
stringToDateLinen("03/01/18")
.ifPresentOrElse(System.out::println,
() -> System.out.println("Could not parse"));
Output:
2018-01-03
I recommend you stay away from SimpleDateFormat. It is long outdated and notoriously troublesome too. And Date is just as outdated. Instead use LocalDate and DateTimeFormatter from java.time, the modern Java date and time API. It is so much nicer to work with. A LocalDate is a date without time of day, so this suites your requirements much more nicely than a Date, which despite its name is a point in time. LocalDate.toString() produces exactly the format you said you desired (though the LocalDate doesn’t have a format in it).
My method interprets your 2-digit year as 2000-based, that is, from 2000 through 2099. Please think twice before deciding that this is what you want.
What would you want to happen if the string cannot be parsed into a valid date? I’m afraid that returning null is a NullPointerException waiting to happen and a subsequent debugging session to track down the root cause. You may consider letting the DateTimeParseException be thrown out of your method (just declare that in Javadoc) so the root cause is in the stack trace. Or even throw an AssertionError if the situation is not supposed to happen. In my code I am returning an Optional, which clearly signals to the caller that there may not be a result, which (I hope) prevents any NullPointerException. In the code calling the method I am using the ifPresentOrElse method introduced in Java 9. If not using Java 9 yet, use ifPresent and/or read more about using Optional elsewhere.
What went wrong in your code?
The other answers are correct: Your format pattern string used for parsing needs to match the input (not your output). The ParseException was thrown because the format pattern contained hyphens and the input slashes. It was good that you got the exception because another problem is that the order of year, month and day doesn’t match, neither does the number of digits in the year.
Link
Oracle tutorial: Date Time explaining how to use java.time.
This question already has answers here:
Adding days to a date in Java [duplicate]
(6 answers)
Closed 8 years ago.
String dt="2014-04-25";
I want to add n number of days in this date ... I have searched a lot but was not able to get any good working code....
I have tried SimpleDateFormat but it is not working so please help me with the code....
You can do it using joda time library
import org.joda.time;
String dt="2014-04-25";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime dateTime = formatter.parseDateTime(dt);
DateTime oneDayPlus = dateTime.plusDays(1);
String oneDayPlusString = oneDayPlus.toString(formatter); // This is "2014-04-26"
oneDayPlus would give you the object you need.
Again, this needs you to use an extra jar file, so use it if you can introduce adding a new library.
Remember String != Date they don't have anything in common (ok, exclude the fact that a string could represent a Date ok?)
If you want to add days to a String you could convert it to a Date and use normal APIs to add days to it.
And here we use SimpleDateFormat which is used to create from a patten string a date
String dt = "2014-04-25";
// yyyy-MM-dd
// year-month-day
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
try
{
Date date = format.parse(dt);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, 5);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
}
catch (ParseException e)
{
System.out.println("Wrong date");
}
yyyy-MM-dd is our patten which corrisponds to our string.
format.parse(dt);
wil try to create a Date object from the string we passed, if it fails it throw an ParseException. (If you want to check if it works just try to pass an invalid string)
Then we create a new Calendar instance and set the date to the date we created (which corrisponds to the the date in our string) and add five days to our date.. and here we go. Now calendar will refer to the 30-04-2014.
You can replace the
calendar.add(Calendar.DAY_OF_MONTH, 5);
with
calendar.add(Calendar.DAY_OF_MONTH, n);
If you want and it will add n days.