I'm trying to convert date from API "2022-08-16T06:25:00.000" to HH:mm (6:25) but getting DateTimeParseException.
My code: ZonedDateTime.parse(it.time[0], DateTimeFormatter.ofPattern("HH:mm"))
"time": [
"2022-08-16T06:25:00.000",
"2022-08-16T07:40:00.000"
],
String dateTimeStr = "2022-08-16T06:25:00.000";
LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm");
String time = dateTime.format(fmt);
System.out.println(time);
or, if you want to use the time as an instance of LocalTime, you can get it by dateTime.toLocalTime()
You don't need to define any DateTimeFormatter in this situation.
use a LocalDateTime because the input String does not hold any information about the zone
don't use a DateTimeFormatter for parsing that only parses hour of day and minutes of hour, the String to be parsed just contains more information
Here's an example without any DateTimeFormatter explicitly defined (but it will use default ones for parsing, at least):
public static void main(String[] args) {
// example input
String fromApi = "2022-08-16T06:25:00.000";
// parse it to a LocalDateTime because there's no zone in the String
LocalDateTime localDateTime = LocalDateTime.parse(fromApi);
// extract the time-of-day part
LocalTime localTime = localDateTime.toLocalTime();
// and print its toString() implicitly
System.out.println(localTime);
}
Output: 06:25
The above code will produce output of the pattern HH:mm, which will have leading zeros at hours of day to always have a two-digit representation.
If you insist on single-digit hours of day, you will have to prepare a DateTimeFormatter, like in this alternative example:
public static void main(String[] args) {
// example input
String fromApi = "2022-08-16T06:25:00.000";
// parse it to a LocalDateTime because there's no zone in the String
LocalDateTime localDateTime = LocalDateTime.parse(fromApi);
// extract the time-of-day part
LocalTime localTime = localDateTime.toLocalTime();
// prepare a DateTimeFormatter that formats single-digit hours of day
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:mm");
// print the LocalTime formatted by that DateTimeFormatter
System.out.println(localTime.format(dtf));
}
Output this time: 6:25
The other answers use Java. Since you've added a [kotlin] tag, here is a Kotlin-based answer for the sake of completeness. In order to make it different to the Java answers, I'm using kotlinx.datetime, which is still at the experimental stage at version 0.4.0.
import kotlinx.datetime.LocalDateTime
fun main() {
println(LocalDateTime.parse("2022-08-16T06:25:00.000").time) // prints "06:25"
// If you want "6:25" you can format it yourself:
println(with(LocalDateTime.parse("2022-08-16T06:25:00.000")) {
"$hour:$minute"
})
}
How about different approach
String dateTimeStr = "2022-08-16T06:25:00.000";
Matcher m=Pattern.of("T(\\d{2}:\\d{2}):").matcher(dateTimeStr);
m.find();
System.out.println(m.group(1);; //should print 06:25
And yet another "alternative" answer. It relies on the fact that in an ISO-compliant date-time format, the time starts in the 11th position.
private static final int ISO_TIME_POS = 11;
....
String dateTimeStr = "2022-08-16T06:25:00.000";
String timeStr = dateTimeStr.substring(ISO_TIME_POS, ISO_TIME_POS + 5);
System.out.println(timeStr); // prints "06:25"
Related
I am trying to convert java String date into java.sql.Timestamp. I am able to convert this by using SimpleDateFormat with String date value as "2021-01-07 02:02:16.172", but when trying with the value as "2021-08-04T00:00:00.000" with seperator 'T', it gives me error. Below is the java code:
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest {
public static void main(String[] args) throws ParseException {
//String date = "2021-08-04T00:00:00.000Z";// How to convert this?
String date = "2021-01-07 02:02:16.172";// conversion successful
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
Date parsedDate = dateFormat.parse(date);
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
System.out.println(timestamp);
}
}
You could use the modern API for dates, times and related information (like offsets from UTC): java.time
Strings in different formats need to be handled differently:
your first example String is formatted in ISO standard, so it can be parsed without defining a custom format. The parsing implicitly uses a DateTimeFormatter.ISO_OFFSET_DATE_TIME, which will result in an OffsetDateTime
your seconds String lacks the 'T' between date and time as well as an offset, that means you can just directly parse it to a LocalDateTime
java.sql.Timestamp got methods for conversion to java.time classes, at least to/from an Instant and a LocalDateTime. Since an Instant is a well defined moment in time, you can derive it from an OffsetDateTime:
public static void main(String[] args) throws Exception {
// your two example datetimes
String isoDateTime = "2021-08-04T00:00:00.000Z";
String customDateTime = "2021-01-07 02:02:16.172";
// you will need a custom formatter for the second one
DateTimeFormatter customDtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
// parse the Strings to java.time objects
// ISO standard, no extra formatter needed for the first one
OffsetDateTime odt = OffsetDateTime.parse(isoDateTime);
// the second one requires the formatter defined above
LocalDateTime ldt = LocalDateTime.parse(customDateTime, customDtf);
// convert them into Timestamps
Timestamp tsOne = Timestamp.from(odt.toInstant());
Timestamp tsTwo = Timestamp.valueOf(ldt);
// and print them
System.out.println("First Timestamp: " + tsOne);
System.out.println("Second Timestamp: " + tsTwo);
}
The output of this is
First Timestamp: 2021-08-04 02:00:00.0
Second Timestamp: 2021-01-07 02:02:16.172
This would be the new style...
new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS");
would be the old style
I am looking to convert the date from default Date format to timestamp in Java.
I tried the following code, but it doesn't work:
String string = "2017-08-01T16:00:00-04:00";
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss-mm:ss");
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date);
java.time.format.DateTimeParseException: Text
'2017-08-01T16:00:00-04:00' could not be parsed at index 20
at
java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at
java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDate.parse(LocalDate.java:400)
Don't use a LocalDate for a String that
contains information about the time of day, wich would have required a LocalDateTime and
contains an offset, wich cannot be considered by a LocalDateTime.
Instead, use an OffsetDateTime:
public static void main(String[] args) {
String string = "2017-08-01T16:00:00-04:00";
OffsetDateTime odt = OffsetDateTime.parse(string);
System.out.println(odt.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
}
Output:
2017-08-01T16:00:00-04:00
In addition, your pattern in DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss-mm:ss"); has serious flaws, like duplicate items.
You can of course print the result using a pattern different from the input (which complies with the ISO 8601 standard):
public static void main(String[] args) {
String string = "2017-08-01T16:00:00-04:00";
OffsetDateTime odt = OffsetDateTime.parse(string);
System.out.println(odt.format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss Z")));
}
Output this time:
01.08.2017 16:00:00 -0400
I need to parse a date string which has the following format:
yyyy-MM-dd TTTTT. All pattern letters are the standard DateTimeFormatter letters, except for the TTTTT part, which is a seconds-of-day field.
As there is no pattern defined for such a field, I needed to come up with something else. My first thought was to try and parse the field as milli-of-day (A), but by using 5 A's my field is treated as the least significant characters which is... yeah, not what I want.
Is there any out-of-the box solution I could use or do I have to resort to some custom made solution (like ignoring the TTTTT field, parsing it manually and using LocalDateTime.plusSeconds() on the resulting date)?
In other words, how can I make the following test case pass?
public class DateTimeParserTest {
private static final String PATTERN = "yyyy-MM-dd TTTTT";
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern(PATTERN);
#Test
public void testParseSecondsOfDay() throws Exception {
String input = "2016-01-01 86399";
LocalDateTime localDateTime = LocalDateTime.parse(input, FORMATTER);
assertEquals("2016-01-01T23:59:59", localDateTime.toString());
}
}
Based on your correction (leaving out the potentially ambivalent part "HH:mm") the Java-8-solution would look like:
private static final DateTimeFormatter FORMATTER =
new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd ")
.appendValue(ChronoField.SECOND_OF_DAY, 5)
.toFormatter();
well it may not be what what you are looking, but i hope it helps
private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; //MODIFICATION HERE
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern(PATTERN);
#Test
public void testParseSecondsOfDay() throws Exception {
String input = "2016-01-01 00:00:86399";
int lastIndexOf = input.lastIndexOf(':');
CharSequence parsable = input.subSequence(0,lastIndexOf)+":00";
CharSequence TTTTPart = input.subSequence(lastIndexOf+1, input.length());
LocalDateTime localDateTime = LocalDateTime.parse(parsable, FORMATTER);
Calendar calendar = Calendar.getInstance(); // gets a calendar using the default time zone and locale.
calendar.set(
localDateTime.getYear(),
localDateTime.getMonth().ordinal(),
localDateTime.getDayOfMonth(),
localDateTime.getHour(),
localDateTime.getMinute(),
0);
calendar.add(Calendar.SECOND, Integer.parseInt(TTTTPart.toString()));
StringBuilder toParse = new StringBuilder();
toParse.append(calendar.get(Calendar.YEAR) /* It gives 2016 but you what 2016, why */-1);
toParse.append("-").append(calendar.get(Calendar.MONTH) + 1 < 10 ? "0" : "")
.append(calendar.get(Calendar.MONTH)+1);
toParse.append("-").append(calendar.get(Calendar.DAY_OF_MONTH) < 10 ? "0" : "")
.append(calendar.get(Calendar.DAY_OF_MONTH));
toParse.append(" ").append(calendar.get(Calendar.HOUR_OF_DAY) < 10 ? "0" : "")
.append(calendar.get(Calendar.HOUR_OF_DAY));
toParse.append(":").append(calendar.get(Calendar.MINUTE) < 10 ? "0" : "")
.append(calendar.get(Calendar.MINUTE));
toParse.append(":").append(calendar.get(Calendar.SECOND) < 10 ? "0" : "")
.append(calendar.get(Calendar.SECOND));
localDateTime = LocalDateTime.parse(toParse, FORMATTER);
//Why 2015 and not 2016?
assertEquals("2015-01-01T23:59:59", localDateTime.toString());
}
it bugs me with is 2015 and not 2016, be aware that the solution is hammered to give you 2015 instead of 2016.
I'm still using Joda and no java8, but there it would be
Chronology lenient = LenientChronology.getInstance(ISOChronology.getInstance());
DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:sssss").withChronology(lenient);
DateTime dateTime = DateTime.parse("2016-01-01 00:00:86399", FORMATTER);
assertEquals("2016-01-01T23:59:59", dateTime.toLocalDateTime().toString());
Maybe you can obtain the same behavior using:
DateTimeFormatter formatter =
DateTimeFormatter.ISO_LOCAL_DATE.withResolverStyle(ResolverStyle.LENIENT);
I am reading text and storing the dates as LocalDate variables.
Is there any way for me to preserve the formatting from DateTimeFormatter so that when I call the LocalDate variable it will still be in this format.
EDIT:I want the parsedDate to be stored in the correct format of 25/09/2016 rather than printing as a string
My code:
public static void main(String[] args)
{
LocalDate date = LocalDate.now();
DateTimeFormatter formatters = DateTimeFormatter.ofPattern("d/MM/uuuu");
String text = date.format(formatters);
LocalDate parsedDate = LocalDate.parse(text, formatters);
System.out.println("date: " + date); // date: 2016-09-25
System.out.println("Text format " + text); // Text format 25/09/2016
System.out.println("parsedDate: " + parsedDate); // parsedDate: 2016-09-25
// I want the LocalDate parsedDate to be stored as 25/09/2016
}
EDIT: Considering your edit, just set parsedDate equal to your formatted text string, like so:
parsedDate = text;
A LocalDate object can only ever be printed in ISO8601 format (yyyy-MM-dd). In order to print the object in some other format, you need to format it and save the LocalDate as a string like you've demonstrated in your own example
DateTimeFormatter formatters = DateTimeFormatter.ofPattern("d/MM/uuuu");
String text = date.format(formatters);
Just format the date while printing it out:
public static void main(String[] args) {
LocalDate date = LocalDate.now();
DateTimeFormatter formatters = DateTimeFormatter.ofPattern("d/MM/uuuu");
String text = date.format(formatters);
LocalDate parsedDate = LocalDate.parse(text, formatters);
System.out.println("date: " + date);
System.out.println("Text format " + text);
System.out.println("parsedDate: " + parsedDate.format(formatters));
}
No, you cannot have a format persist, because you cannot override toString of LocalDate (constructor of LocalDate is private, it is imposible extends) and there are not a method to change the format in LocalDate persistently.
Maybe, you could create a new class and use an static method to change the format, but you have always to use MyLocalDate.myToString(localDate) instead localDate.toString() when you want other format.
public class MyLocalDate {
public static String myToString(LocalDate localDate){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
return localDate.format(formatter);
}
}
When you invoke you have to use this way
FechaInicioTextField.setText(MyLocalDate.myToString(fechaFacturaInicial));
instead of
FechaInicioTextField.setText(fechaFacturaInicial.toString());
Short answer: no.
Long answer: A LocalDate is an object representing a year, month and day, and those are the three fields it will contain. It does not have a format, because different locales will have different formats, and it will make it more difficult to perform the operations that one would want to perform on a LocalDate (such as adding or subtracting days or adding times).
The String representation (produced by toString()) is the international standard on how to print dates. If you want a different format, you should use a DateTimeFormatter of your choosing.
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"