Java: SimpleDateFormat not simplifying to specified pattern? [duplicate] - java

This question already has answers here:
display Java.util.Date in a specific format
(11 answers)
want current date and time in "dd/MM/yyyy HH:mm:ss.SS" format
(11 answers)
convert java.util.Date to java.util.Date with different formating in JAVA [duplicate]
(1 answer)
SimpleDateFormat ignoring month when parsing
(4 answers)
Closed 2 years ago.
Tried converting string of yyyy-mm-dd, example 2013-12-30, to date object using SimpleDateFormat.parse("yyyy-mm-dd").
Expected output of 2013-12-30, received output of Mon Dec 30 00:00:00 EST 2013 object.
Tried finding out why SimpleDateFormat is returning a different format, but overwhelmed when trying to look through the java api. Asking for clarifications on what is going on and what would be a better approach.
Note: Stuck using java.utl.Date.
...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateArray = new Date[rowCount];
try {
for(int index = 0; index < rowCount; index++){
dateArray[index] = simpleDateFormat.parse(fileArray[index][0]);
System.out.println(dateArray[index].toString());
}
} catch(ParseException err){
System.out.println("ERR: Data parse exception. Format is not correct.");
err.printStackTrace();
}

The pattern, mm stands for minute, not month. For month, you need to use MM.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
String strDate = "2013-12-30";
SimpleDateFormat sdfISO8601 = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdfISO8601.parse(strDate);
System.out.println(date);
String strDateISO8601 = sdfISO8601.format(date);
System.out.println(strDateISO8601);
// Some other format
String strSomeOtherFormat = new SimpleDateFormat("EEEE MMM dd yyyy").format(date);
System.out.println(strSomeOtherFormat);
}
}
I also recommend you check Convert UTC String to UTC Date.
Note that the date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. I suggest you should stop using them completely and switch to the modern date-time API.
Using the modern date-time API:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDate = "2013-12-30";
LocalDate date = LocalDate.parse(strDate);
System.out.println(date);
String strDate8601 = date.toString();
System.out.println(strDate8601);
// Custom format
String customFormat = DateTimeFormatter.ofPattern("EEEE MMM dd uuuu").format(date);
System.out.println(customFormat);
}
}
Your date string is already in ISO 8601 format for date and therefore do not need to use any formatter to parse it when you use the modern date-time API.
Learn more about the modern date-time API at Trail: Date Time.
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.

Related

Convert a String (with reserved characters) to Date in Java

I want to convert a String (with reserved characters) to Date in Java
I have a string with some reserved characters in it. I am getting it from some source. Also I get the format of it from the same source. I tried to convert that string to a date but I was unable to.
The date I get:
{ts '2021-03-24 12:52:38.933'}
The format I get:
'{ts' ''yyyy-MM-dd HH:mm:ss{.SSS}[Z]'''}'
I tried with the sample code snippet but since {} are reserved characters and also ts is an invalid character for parsing, I am unable to parse it. Please help with how I can solve this.
Obviously I can do some string manipulation and convert it to a format I want but I don't want to do that.
String dateInString = "{ts '2021-03-24 12:52:38.933'}";
SimpleDateFormat sdf = new SimpleDateFormat("{ts' ''yyyy-MM-dd HH:mm:ss{.SSS}[Z]'''}", Locale.ENGLISH);
try {
Date date = sdf.parse(dateInString);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
You need to escape ' with another '.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String dateInString = "{ts '2021-03-24 12:52:38.933'}";
SimpleDateFormat parser = new SimpleDateFormat("'{ts '''yyyy-MM-dd HH:mm:ss.SSS'''}'", Locale.ENGLISH);
Date date = parser.parse(dateInString);
System.out.println(date);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println(formatter.format(date));
}
}
Output:
Wed Mar 24 12:52:38 GMT 2021
2021-03-24T12:52:38.933
ONLINE DEMO
Note that 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*.
Solution using java.time, the modern Date-Time API:
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String dateInString = "{ts '2021-03-24 12:52:38.933'}";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("'{ts '''yyyy-MM-dd HH:mm:ss.SSS'''}'", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(dateInString, parser);
System.out.println(ldt);
}
}
Output:
2021-03-24T12:52:38.933
ONLINE DEMO
Learn more about 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.

