Java String to Date Conversion in different format - java

So i have String trDate="20120106"; and want to get Date trDate=2012-01-06 and am trying to use SimpleDateFormat for changing the pattern but first i get to parse the string and then generate date and then try to call format which gives me back string but i need date, any suggestions, here is the code i have:
String trDate="20120106";
Date tradeDate = new SimpleDateFormat("yyyymmdd", Locale.ENGLISH).parse(trDate);
String krwtrDate = new SimpleDateFormat("yyyy-mm-dd", Locale.ENGLISH).format(tradeDate);
Date krwTradeDate = new SimpleDateFormat("yyyy-mm-dd", Locale.ENGLISH).parse(krwtrDate);
Here is similar question but it does not answer my question
I need converted string in Date format only because i need to pass it to another function that expects Date object only.
Would really appreciate if someone can give example of how to get date in yyyy-mm-dd format from string which is in yyyymmdd format?

--- Answer updated due to commentary ---
Ok, so the API you are using demands a String, which represents a Date in the format of 2012-04-20
You then need to parse the incorrectly formatted Date and then format it again in the needed format.
String trDate="20120106";
Date tradeDate = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH).parse(trDate);
String krwtrDate = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).format(tradeDate);
Also note that I changed your "month" designator, as you have made a very common mistake of using m for month. Due to the "hours:minutes:seconds" date formats have two common "names" that both start with m, minutes and months. Uppercase M is therefore used for months, while lowercase m is used for minutes. I'll bet that this is the real reason you're encountering problems.
--- Original post follows ---
If your APIneeds a java.util.Date, then you don't need to do as much as you have. You actually have the java.util.Date with just the two lines
String trDate="20120106";
Date tradeDate = new SimpleDateFormat("yyyymmdd", Locale.ENGLISH).parse(trDate);
But this solution might not make sense without a quick review of what java.util.Dates are. Dates are things, but how they are presented is divorced from what they are.
At any moment in time, there is one Date instance that describes that moment in time. How that Date instance should be presented is not in agreement, it depends heavily on what language the viewer speaks, which country they are in, what rules the country has imposed (daylight savings time), and what their cultural background has done before.
As such, a Date has no single associated presentation. That's why every "get the X" method on Date is deprecated (where X is day, month, hour, year, etc.), with the exception of grabbing the milliseconds from the 0 date (known as the epoch).
So, for every Date that is to be properly presented, you need to convert it to a String using rules that are specific to the language, country, time zone, and cultural precedent. The object that understands these rules and applies them is the DateFormat.
Which means, once you get the Date you don't need to reformat it and re-parse it to get the "right" Date as the two dates should be the same (for the same locale).

Do I understand it well?
You have a method which only accepts Date as parameter, and internally that method converts the Date to a string in the wrong format using toString()?
Best is to modify that method and exchange the use of toString() with SimpleDateFormat.format().
If you can't modify that method, than you can "cheat" with OO, i. e. replace the toString method with your own implementation, for example like this:
public class MyDate {
private static final FMT = SimpleDateFormat("yyyy-mm-dd", Locale.ENGLISH);
MyDate(long time) {
super(time);
}
String toString() {
return FMT.format(this);
}
}
and you call your method with
xxx = myMethod(new MyDate(new SimpleDateFormat("yyyymmdd", Locale.ENGLISH).parse(trDate).getTime()));
But if that method does not use toString internally but SimpleDateFormat with the wrong format, then my proposition does not work.

can you give me an example of how to get date in yyyy-mm-dd format from string which is in yyyymmdd format
A Date objects does not have a format associated with it. Internally it typically just stores a long value.
If some other methods is responsible for printing the date, then you unfortunately have no control over how the resulting output is formatted.

If the String date always comes in the format you have mentioned than you can use the subString method to extract the year, month and day.
String trDate="20120106";
Using the subString method for String extract the Year, month and day
String year = "2012";
String month = "01";
String day = "06";
And parse these to integer. Assuming you will do the parsing of string to integer
int intYear = 2012;
int intMonth = 01;
int intDay = 06;
Calendar calendar= new GregorianCalendar(intYear, intMonth - 1, intDay);
Date date = new Date(calendar);

Related

Converting string date to string in yyyy-MM-dd'T'HH:mm:ss.SSSSSS format in java 7

