I'm querying database and getting date in this format "01-SEP-22"
I want to convert this date into this format "yyyy-MM-dd" in Java. Is there any way I can do this.
java.time
I recommend that you use java.time, the modern Java date and time API, for your date work.
In order to parse the month abbreviation in all upper case (like SEP) we need to instruct it to apply case insensitive parsing.
We can use DateTimeFormatterBuilder to build a DateTimeFormatter with such an instruction.
private static final DateTimeFormatter oracleFormatter
= new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd-MMM-uu")
.toFormatter(Locale.ROOT);
The rest goes smoothly:
String stringFromOracle = "01-SEP-22";
LocalDate date = LocalDate.parse(stringFromOracle, oracleFormatter);
String formattedString = date.toString();
System.out.println(formattedString);
Output is:
2022-09-01
For generating the string I am exploiting the fact that LocalDate.toString() gives the format that you asked for, so I am not using any formatter explicitly. The format is known as ISO 8601 and as this name says, is an international standard.
Suggestions for improvement
Don’t retrieve your date as a String from Oracle. Retrieve a LocalDate directly and save the parsing.
Don’t convert a date from one string format to another. In your program keep the date as a LocalDate. If you need to take string input (which is not the case here), parse the string into a LocalDate immediately. Only when you need to give string output (to the user or in data exchange with another system, for example), format the LocalDate into a string in the required format.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Question: Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2
You can simply use DateTimeFormatter:
public String convertDate(String dateStr) throws ParseException {
String[] split = dateStr.split("-");
split[1] = split[1].substring(0, 1).toUpperCase() + split[1].substring(1).toLowerCase();
dateStr = String.join("-", split);
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MMM-yy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(dateStr, dateFormatter);
return date.toString();
}
#Test
public void test_convertDate() throws ParseException {
assertEquals("2022-09-01", convertDate("01-SEP-22"));
}
Related
I'm getting this date from bing search and have difficulty to parse it to date, I need
the time as well.
""2021-09-02T13:16:00.0000000Z""
I'm doing this:
public static Date parseDate(String publishedDate) {
String dateStr = publishedDate.replaceFirst("T", "");
SimpleDateFormat formatter = null;
if (publishedDate.length() > 10) {
formatter = new SimpleDateFormat("yyyy-MM-ddhh:mm:ss");
} else {
formatter = new SimpleDateFormat("yyyy-MM-dd");
}
Date date = null;
try {
date = formatter.parse(publishedDate);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
getting the following error:
java.text.ParseException: Unparseable date: ""2021-09-02T13:16:00.0000000Z""
at java.base/java.text.DateFormat.parse(DateFormat.java:396)
Parse the quotes too; use java.time.Instant
Like many others I recommend that you use java.time, the modern Java date and time API, for your date and time work.
Your string contains double quotes first and last. You can deal with them in two ways:
If there’s a way that you can get your string from Bing search without the quotes, do that. Then Instant.parse() will parse your string, and you’re done.
Otherwise java.time can parse the quotes too.
For parsing the quotes use the following formatter:
private static final DateTimeFormatter BING_INSTANT_PARSER
= new DateTimeFormatterBuilder().appendLiteral('"')
.append(DateTimeFormatter.ISO_INSTANT)
.appendLiteral('"')
.toFormatter();
Then parse like this:
String stringFromBing = "\"2021-09-02T13:16:00.0000000Z\"";
Instant instant = BING_INSTANT_PARSER.parse(stringFromBing, Instant::from);
System.out.println("String to parse: " + stringFromBing);
System.out.println("Result: " + instant);
Output:
String to parse: "2021-09-02T13:16:00.0000000Z"
Result: 2021-09-02T13:16:00Z
Which java.time class to use?
Assuming that your string always comes with the Z at the end, denoting UTC, Instant is the correct class to use. OffsetDateTime and ZonedDateTime will work too, but I consider them overkill. You don’t want to use LocalDateTime since you would then throw away the essential information that the string is in UTC.
Link
Oracle tutorial: Date Time explaining how to use java.time.
What you are dealing with is called Time Stamp,
there are Duration and INSTANT classes to deal with it.
This page explain it all
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
As #Basil Bourque suggested, we dont need DateTimeFormatter because Instant.parse() by default uses UTC. Also, we can use OffsetDateTime instead of ZonedDateTime (more detailed),
String date = "2021-09-02T13:16:00.0000000Z";
Instant timeStamp = Instant.parse(date);
// To get Time or Date," with Instant you must provide time-zone too"
ZonedDateTime dateTimeZone = ZonedDateTime.ofInstant(timeStamp, ZoneOffset.UTC);
System.out.println(dateTimeZone);
System.out.println(dateTimeZone.toLocalDate());// can also be tolocalTime
I'm having trouble to figure out what is this date format: 2019-02-28T12:17:46.279+0000. I have tried different date formats to get this result but nothing worked. Closest pattern was: yyyy-MM-dd'T'HH:mm:ss.SSSZ But with this pattern output was like this: 2019-02-28T12:17:46.279-0000 (- is after seconds instead of +)
I get this exception:
Caused by: java.lang.IllegalArgumentException: 2019-02-28T12:17:46.279+0000
at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.skip(XMLGregorianCalendarImpl.java:2932)
at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(XMLGregorianCalendarImpl.java:2898)
at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl.<init>(XMLGregorianCalendarImpl.java:478)
at org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl.newXMLGregorianCalendar(DatatypeFactoryImpl.java:230)
at __redirected.__DatatypeFactory.newXMLGregorianCalendar(__DatatypeFactory.java:132)
at javax.xml.bind.DatatypeConverterImpl.parseDate(DatatypeConverterImpl.java:519)
at javax.xml.bind.DatatypeConverter.parseDate(DatatypeConverter.java:431)
at eu.europa.ec.my.custom.package.model.mapper.XsdDateTimeConverter.unmarshal(XsdDateTimeConverter.java:23)
My XsdDateTimeConverter class looks like this:
public class XsdDateTimeConverter {
public static Date unmarshal(String dateTime) {
return DatatypeConverter.parseDate(dateTime).getTime();
}
public static String marshalDate(Date date) {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return DatatypeConverter.printDate(calendar);
}
public static String marshalDateTime(Date dateTime) {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(dateTime);
return DatatypeConverter.printDateTime(calendar);
}
}
And parsed date in my postgres db looks like this:
move_timestamp timestamp(6) with time zone
2019-02-28 12:17:46.279+00
In my rest method I use ObjectMapper like this.
MyCustomResponseDto responseDto = customService.getCustomResponseDto(query);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
String strValue = mapper.writeValueAsString(responseDto);
return Response.ok(strValue).build();
I guess what I really wanted is what is the right pattern for this date. I can go in this page: http://www.sdfonlinetester.info/ and enter my pattern (e.g. yyyy-MM-dd'T'HH:mm:ss.SSSZ) and it gives you an actual date output for that pattern. I need the other way around. I want to enter my date and it will give me the right pattern for it.
tl;dr
OffsetDateTime.parse(
"2019-02-28T12:17:46.279+0000" ,
DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" , Locale.ROOT )
)
java.time
You are using terrible Calendar class that was supplanted years ago by the java.time classes.
ISO 8601
Your input string is in standard ISO 8601 format, designed for human-readable machine-parseable textual representations of date-time values. That is a good thing.
The java.time classes use ISO 8601 formats by default when parsing/generating strings.
OffsetDateTime
You should be able to simply parse with OffsetDateTime.
OffsetDateTime.parse( "2019-02-28T12:17:46.279+0000" )
…but unfortunately the optional COLON character being omitted from the offset (+00:00) is a problem. The OffsetDateTime class has a minor bug where it refuses to parse without that character. The bug is discussed here and here.
The ISO 8601 standard permits the colon’s absence, but practically you should always include it. The OffsetDateTime class is not alone; I have seen other libraries that break when the colon or padding zeros are absent. I suggest asking the publisher of your data to use the full ISO 8601 format including the colon.
The workaround for the OffsetDateTime bug is to define a DateTimeFormatter explicitly.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" , Locale.ROOT ) ;
Then parse.
String input = "2019-02-28T12:17:46.279+0000" ;
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;
To generate text in full standard ISO 8601 format, simply call toString.
String output = odt.toString() ;
See this code run live at IdeOne.com.
output: 2019-02-28T12:17:46.279Z
The Z on the end means UTC, that is +0000 or +00:00. Pronounced “Zulu”. Very commonly used, more immediately readable than the numeric offset.
If you want same output format as your input, use the same DateTimeFormatter.
String output = odt.format( f ) ;
You may try below code
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ENGLISH);
String lastmod = format.format(new Date());
Save yourself a mountain of trouble and save the epochtime in millis. Only parse and render dates in UIs. Very very few cases of scheduling for humans require a computer to know hours, day, week, month, year... But saving an instant in time is just a 'long'.
I'm using JodaTime to get the date and time of creation of an account. The format being
2017-04-05T12:38:35.585
When I get this I store it in my database as a string so I've looked around for ways to format this from a string to LocalDate but haven't been succesful in anything I've found online. My next step is a horrible solution in my opinion to loop through the string until I find the T and remove everything after it. So I'm left with
2017-04-05.
But Ideally if possible have the date as
05/04/2017
Use the ISODateTimeFormat to get a LocalDateTime and from this get the LocalDate.
Be careful to use the right Locale
String input="2017-04-05T12:38:35.585";
LocalDateTime ldt = ISODateTimeFormat.localDateOptionalTimeParser()
.withLocale(Locale.ENGLISH)
.parseLocalDateTime(input);
System.out.println(ldt.toLocalDate());//prints 2017-04-05
I'm using joda-time 2.7.
LocalDateTime class has a constructor that takes a String and parses it. Then you just call toString() method with the pattern you want:
String input = "2017-04-05T12:38:35.585";
LocalDateTime d = new LocalDateTime(input);
System.out.println(d.toString("dd/MM/yyyy"));
Output:
05/04/2017
Note: you can also use ISODateTimeFormat to parse and a DateTimeFormatter instead of toString() to get the output:
LocalDateTime d = ISODateTimeFormat.localDateOptionalTimeParser().parseLocalDateTime(input);
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy");
System.out.println(fmt.print(d));
The output will be the same.
So I am trying to convert a string into an iso format for the date.
This is the string that I am trying to convert "2016-07-05 02:14:35.0"
I would like to have it in this format the iso 8601
"2016-07-05T02:14:35.0"
I have this so far
DateTimeFormatter format = DateTimeFormat.forPattern("YYYY-MM-DDTHH:mm:sszzz");
new LocalDate();
LocalDate newDate = LocalDate.parse(created,format);
created = newDate.toString();
But it is giving me this exception
ERROR: Illegal pattern component: T; nested exception is java.lang.IllegalArgumentException: Illegal pattern component: T
I followed the examples and I don't know what I am doing wrong here.
Any help would be appreciated.
Firstly, that value is a LocalDateTime, not a LocalDate. If you want to get a date out in the end, I'd convert it to a LocalDateTime first, then take the date part of that.
When performing date formatting and parsing, always read the documentation really carefully. It looks like you're using Joda Time (due to using forPattern; if you can move to Java 8 that would be beneficial). That means you should be reading the DateTimeFormat docs.
Current problems with your pattern:
You're using 'D' instead of 'd'; that means day-of-year
You've specified 'T' without quoting it, and it isn't in the pattern anyway
You've ignored the fraction-of-second part of your value
You've specified 'zz' when there's no time zone indicator in the value.
Here's a working example:
import org.joda.time.*;
import org.joda.time.format.*;
public class Test {
public static void main(String[] args) {
String text = "2016-07-05 02:14:35.0";
DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.S");
LocalDateTime localDateTime = LocalDateTime.parse(text, format);
System.out.println(localDateTime);
}
}
If you actually want to parse values with T in the middle, you'd use a pattern of "yyyy-MM-dd'T'HH:mm:ss.S" - note how then the T is quoted so it's treated literally instead of as a format specifier.
Note that this is just parsing. It's not "converting a string into ISO date format" - it's converting a string into a LocalDateTime. If you then want to format that value in an ISO format, you need to be using DateTimeFormatter.print, with an appropriate format. For example, you might want to convert to a format of yyyy-MM-dd'T'HH:mm:ss.S':
import org.joda.time.*;
import org.joda.time.format.*;
public class Test {
public static void main(String[] args) {
String text = "2016-07-05 02:14:35.0";
DateTimeFormatter parser = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.S");
LocalDateTime localDateTime = LocalDateTime.parse(text, parser);
DateTimeFormatter printer = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.S");
String formatted = printer.print(localDateTime);
System.out.println(formatted); // Output 2016-07-05T02:14:35.0
}
}
The code above will only handle a single digit fraction-of-second. You could parse using .SSS instead of .S, but you really need to work out what you want the output to be in different cases (e.g. for 100 milliseconds, do you want .1 or .100?).
You have some errors in your code:
The pattern should be 'yyyy-MM-dd HH:mm:ss.SSS'. Be aware of upper-
and lowercase.
Use LocalDateTime to get date and time. LocalDate only holds the date.
The corrected code:
String created = "2016-07-05 02:14:35.000";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime newDate = LocalDateTime.parse(created,format);
created = newDate.toString();
System.out.println(created);
Use the following format to convert
String format = "yyyy-mm-dd hh:mm:ss"
You are using the wrong format to convert. Using T is only to separate the date from time.
Use the format like this
String = "yyyy-MM-dd'T'HH:mm:ss"
I want to convert the timestamp 2011-03-10T11:54:30.207Z to 10/03/2011 11:54:30.207. How can I do this? I want to convert ISO8601 format to UTC and then that UTC should be location aware. Please help
String str_date="2011-03-10T11:54:30.207Z";
DateFormat formatter ;
Date date ;
formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");
date = (Date)formatter.parse(str_date);
System.out.println("output: " +date );
Exception :java.text.ParseException: Unparseable date: "2011-03-10T11:54:30.207Z"
Firstly, you need to be aware that UTC isn't a format, it's a time zone, effectively. So "converting from ISO8601 to UTC" doesn't really make sense as a concept.
However, here's a sample program using Joda Time which parses the text into a DateTime and then formats it. I've guessed at a format you may want to use - you haven't really provided enough information about what you're trying to do to say more than that. You may also want to consider time zones... do you want to display the local time at the specified instant? If so, you'll need to work out the user's time zone and convert appropriately.
import org.joda.time.*;
import org.joda.time.format.*;
public class Test {
public static void main(String[] args) {
String text = "2011-03-10T11:54:30.207Z";
DateTimeFormatter parser = ISODateTimeFormat.dateTime();
DateTime dt = parser.parseDateTime(text);
DateTimeFormatter formatter = DateTimeFormat.mediumDateTime();
System.out.println(formatter.print(dt));
}
}
Yes. you can use SimpleDateFormat like this.
SimpleDateFormat formatter, FORMATTER;
formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String oldDate = "2011-03-10T11:54:30.207Z";
Date date = formatter.parse(oldDate.substring(0, 24));
FORMATTER = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss.SSS");
System.out.println("OldDate-->"+oldDate);
System.out.println("NewDate-->"+FORMATTER.format(date));
Output
OldDate-->2011-03-10T11:54:30.207Z
NewDate-->10-Mar-2011 11:54:30.207
Enter the original date into a Date object and then print out the result with a DateFormat. You may have to split up the string into smaller pieces to create the initial Date object, if the automatic parse method does not accept your format.
Pseudocode:
Date inputDate = convertYourInputIntoADateInWhateverWayYouPrefer(inputString);
DateFormat outputFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss.SSS");
String outputString = outputFormat.format(inputDate);
You might want to have a look at joda time, which is a little easier to use than the java native date tools, and provides many common date patterns pre-built.
In response to comments, more detail:
To do this using Joda time, you need two DateTimeFormatters - one for your input format to parse your input and one for your output format to print your output. Your input format is an ISO standard format, so Joda time's ISODateTimeFormat class has a static method with a parser for it already: dateHourMinuteSecondMillis. Your output format isn't one they have a pre-built formatter for, so you'll have to make one yourself using DateTimeFormat. I think DateTimeFormat.forPattern("mm/dd/yyyy kk:mm:ss.SSS"); should do the trick. Once you have your two formatters, call the parseDateTime() method on the input format and the print method on the output format to get your result, as a string.
Putting it together should look something like this (warning, untested):
DateTimeFormatter input = ISODateTimeFormat.dateHourMinuteSecondMillis();
DateTimeFormatter output = DateTimeFormat.forPattern("mm/dd/yyyy kk:mm:ss.SSS");
String outputFormat = output.print( input.parseDate(inputFormat) );
Hope this Helps:
public String getSystemTimeInBelowFormat() {
String timestamp = new SimpleDateFormat("yyyy-mm-dd 'T' HH:MM:SS.mmm-HH:SS").format(new Date());
return timestamp;
}
Use DateFormat. (Sorry, but the brevity of the question does not warrant a longer or more detailed answer.)