simpledate formater to format returns incorrect.deducted date after formating [duplicate]

This question already has answers here:
SimpleDateFormat producing wrong date time when parsing "YYYY-MM-dd HH:mm"
(5 answers)
how to parse 'following string '20190911T14:37:08.7770400' into date format
(3 answers)
Unable to parse date Apr 15, 2020 12:14:17 AM to LocalDatetime
(2 answers)
Closed 2 years ago.
I am attempting to parse date using SimpleDateFormat. The date is parsed successfully but the output date format is incorrect or deducted by a year, The Date method that uses SimpleDateFormat is shown below
public Date parseDate(String date) {
SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-DD",Locale.ENGLISH);
Date parsedDate = null;
try {
parsedDate = format.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return parsedDate;
}
Here is the sample image parsed
Date start = parseDate(dateVal); // dateVal sample is 2020-09-25
When the date is parsed, this is the output
Sun Dec 29 00:00:00 WAT 2019
My challenge is to return a date sample of - 2020-09-25 after parsing
You have used the wrong symbols. Use yyyy-MM-dd instead of YYYY-MM-DD. Note that DD stands for the Day of the year and Y stands for Week year. Check the documentation to learn more about it.
Also, I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time.
If you are using Android and your Android API level is still not compliant with Java8, check How to use ThreeTenABP in Android Project and Java 8+ APIs available through desugaring.
Using modern date-time API:
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2020-09-25");
System.out.println(date);
}
}
Output:
2020-09-25
Note that since your date-time string is already in the ISO8601 format, you do not need to use any DateTimeFormatter while parsing it to LocalDate as it is the default pattern used by LocalDate#parse.
Using the legacy date-time API:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2020-09-25");
System.out.println(date);
}
}
You can do it like so:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
parsedDate = format.parse(date);
You should be using parse(String) instead of parseDate()

How to convert String to Date with a specific format in java [duplicate]

This question already has answers here:
display Java.util.Date in a specific format
(11 answers)
want current date and time in "dd/MM/yyyy HH:mm:ss.SS" format
(11 answers)
Convert String date into java.util.Date in the dd/MM/yyyy format [duplicate]
(1 answer)
return date type with format in java [duplicate]
(1 answer)
Calendar date to yyyy-MM-dd format in java
(11 answers)
Closed 3 years ago.
I have a requirement to convert String to Date (in dd-MM-yyyy format). But dateformat.parse gives the format with seconds. I need to convert the String date to Date in the same format as mentioned above.
The class Date will always contain both date a nd time information, since it represents an instant in time.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ParsingDate {
public static void main(String[] args) {
DateFormat fmt = new SimpleDateFormat("dd-MM-yyyy");
Date d;
try {
d = fmt.parse("04-12-2019");
System.out.println(d); // Wed Dec 04 00:00:00 CET 2019
} catch (ParseException e) {
e.printStackTrace();
}
}
}
As you can see, hours, minutes, seconds and millis get all set to 0.
If you later want to output the date in string format, you need to use the DateFormat#format(Date) method:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ParsingDate {
public static void main(String[] args) {
DateFormat fmt = new SimpleDateFormat("dd-MM-yyyy");
Date d = new Date();
System.out.println(d); // Wed Dec 04 11:24:35 CET 2019
System.out.println(fmt.format(d)); // 04-12-2019
}
}
If you'd rather store only date information, you could use the java.time package and make use of LocalDate.
LocalDate stores only date information, since it does not represent an instant, rather a triple of year, month and date.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class ParsingLocalDate {
public static void main(String[] args) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate d = LocalDate.parse("04-12-2019", fmt);
System.out.println(d); // 2019-12-04
}
}
If you do not need to use time of day or time zone, you can parse it by LocalDate.
String str = "01-01-2000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate date = LocalDate.parse(str, formatter);
Note that for day and time people most of the time would want a ZonedDateTime rather than a LocalDateTime. The name is counter-intuitive; the Local in both LocalDate and LocalDateTime means any locality in general rather than a specific time zone.
In most programming languages, date/time types are simply containers for the amount of time which has passed from a given point in time. They don’t have a format.
In the case of Java (AFAIR), time is measured in milliseconds since the Unix Epoch.
Since it's 2019, there is no excuse not to making use of the java.time APIs (or the ThreeTen backport) and you should avoid using the, now effectively deprecated, older APIs
Parse String to LocalDate
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate localDate = LocalDate.parse("08-03-1972", inputFormatter);
Format LocalDate to desired format
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd EEE MMM yyyy");
String value = localDate.format(outputFormatter);
System.out.println(value);
which outputs
08 Wed. Mar. 1972