I have the following date
2017-08-23-11.19.02.234850
it has the following date format
yyyy-MM-dd-HH.mm.ss.SSSSSS
What I want to do is to convert the date to format yyyy-MM-dd'T'HH:mm:ss.SSSSSS
I have the following code
public static void main(String[] args) {
String strDate = "2017-08-23-11.19.02.234850";
String dateFmt = "yyyy-MM-dd-HH.mm.ss.SSSSSS";
System.out.println("converted Date: " + convertDate(strDate, dateFmt));
}
public static String convertDate(String strDate, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
sdf.setLenient(true);
try {
Date dateIn = sdf.parse(strDate);
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS").format(dateIn);
}catch(ParseException e) {
e.printStackTrace();
}
return "";
}
the result is
converted Date: 2017-08-23T11:22:56.000850
input date 2017-08-23-11.19.02.234850
converted date 2017-08-23T11:22:56.000850
doesn't look the same, it seems java is rounding the milliseconds besides if I turn lenient off for date validation
sdf.setLenient(false);
I get the following
java.text.ParseException: Unparseable date: "2017-08-23-11.19.02.234850"
at java.text.DateFormat.parse(Unknown Source)
at mx.santander.canonical.datamodel.enums.Main.convertDate(Main.java:74)
at mx.santander.canonical.datamodel.enums.Main.main(Main.java:66)
converted Date:
How to build a function which validates and converts date strings like this in a proper way?
EDIT:
I added a new function to obtain results
/**
* Gets the ISO 8601 date str from string.
*
* #param strDate the str date
* #return the ISO 8601 date str from string
*/
private String getISO8601DateStrFromString (String strDate) {
String responseISO8601Date = "";
if(strDate == null || "".equals(strDate.trim())) {
return responseISO8601Date;
}
try {
String strDtWithoutNanoSec = strDate.substring(0, strDate.lastIndexOf("."));
String strDtNanoSec = strDate.substring(strDate.lastIndexOf(".") + 1, strDate.length());
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss");
formatter.setLenient(false);
Date date = formatter.parse(strDtWithoutNanoSec);
Timestamp t = new Timestamp(date.getTime());
t.setNanos(Integer.parseInt(strDtNanoSec));
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'");
NumberFormat nf = new DecimalFormat("000000");
responseISO8601Date = df.format(t.getTime()) + nf.format(t.getNanos());
} catch (ParseException | StringIndexOutOfBoundsException | NumberFormatException e) {
String errorMsg = String.format("The date provided for conversion to ISO 8601 format [%s] is not correct", strDate);
System.out.println(errorMsg);
}
return responseISO8601Date;
}
What I get:
Uptadet date 2017-12-20T11:19:02.234850
As others have already mentioned, your requirement does not fit the use of Date and SimpleDateFormat since these only support milliseconds, that is, three decimals on the seconds, where you have six decimals (microseconds). So we need to find some other way. This is basically a good idea anyway, since Date and SimpleDateFormat are long outdated, and today we have better tools for the job.
I have got two suggestions for you.
java.time
Even in Java 7 I think that it’s a good idea to use the modern Java date and time API that came out with Java 8, AKA JSR-310. Can you do that? Certainly; use the backport for Java 6 and 7, ThreeTen Backport. The modern API supports anything from 0 through 9 decimals on the seconds, and the code is straightforward when you know how:
private static DateTimeFormatter inputParser
= DateTimeFormatter.ofPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS");
private static DateTimeFormatter outputFormatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
public static String convertDate(String strDate) {
return LocalDateTime.parse(strDate, inputParser)
.format(outputFormatter);
}
I am using your own two format pattern strings. convertDate("2017-08-23-11.19.02.234850") returns 2017-08-23T11:19:02.234850.
There is a simplification possible: Since the format you want to obtain, conforms with ISO 8601, you don’t need an explicit formatter for it. The modern classes understand and produce ISO 8601 formats natively, so you may use:
return LocalDateTime.parse(strDate, inputParser).toString();
However, if the decimals on the seconds happened to end in 000, this will not print the last three zeroes. So if six decimals are required even in this case, use the formatter.
Regular expression
If you don’t want to rely on an external library, even temporarily until once you upgrade to Java 8 (or 9), your job can be done with a regular expression:
return strDate
.replaceFirst("^(\\d{4}-\\d{2}-\\d{2})-(\\d{2})\\.(\\d{2})\\.(\\d{2}\\.\\d{6})$",
"$1T$2:$3:$4");
It’s less elegant and harder to read, and it doesn’t offer the level of input validation you get from using a proper date and time API. Other than that, it’s a way through.
java.sql.Timestamp?
As others have said, java.sql.Timestamp offers nanosecond precision and thus will hold your date-time. Parsing your string into a Timestamp isn’t straightforward, though, so I don’t think it’s worth the trouble. Usagi Miyanmoto correctly identifies Timestamp.valueOf() as the method to use, but before you could do that, you would have change the format, so you would end up changing the format twice instead of just once. Or maybe three times since Timestamp also doesn’t produce your desired ISO 8601 format readily. Additionally you would need to decide a time zone for the timestamp, but I assume you could do that without any trouble.
If you needed to keep the the date-time around, a Timestamp object might be worth considering, but again, it’s a long outdated class. In any case, for reformatting alone, I certainly would not use it.
What happened in your code?
SimpleDateFormat understood 234850 as milliseconds, that is, 234 seconds 850 milliseconds. So it added 234 seconds to your time, 11:19:02. And then printed the remaining 850 milliseconds in 6 decimal places as you had requested.
Date has precision only till milli seconds. Please use timestamp instead - it has precision till nano seconds, which is expected in your case.
Please refer this answer - precision till nano seconds
TimeStamp API
A thin wrapper around java.util.Date that allows the JDBC API to
identify this as an SQL TIMESTAMP value. It adds the ability to hold
the SQL TIMESTAMP fractional seconds value, by allowing the
specification of fractional seconds to a precision of nanoseconds. A
Timestamp also provides formatting and parsing operations to support
the JDBC escape syntax for timestamp values.
SimpleDateFormat of Java does not support microsecond in pattern.
java.util.Date format SSSSSS: if not microseconds what are the last 3 digits?
You have several choices:
Manually handle the parsing and formatting of the microseconds
Switch to use Java 8 as Time API supports fraction of second in pattern (https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)
If you need to use Java 7, consider using JODA Time for your date-time logics. JODA support fraction of second in its DateTimeFormat (http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html)
That result you got is expected. In your format string S were used. S is for milliseconds, hat is thousandths of seconds, and in this case the number of S's does not matter for parsing.
Your input string ends with 11.19.02.234850, the last part is interpreted as an integer value, and added to the date and time as milliseconds. That is as 234.850 seconds. Now, if you add 234 secs to 11:19:02, it becomes 11:22:56, just as you got in the result...
You cannot make a SimpleDateFormat mask that can parse microseconds into a Date, and Date cannot hold microseconds value either.
You have to choose, whether you want to use Date, or really need the finer then milliseconds resolution?
If you stick with Date, you should truncate the string of the last 3 characters.
Or you could use java.sql.Timestamp, which has a valueOf() method, hat uses SQL timestamp format.
Unfortunately it is not exactly he same as yours (being yyyy-[m]m-[d]d hh:mm:ss[.f...])...
Another way could be to split the string by separators (like [-.]), parse them to integers, and use hese integers with the Timestamp() constructor...

