how to convert string to date (HHMMMDD) (hour, month, day-of-month) - java

I try to convert a string into date type. This is the whole what I did.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HHMMMDD");
String date = "23Mar25";
System.out.println(date);
LocalDate localDate = LocalDate.parse(date, formatter);
System.out.println(localDate);
And I got the error information as
Text '23Mar25' could not be parsed:
Unable to obtain LocalDate from TemporalAccessor:
{MonthOfYear=3, DayOfYear=25},ISO resolved to 23:00 of type
java.time.format.Parsed at
java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
Anyone can help me to solve it?

tl;dr
LocalTime.parse( "23Mar25" , DateTimeFormatter.ofPattern ( "HHMMMdd", Locale.US )
.toString() // 23:00
…and…
MonthDay.parse( "23Mar25" , DateTimeFormatter.ofPattern ( "HHMMMdd", Locale.US )
.toString() // --03-25
Details
If you are certain that input indeed represents an hour-of-day, month, and day-of-month…
DateTimeFormatter
Define a single DateTimeFormatter. Be sure to specify a Locale for the human language by which to translate the abbreviated name of the month.
String input = "23Mar25";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "HHMMMdd", Locale.US );
LocalTime
Use that formatter twice. Once to produce a time-of-day as a LocalTime object to hold the hour-of-day.
LocalTime lt = LocalTime.parse ( input, f );
MonthDay
Again to produce a MonthDay object to hold the month and the day-of-month.
MonthDay md = MonthDay.parse ( input , f );
ZoneId
To make a specific moment of that value, we must assign a year and a time zone. If we want to use use the current year, we need a time zone for that as well. Keep in mind the fact that for any given moment both the date and the time-of-day vary around the globe by zone.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of ( "America/Montreal" );
LocalDate
Determine a LocalDate object by assigning a year to our MonthDay object.
int yearNumber = Year.now ( z )
.getValue ( ) ;
LocalDate ld = md.atYear ( yearNumber );
ZonedDateTime
Combine with the LocalTime to get an exact moment, a point on the timeline. Result is a ZonedDateTime object.
ZonedDateTime zdt = ZonedDateTime.of ( ld, lt, z );
Dump to console.
System.out.println ( "input: " + input );
System.out.println ( "lt: " + lt );
System.out.println ( "md: " + md );
System.out.println ( "ld: " + ld );
System.out.println ( "zdt: " + zdt );
input: 23Mar25
lt: 23:00
md: --03-25
ld: 2017-03-25
zdt: 2017-03-25T23:00-04:00[America/Montreal]
OffsetDateTime
If your input is intended for UTC, then instead of ZoneId and ZonedDateTime, use ZoneOffset.UTC constant and OffsetDateTime class in code similar to above.
OffsetDateTime zdt = OffsetDateTime.of ( ld, lt, ZoneOffset.UTC );
ISO 8601
Notice the output, the strings generated by the toString methods. The java.time classes use the ISO 8601 standard formats by default when parsing/generating strings. I strongly suggest you and your data-source use these standard formats rather than invent your own such as seen in the Question. The java.time classes can directly parse as well as generate such standard strings without needing to specify a formatting pattern.
To generate strings in other formats, use the DateTimeFormatter class. That topic is covered by many other Stack Overflow pages, so search for many examples and more discussion.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HHMMMDD");
It is using a pattern for:
HH: 2 spaces for hour
MMM: 3 spaces for month
DD: 2 spaces for day
I think you want a format like: `ddmmmyy
dd: 2 spaces for day
mmm: 3 spaces for month
yy: 2 spaces for year

Related

How can I add 18 as day to current month using java Instant

I can get the current date using
Instant.now()
I am looking to get 18-<current month>-<current year>
I endorse Basil Bourque's answer. However, if you are looking for an Instant object, you can get it by adjusting the current OffsetDateTime at UTC to 18th day of the month as shown below:
public class Main {
public static void main(String[] args) {
Instant thisInstantOn18th = OffsetDateTime.now(ZoneOffset.UTC)
.with(ChronoField.DAY_OF_MONTH, 18)
.toInstant();
System.out.println(thisInstantOn18th);
}
}
Output:
2022-12-18T19:19:20.128313Z
Learn more about the modern Date-Time API from Trail: Date Time.
tl;dr
YearMonth // Represents a year and month only, no day of month.
.now(
ZoneId.of( "America/Edmonton" ) // Returns a `ZoneId` object.
)
.atDay( 18 ) // Returns a `LocalDate` object.
.format(
DateTimeFormatter
.ofPattern( "dd-MM-uuuu" )
) // Returns a `String` object.
Details
As Comments by Ole V.V. explain, you are using the wrong class. No need for Instant here.
To represent a date, use LocalDate.
To represent a year and month, use YearMonth.
Capture the current year-month.
Doing so requires a time zone. For any given moment, the date varies around the globe by time zone. So the current month could be simultaneously “next month” in Tokyo Japan while “last month” in Toledo Ohio.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
YearMonth ym = YearMonth.now( z ) ;
If you want the current month as seen with an offset of zero hours-minutes-seconds from UTC, use ZoneOffset.UTC constant.
YearMonth ym = YearMonth.now( ZoneOffset.UTC ) ;
Apply a day of month to get a date.
LocalDate ld = ym.atDay( 18 ) ;
Generate text in standard ISO 8601 format.
String output = ld.toString() ;
Generate text in a specific format.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ;
String output = ld.format( f ) ;

Java Time conversion from string to ZonedDateTime

Hello I am trying to convert a Date and Time from a SQL data base that is being stored in UTC time to my systems Local Time zone that will be displayed in a table in a JAVAFX application.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String appointmentStart = rs.getString("Start");
LocalDateTime ldtStart = LocalDateTime.parse(appointmentStart, formatter);
ZonedDateTime zdtStart = ZonedDateTime.of(ldtStart, ZoneId.systemDefault());
appointmentStart = zdtStart.format(formatter);
String appointmentEnd = rs.getString("End");
LocalDateTime ldtEnd = LocalDateTime.parse(appointmentEnd, formatter);
ZonedDateTime zdtEnd = ZonedDateTime.of(ldtEnd, ZoneId.systemDefault());
appointmentEnd = zdtEnd.format(formatter);
This is what I have written. The table is being populated in UTC time and is not converting. I get no errors but is this logic wrong? If so how can I do this?
Welcome to Stack Overflow!
There are a couple issues with your code:
Look and code lines 3 and 4. You don't actually parse as UTC.
Since your appointmentStart string doesn't include the timezone, you need to specify that in your DateTimeFormatter.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneOffset.UTC);
String appointmentStart = rs.getString("Start");
// UTC
ZonedDateTime ldtStart = ZonedDateTime.parse(appointmentStart, formatter);
// Local.
ZonedDateTime start = ldtStart.withZoneSameInstant(ZoneId.systemDefault());
tl;dr
DateTimeFormatter // Class for generating text that represents the value of a date-time object.
.ofLocalizedDateTime( FormatStyle.FULL ) // Automatically localize the generated text.
.withLocale( Locale.FRANCE ) // Whatever human language and cultural norms are best for presentation to this particular user. Or call `Locale.getDefault`.
.format( // Generate text.
LocalDateTime // Represent a date with a time-of-day. Does *not* represent a moment as it lacks the context of a time zone or offset from UTC.
.parse( // Interpret text as a date-time value.
"2023-01-23 15:30:55"
.replace( " " , "T" ) // Comply with ISO 8601 format. Then we can proceed with parsing without bothering to specify a formatting pattern.
) // Returns a `LocalDateTime` object.
.atOffset( ZoneOffset.UTC ) // Returns a `OffsetDateTime` object.
.atZoneSameInstant(
ZoneId.systemDefault()
) // Returns a `ZonedDateTime` object.
) // Return a `String` object.
lundi 23 janvier 2023 à 07:30:55 heure normale du Pacifique nord-américain
Details
The Answer by CryptoFool and the Answer by Oliver are headed in the right direction. But I do not like that they directly inject an offset before parsing the date-time alone. I also do not like that they use ZonedDateTime where OffsetDateTime is more appropriate.
Apparently you have an input string with a date and a time-of-day but lacking the context of a time zone or offset from UTC. For example: "2023-01-23 15:30:55".
String input = "2023-01-23 15:30:55" ;
That input nearly complies with the ISO 8601 standard format for date-time values. To fully comply, swap that SPACE in the middle with a T.
String modified = input.replace( " " , "T" ) ;
The java.time classes use ISO 8601 formats by default when parsing/generating text. So no need to specify a formatting pattern.
Parse as a date-with-time object, an LocalDateTime object.
LocalDateTime ldt = LocalDateTime.parse( modified );
You said you want to assume that date and time is intended to represent a moment as seen with an offset from UTC of zero hours-minutes-seconds. Java offers a constant for that offset, ZoneOffset.UTC. Apply that ZoneOffset to produce an OffsetDateTime object.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
Next you asked to adjust from that offset of zero to view the same moment in the JVM’s current default time zone. Same moment, same point on the timeline, but different wall-clock time.
Get that default zone.
ZoneId z = ZoneId.systemDefault() ;
Apply that ZoneId to the OffsetDateTime to get a ZonedDateTime.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Generate text in localized format. Specify the Locale to use in localizing for human language and cultural norms.
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale );
String output = zdt.format( f );
Pull all that code together.
String input = "2023-01-23 15:30:55";
String modified = input.replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( modified );
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
ZoneId z = ZoneId.systemDefault();
ZonedDateTime zdt = odt.atZoneSameInstant( z );
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale );
String output = zdt.format( f );
Dump to console.
input = 2023-01-23 15:30:55
modified = 2023-01-23T15:30:55
ldt = 2023-01-23T15:30:55
odt.toString() = 2023-01-23T15:30:55Z
z.toString() = America/Los_Angeles
zdt.toString() = 2023-01-23T07:30:55-08:00[America/Los_Angeles]
output = Monday, January 23, 2023 at 7:30:55 AM Pacific Standard Time
There may be a slicker way to do this, but here's how I would do this:
// We have an unzoned datetime String that we assume is in UTC
String appointmentStart = "2022-12-24 11:00:00";
// Add a UTC time (+0) offset to the end of our String, and parse it to get a UTC-zoned ZonedDateTime
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssZ");
ZonedDateTime utcStart = ZonedDateTime.parse(appointmentStart + "+0000", formatter);
// Convert to the local timezone
ZonedDateTime localZonedStart = utcStart.withZoneSameInstant(ZoneId.systemDefault());
// Define a formatter that doesn't include the time zone
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// Convert the local time to a String
String localZonedStartString = localZonedStart.format(formatter2);
// Print the resulting String
System.out.println(localZonedStartString);
Result:
2022-12-24 03:00:00
I'm in Pacific time zone, which is offset by -8 hours from UTC, and we see that the resulting string is correct for my local time zone.

Create an Instance of ZonedDateTime from String with same time as String [Java]

I want to create an instance of ZonedDateTime from String. I want to make "2021-03-18 8:00:00" turn into "2021-03-18 8:00:00 EST". I don't want an unexpected variable to interfere by converting 8:00:00 to a different time from what is shown. i.e from 8:00:00 to 17:00:00.
The code that I used to try to convert it was:
SimpleDateFormat estForm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
estForm.setTimeZone(TimeZone.getTimeZone("EST"));
String start = "2021-03-18 08:00:00";
Date estDT = estForm.parse(start);
final ZoneId zoneEST = ZoneId.of("US/Eastern");
ZonedDateTime zoneEst = ZonedDateTime.ofInstant(estDT.toInstant(), zoneEST);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(zoneEST);
System.out.println(zoneEst);
Here is the last output I got from this:
US/Eastern
2021-03-18T09:00-04:00[US/Eastern]
Well, you could simply do:
"2021-03-18 08:00:00" + " EST"
If you want to treat the input as a logical date-time value, parse as a LocalDateTime. This type is appropriate because your input lacks indicator of time zone or offset-from-UTC.
Then call atZone to place that date-with-time into the context of a time zone. EST is not a time zone. Such 2-4 pseudo-zones represent only a general idea of whether Daylight Saving Time (DST) is effect, and even that is just a general idea for an area, not precise. Also not standardized, and not even unique.
I will guess that you want New York time.
LocalDateTime
.parse(
"2021-03-18 08:00:00".replace( " " , "T" )
) // Returns a `LocalDateTime` object.
.atZone(
ZoneId.of( "America/New_York" )
) // Returns a `ZonedDateTime` object.
Generally best to let DateTimeFormatter automatically localize while generating text, via the `ofLocalized… methods. But if you insist on your specific method, define a formatting pattern.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss z" ) ;
String output = zdt.format( f ) ;
Pull that code together.
ZonedDateTime zdt =
LocalDateTime
.parse( "2021-03-18 08:00:00".replace( " " , "T" ) )
.atZone(
ZoneId.of( "America/New_York" )
)
;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss z" ) ;
String output = zdt.format( f ) ;
See this code run live at IdeOne.com.
2021-03-18 08:00:00 EDT
As we can see in that output, your desired EST is incorrect, as New York time switched off DST to standard time a few days before this date-time.

Parse non ISO 8601 to ISO_INSTANT

I'm trying parse this String 2020-05-20 14:27:00.943000000 +00:00 and this Wed May 20 14:27:00 CEST 2020 to a ISO_INSTANT, but always return this exception
java.time.format.DateTimeParseException: Text '2020-05-20 14:27:00.943000000 +00:00' could not be parsed at index 10
My code is:
protected Instant parseDateTime(String fechaHora) {
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
TemporalAccessor temporalAccessor = formatter.parse(fechaHora);
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
Instant result = Instant.from(zonedDateTime);
return result; }
How can I convert this types?
tl;dr
OffsetDateTime.parse(
"2020-05-20 14:27:00.943000000 +00:00" ,
DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss.SSSSSSSSS xxx" )
)
.toInstant()
Fixing your code
Your code is flawed in a few ways.
Use of TemporalAccessor is unnecessary and inappropriate here. To quote its Javadoc:
This interface is a framework-level interface that should not be
widely used in application code. Instead, applications should create
and pass around instances of concrete types
LocalDateTime is not appropriate here as it strips away vital information, the time zone or offset-from-UTC.
You specified a formatter whose formatting pattern does not match your inputs.
Solution
Manipulate your input string to comply with standard ISO 8601 format. Replace the SPACE between date and time with T. Delete SPACE between time and offset.
String input = "2020-05-20 14:27:00.943000000 +00:00" ;
String[] strings = input.split( " " ) ;
String modifiedInput = strings[0] + "T" + strings[1] + strings[2] ;
Parse as an OffsetDateTime, a date with time-of-day in the context of an offset-from-UTC.
OffsetDateTime odt = OffsetDateTime.parse( modifiedInput ) ;
Or, define a formatting pattern to match your input string. Use the DateTimeFormatter class. This has been covered many many times already on Stack Overflow, so search to learn more.
The predefined formatter DateTimeFormatter.ISO_INSTANT that you tried to use does not match your input. Your input does not comply with the ISO 8601 standard used by that formatter.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss.SSSSSSSSS xxx" ) ;
String input = "2020-05-20 14:27:00.943000000 +00:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;
See this code run live at IdeOne.com.
odt.toString(): 2020-05-20T14:27:00.943Z
If you need to return an Instant, call toInstant.
Instant instant = odt.toInstant() ;
To see that same moment in the context of a time zone, apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
The OffsetDateTime and ZonedDateTime objects represent the same moment, same point on the timeline.
The cause of your exception is the different format between your String 2020-05-20 14:27:00.943000000 +00:00 and ISO_INSTANT ; from DateTimeFormatter ISO_INSTANT accepts strings like 2011-12-03T10:15:30Z and this is not your case. A possible solution to this problem is use a custom DateTimeFormatter like below:
String fechaHora = "2020-05-20 14:27:00.943000000 +00:00";
DateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS ZZZZZ");
TemporalAccessor temporalAccessor = formatter.parse(fechaHora);
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
Instant result = Instant.from(zonedDateTime);
System.out.println(result); //<-- it will print 2020-05-20T12:27:00.943Z

Plus 1 hour and 1 day in date using java 8 apis

I have this code to add 1 hour or 1 day in date Java 8, but doesn´t work
String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(DATE_FORMAT);
Date parse = format.parse("2017-01-01 13:00:00");
LocalDateTime ldt = LocalDateTime.ofInstant(parse.toInstant(), ZoneId.systemDefault());
ldt.plusHours(1);
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date te = Date.from(zdt.toInstant());
What´s wrong? The code shows: Sun Jan 01 13:00:00 BRST 2017
LocalDateTime is immutable and returns a new LocalDateTime when you call methods on it.
So you must call
ldt = ldt.plusHours(1);
Apart from the issue that you don't use the result of your date manipulation (ldt = ldt.plusHours(1)), you don't really need to go via a LocalDateTime for this operation.
I would simply use an OffsetDateTime since you don't care about time zones:
OffsetDateTime odt = parse.toInstant().atOffset(ZoneOffset.UTC);
odt = odt.plusDays(1).plusHours(1);
Date te = Date.from(odt.toInstant());
You could even stick to using Instants:
Instant input = parse.toInstant();
Date te = Date.from(input.plus(1, DAYS).plus(1, HOURS));
(with an import static java.time.temporal.ChronoUnit.*;)
tl;dr
LocalDateTime.parse( // Parse input string that lacks any indication of offset-from-UTC or time zone.
"2017-01-01 13:00:00".replace( " " , "T" ) // Convert to ISO 8601 standard format.
).atZone( // Assign a time zone to render a meaningful ZonedDateTime object, an actual point on the timeline.
ZoneId.systemDefault() // The Question uses default time zone. Beware that default can change at any moment during runtime. Better to specify an expected/desired time zone generally.
).plus(
Duration.ofDays( 1L ).plusHours( 1L ) // Add a span of time.
)
Details
Do not mix the troublesome old legacy classes Date and Calendar with the modern java.time classes. Use only java.time, avoiding the legacy classes.
The java.time classes use the ISO 8601 standard formats by default when parsing and generating strings. Convert your input string by replacing the SPACE in the middle with a T.
String input = "2017-01-01 13:00:00".replace( " " , "T" ) ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
ALocalDateTime does not represent an actual moment, not a point on the timeline. It has no real meaning until you assign a time zone.
ZoneId z = ZoneId.systemDefault() ; // I recommend specifying the desired/expected zone rather than relying on current default.
ZonedDateTime zdt = ldt.atZone( z ) ;
A Duration represents a span of time not attached to the timeline.
Duration d = Duration.ofDays( 1L ).plusHours( 1L ) ;
ZonedDateTime zdtLater = zdt.plus( d ) ;

Categories

Resources