Java SimpleDateFormat decrementing date by one day

I am trying to reformat a date string using sdf. SDF is decrementing the date by a day. Pointers would be helpful.
java version "1.8.0_31"
Input: ChangeDateStringFormat("10-Mar-2015");
Code:
public static String ChangeDateStringFormat (String Input) throws InterruptedException
{
System.out.print("Input Date inside ChangeDateStringFormat : " + Input );
SimpleDateFormat sdf = new SimpleDateFormat("MMM-dd-yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("MST"));
System.out.print(" || Output Date inside ChangeDateStringFormat : " + sdf.format(new Date(Input)) + "\n");
return sdf.format(new Date(Input));
}
Output Actual:
Input Date inside ChangeDateStringFormat : 10-Mar-2015 || Output Date inside ChangeDateStringFormat : Mar-09-2015
Output I was Expecting :
Input Date inside ChangeDateStringFormat : 10-Mar-2015 || Output Date inside ChangeDateStringFormat : Mar-10-2015
This is the problem:
new Date(Input)
You should not use that. Instead, construct a SimpleDateFormat to parse your input:
import java.text.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws ParseException {
System.out.println(convertDateFormat("10-Mar-2015"));
}
public static String convertDateFormat(String input) throws ParseException {
TimeZone zone = TimeZone.getTimeZone("MST");
SimpleDateFormat inputFormat = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
inputFormat.setTimeZone(zone);
SimpleDateFormat outputFormat = new SimpleDateFormat("MMM-dd-yyyy", Locale.US);
outputFormat.setTimeZone(zone);
Date date = inputFormat.parse(input);
return outputFormat.format(date);
}
}
However:
If you're just parsing a date, you'd be better of specifying UTC as the time zone; you don't want to end up with problems due to time zones that switch DST at midnight
If you're going to run this code on Java 8 and nothing lower, I'd strongly recommend using java.time instead of Date, Calendar etc.
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*.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(changeDateStringFormat("10-Mar-2015"));
}
static String changeDateStringFormat(String input) {
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("d-MMM-u", Locale.ENGLISH);
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("MMM-dd-uuuu", Locale.ENGLISH);
LocalDate date = LocalDate.parse(input, dtfInput);
return date.format(dtfOutput);
}
}
Output:
Mar-10-2015
ONLINE DEMO
Note: Never use SimpleDateFormat or DateTimeFormatter without a Locale.
Learn more about the modern Date-Time API from Trail: Date Time.
Side Note: Always follow Java naming conventions e.g. the name of your function should be changeDateStringFormat instead of ChangeDateStringFormat and the parameter Input should be named as input.
* 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.

How to properly format the date?