Format a String to a Fixed Date at UTC+0 in Java

I want to convert a String date - 2017-01-01 to java.util.Date with UTC+0. So, what I am expecting is.
"2017-01-01" -> 2017-01-01T00:00:00 UTC+0100
Here is how I am trying to do, but as my default Timezone is UTC+1, I am getting that 1 hour added to the Date.
Date d = Date.from(Instant.parse("2017-01-01T00:00:00Z"));
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss 'UTC'ZZZZZ");
String output = sf.format(d);
System.out.println(output);
Here is the output:
2017-01-01T01:00:00 UTC+0100
Can somebody help?
Your code is mixing oldfashioned and modern classes. Date and SimpleDateFormat are long outdated. Instant is modern (from 2014). I recommend you stick to the modern ones unless you are working with an old API that requires and/or gives you an instance of an oldfashioned class. So the answer is
String output = LocalDate.parse("2017-01-01")
.atStartOfDay(ZoneOffset.ofHours(1))
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss 'UTC'XX"));
The result is the one you asked for
2017-01-01T00:00:00 UTC+0100
The code is not really shorter than yours, but once you get used to the fluent style you will find it clearer and more natural. The room for confusion and errors is considerably reduced.
If you want the start of day in whatever time zone the user is in, just fill in ZoneId.systemDefault() instead of ZoneOffset.ofHours(1).
LocalDate parses your date string — "2017-01-01" — without an explicit format. The string conforms to ISO 8601, and the modern classes use this standard as their default for parsing and also for their toString().
You can set the timezone first and then format it.
sf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sf.parse(d);
And now format as per your requirements:
String output = sf.format(date);
System.out.println(output);
I wonder please try this also:
Date date = new Date();
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
date = cal.getTime();

Get date and time input from text