The function shown below returns the date, e.g. "Sat Sep 8 00:00 PDT 2010". But I expected to get the date in the following format "yyyy-MM-dd HH:mm". What's wrong in this code?
String date = "2010-08-25";
String time = "00:00";
Also in one laptop the output for,e.g. 23:45 is 11:45. How can I define exactly the 24 format?
private static Date date(final String date,final String time) {
final Calendar calendar = Calendar.getInstance();
String[] ymd = date.split("-");
int year = Integer.parseInt(ymd[0]);
int month = Integer.parseInt(ymd[1]);
int day = Integer.parseInt(ymd[2]);
String[] hm = time.split(":");
int hour = Integer.parseInt(hm[0]);
int minute = Integer.parseInt(hm[1]);
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month);
calendar.set(Calendar.DAY_OF_MONTH,day);
calendar.set(Calendar.HOUR,hour);
calendar.set(Calendar.MINUTE,minute);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date d = calendar.getTime();
String dateString= dateFormat.format(d);
Date result = null;
try {
result = (Date)dateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
What's wrong in this code?
You seem to be expecting the returned Date object to know about the format you've parsed it from - it doesn't. It's just an instant in time. When you want a date in a particular format, you use SimpleDateFormat.format, it's as simple as that. (Well, or you use a better library such as Joda Time.)
Think of the Date value as being like an int - an int is just a number; you don't have "an int in hex" or "an int in decimal"... you make that decision when you want to format it. The same is true with Date.
(Likewise a Date isn't associated with a specific calendar, time zone or locale. It's just an instant in time.)
How did you print out the return result? If you simply use System.out.println(date("2010-08-25", "00:00") then you might get Sat Sep 8 00:00 PDT 2010 depending on your current date time format setting in your running machine. But well what you can do is:
Date d = date("2010-08-25", "00:00");
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d));
Just curious why do you bother with this whole process as you can simple get the result by concatenate your initial date and time string.
just use SimpleDateFormat class
See
date formatting java simpledateformat
The standard library does not support a formatted Date-Time object.
The function shown below returns the date, e.g. "Sat Sep 8 00:00 PDT
2010". But I expected to get the date in the following format
"yyyy-MM-dd HH:mm".
The standard Date-Time classes do not have any attribute to hold the formatting information. Even if some library or custom class promises to do so, it is breaking the Single Responsibility Principle. A Date-Time object is supposed to store the information about Date, Time, Timezone etc., not about the formatting. The only way to represent a Date-Time object in the desired format is by formatting it into a String using a Date-Time parsing/formatting type:
For the modern Date-Time API: java.time.format.DateTimeFormatter
For the legacy Date-Time API: java.text.SimpleDateFormat
About java.util.Date:
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 (or UTC). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
Date date = new Date(); // In your case, it will be Date date = date("2010-08-25", "00:00");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
// sdf.setTimeZone(TimeZone.getTimeZone("America/New_York")); // For a timezone-specific value
String strDate = sdf.format(date);
System.out.println(strDate);
Your function, Date date(String, String) is error-prone.
You can simply combine the date and time string with a separator and then use SimpleDateFormat to parse the combined string e.g. you can combine them with a whitespace character as the separator to use the same SimpleDateFormat shown above.
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
Note that using a separator is not a mandatory requirement e.g. you can do it as sdf.parse(date + time) but for this, you need to change the format of sdf to yyyy-MM-ddHH:mm which, although correct, may look confusing.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
public static void main(String[] args) throws ParseException {
Date date = date("2010-08-25", "00:00");
String strDate = sdf.format(date);
System.out.println(strDate);
}
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
}
Output:
2010-08-25 00:00
ONLINE DEMO
Switch to java.time API.
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*.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = localDateTime("2010-08-25", "00:00");
// Default format i.e. the value of ldt.toString()
System.out.println(ldt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm", Locale.ENGLISH);
String strDate = dtf.format(ldt);
System.out.println(strDate);
}
private static LocalDateTime localDateTime(final String date, final String time) {
return LocalDateTime.of(LocalDate.parse(date), LocalTime.parse(time));
}
}
Output:
2010-08-25T00:00
2010-08-25 00:00
ONLINE DEMO
You must have noticed that I have not used DateTimeFormatter for parsing the String date and String time. It is because your date and time strings conform to the ISO 8601 standards. The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.
Learn more about 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.
I'm surprise you are getting different date outputs on the different computers. In theory, SimpleDateFormat pattern "H" is supposed to output the date in a 24h format. Do you get 11:45pm or 11:45am?
Although it should not affect the result, SimpleDateFormat and Calendar are Locale dependent, so you can try to specify the exact locale that you want to use (Locale.US) and see if that makes any difference.
As a final suggestion, if you want, you can also try to use the Joda-Time library (DateTime) to do the date manipulation instead. It makes it significantly easier working with date objects.
DateTime date = new DateTime( 1991, 10, 13, 23, 39, 0);
String dateString = new SimpleDateFormat("yyyy-MM-dd HH:mm").format( date.toDate());
DateTime newDate = DateTime.parse( dateString, DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"));

Categories