So, I was searching for this for some time but I didn't find an answer. Thats why I'm asking here. My problem goes like this:
With Swing I made an app that will get text from JTextArea and then save it inside a .txt document. Also it will save 2 more files (as .txt documents too). In one, there would be date (i.e 2016.03.05) and in other would be time (i.e 09:50 AM). What I need is compare the date and time to system date and time and check if they match. I only need a way on how to exactly do this, since they are stored as string, what would be good way to compare them to system date and time.
I think that is should be like this:
if(date in date file is equal to system date) {/do stuff}
I wouldn't rly be looking for spoonfeeding, but I need to have a good and efficient way of doing this.
Let's pretend the op has read the date/time strings from a file.
String date = "2016.03.05";
String time = "09:50 AM";
We want to compare that to the "system time" so how about.
LocalDateTime now = LocalDateTime.now();
Now we have a date and time and we want to compare it to the values in the file. One way, is to create a LocalDate object from the date string.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd");
LocalDate localDate = LocalDate.parse(date, dateFormatter);
if(now.toLocaleDate().equals(localDate)){
//date is equal so now what?
}
We can do the same for the local time.
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:m a");
LocalTime localTime = LocalTime.parse(time, timeFormatter);
if(now.toLocalTime().equals(localTime)){
//do stuff if the time is equal (which it will rarely be)
}
If you are using java 8 then there is a very good article on how to parse a String to Date. Once you parse a String into class LocalDateTime then you can then run:
if(LocalDateTime.now().equals(yourTime)) {
//your code
}
to see if they match.
Please read about java.time package here https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
and here is an article about String parsing to date: https://www.linkedin.com/pulse/java-8-javatime-package-parsing-any-string-date-michael-gantman?trk=pulse_spock-articles

How to change date format from setting it reference in date data type

I am getting date in an date object
Date s = ((java.util.Date) ((Object[]) object)[++i]);
i need to set this format 20130509 06:00
so for this I have choosen ..
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm");
String s1 = sdf.format(s);
now again my task is to put back in date object that string s1, please advise how to achieve this
Date doesn't have a textual format - or even a time zone or calendar. It's just a number of milliseconds since the unix epoch. There's nothing to set within Date.
You need to differentiate between your fundamental data, and a textual representation of that data - in the same way as the int value 16 is the same as 0x10. I can't think of any time where I've found it appropriate to carry a textual representation of a date around with the date itself. In various places in your program you may well find that you need different representations for the same date - but it's usually the same representation for all dates at that specific part of the program.
As an aside, you should consider using Joda Time instead of java.util.Date - it provides you with a much richer set of types to consider, so you can express what your program is actually dealing with (just a date, just a time, a date/time in a particular time zone etc).
Ideally, you shouldn't try to translate to String format and back again. You should persist the original value and just use the String format for display purpose only.
Otherwise, you can use SimpleDateFormat.parse method.
I recommend using Joda time... how given what you've got you can just do
sdf.parse
#Test
public void testDateStringConversion() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm");
String s1 = sdf.format(date);
Date date2 = sdf.parse(s1); // seconds won't match
String s2 = sdf.format(date2);
assertEquals(s1, s2);
}

I want to get a formatted Date in Java

I want to get a new Date object with a SimpleDateFormat applied to it. I would like to do something like:
SimpleDateFormat myFormat = new SimpleDateFormat("dd MMM yyyy kkmm");
Date today = new Date();
today = myFormat.format(today);
I can't do this, because today is a Date, and format returns a String. I also have tried:
Date today;
SimpleDateFormat myFormat = new SimpleDateFormat("dd MMM yyyy kkmm");
try{
today = myFormat.parse((new Date()).toString());
}catch(Exception e){
}
This isn't a good solution, because when I try to use today elsewhere Java complains that today may not have been instantiated. What is a good way to change the format of a Date object (while still keeping it a Date object, and not turning it to a string)?
You are looking at Format and Date wrongly.
Date does not contain format. Date is just a class containing date info like date, month, hours, sec etc.
SimpleDateFormat is the one which tells you the string representation of Date. But there is no date associated with it.
So the idea is when you have to display date or have to store date in some string representation, you will use SimpleDateFormat and pass it the date you want string representation for.
One benefit of doing this way is that, I can use same Date object and can show two different string representations (using two different instances of SimpleDateFormat). And also viceversa, having defined one SimpleDateFormat instance, I can format multiple dates.
Edit:
Now if you want to strip some info from the date. Use
Calendar rightNow = Calendar.getInstance();
Calendar cal = new GregorianCalendar(
rightNow.get(YEAR),
rightNow.get(MONTH),
rightNow.get(DAY_OF_MONTH));
Date now = cal.getTime();
There are other good soln like JodaTime
Ref:
GregorianCalendar
Calendar
Joda Time
I think what you are trying to achieve does not make sense.
A Date object represents time. You can not format it. But, you can get it's string representation in certain format. Like with myFormat.format(today).
I think you're misunderstanding something here about what the Date object is. Date simply holds the information about a point in time - it doesn't have a format at all. When it comes to the String representation of a Date, this is where formatting comes into play. Only worry about the formatting when you are:
Parsing a String representation into a Date object.
Converting a Date back into String representation to display it in a certain way.
Your question doesn't make sense. Formatting a date by definition means converting it to a string using a specific format. The Date object can stay as a Date object. It is only at the point where you wish to convert it to a String that you need to do any formatting.
you cannot associate a format to a Date object instead you can only apply the formats while displaying or other activities,,
Do all processing in the Date object itself and while displaying alone change to the required format,,

Categories