I'm trying to convert a JSON object to a date and write it to a database. The code to convert the date to EST isn't working however. What's the best way to convert a date to EST?
JSON entry
"custom_date_1": "2019-05-19","
Conversion Code
int id;
Date trainingDate;
SimpleDateFormat format = new SimpleDateFormat("DD-MM-YY", Locale.US);
TimeZone tz = TimeZone.getTimeZone("EST");
format.setTimeZone(tz);
logger.info("custom_date_1: {}", object.getString("custom_date_1"));
try {
id= Integer.parseInt(object.getString("employee_number"));
trainingDate = format.parse(object.getString("custom_date_1"));
//Still says GMT
logger.info("trainingDate: {}", trainingDate);
map.put("employee_number", id);
map.put("custom_date_1", trainingDate);
} catch (ParseException e) {
e.printStackTrace();
}
Log Statement
2019-06-10 14:00:00,226 INFO custom_date_1: 2019-05-19
2019-06-10 14:00:00,226 INFO trainingDate: Sun Dec 30 05:00:00 GMT 2018
tl;dr
myPreparedStatement.setObject( // In JDBC 4.2 and later, exchange *java.time* objects with your database. Use `PreparedStatement` to avoid SQL Injection attacks.
… , // Specify which `?` placeholder to replace in your SQL statement.
LocalDate.parse( "2019-05-19" ) // Parse your standard ISO 8601 formatted input string as a date-only value represented in the `LocalDate` class.
)
Details
"custom_date_1": "2019-05-19",
Your input string is in standard ISO 8601 format. These standard formats are used by default in the java.time classes when parsing/generating strings. So no need to specify a formatting pattern.
LocalDate ld = LocalDate.parse( "2019-05-19" ) ;
Time zone is irrelevant here. So your Question is quite confusing.
I'm trying to convert a JSON object to a date and write it to a database.
As of JDBC 4.2, we can exchange java.time objects with the database. Your column in the database for this date-only value (without time-of-day and without time zone) should be of a type akin to the standard SQL type DATE.
myPreparedStatement.setObject( … , ld ) ;
Retrieve.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
From Java 8 onwards you should be using LocalDate and LocalDateTime, so you can do timezone conversions using
LocalDateTime.atZone(ZoneId zoneId)
For example
LocalDateTime date = LocalDateTime.parse("2019-06-10T12:00:00");
ZonedDateTime date2 = date.atZone(ZoneId.systemDefault());
Related
I want to convert this string "2022-01-13 14:33:07.996" to java sql date. I have read the answers and I have converted the string to java util date and then to java sql date. I just don't know how to get the full date in java sql date format
String dateStart = "2022-01-13 14:33:07.996";
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date1 = dateFormat.parse(dateStart);
java.util.Date utilDate = date1;
java.sql.Date sqlDate = new java.sql.Date(date1.getTime());
System.out.println(sqlDate);
in out put i get this
2022-01-13
but I want something like this 2022-01-13 14:33:07.996 in java sql date format
tl;dr
To write date-time values to a database, use appropriate objects, not text. For a date-only value, use LocalDate.
myPreparedStatement
.setObject(
… ,
LocalDateTime
.parse( "2022-01-13 14:33:07.996".replace( " " , "T" ) )
.toLocalDate()
)
Avoid legacy date-time classes
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.
Date-only
You said:
2022-01-13 14:33:07.996 in java sql date format
That is a contradiction. A java.sql.Date object represents a date-only, not a date with time-of-day.
java.time.LocalDateTime
Parse your input string as a LocalDateTime because it lacks any indicator of time zone or offset. Replace the SPACE in the middle with a T to comply with the ISO 8601 standard.
String input = "2022-01-13 14:33:07.996".replace( " " , "T" ) ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
java.time.LocalDate
Extract the date portion.
LocalDate ld = ldt.toLocalDate() ;
Database access
Write to database.
myPreparedStatement.setObject( … , ld ) ;
Retrieve from database.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
These matters have been covered many many times already on Stack Overflow. Search to learn more.
I'm trying to format date in java using SimpleDateFormat class. I have written a function which takes in string as a parameter and returns date as a output having the desired format. The problem arises when i try to parse the date in order to convert the string to date , the value is returned as Wed Jul 03 00:00:00 IST 2019 , instead of yyyy-MM-dd format .
private static final String DOB_FORMAT = "yyyy-MM-dd";
public static Date convertStringToDateFormatYYYYMMDD(String date) {
if (date != null) {
SimpleDateFormat sdf = new SimpleDateFormat(DOB_FORMAT, Locale.ENGLISH);
Date parsedDate = null;
try {
parsedDate = sdf.parse(date);
LOG.info("Date formated " + parsedDate);
return parsedDate;
} catch (ParseException e) {
LOG.info("Date Parsing Issue - date :" + date);
}
}
return null;
}
The result value should be returned as yyyy-MM-dd, instead of Wed Jul 03 00:00:00 IST 2019
Avoid legacy date-time classes
I'm trying to format date in java using SimpleDateFormat class.
You are using terrible date-time classes that were supplanted years ago by the modern java.time classes, with the adoption of JSR 310.
ISO 8601
DOB_FORMAT = "yyyy-MM-dd"
That format happens to comply with the ISO 8601 standard.
The java.time classes comply with the standard as well, using those formats by default when parsing/generating strings.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
String input = "2019-01-23" ; // January 23, 2019
LocalDate localDate = LocalDate.parse( input ) ;
Text has formats, not date-time objects
You Question also says:
value is returned as Wed Jul 03 00:00:00 IST 2019 , instead of yyyy-MM-dd format .
Be clear that date-time objects do not have a “format”. Only text strings have a format. A date-time object is not a text string. A date-time object parses a text string to generate a date-time value, and a date-time object can generate text representing its date-time value. But the date-time object and the text are distinct and separate from one another.
Avoid java.util.Date
Date parsedDate = null;
The terrible java.util.Date class represents a date with time-of-day in UTC (an offset from UTC of zero hours-minutes-seconds). But you want only a date, without the time-of-day and without an offset or time zone. So square peg, round hole. Instead, use appropriate types. And stop using those legacy date-time classes; use only java.time classes.
Generating text
To generate a string in standard ISO 8601 format, simply call toString.
String output = localDate.toString() ;
2019-01-23
To generate a string automatically-localized:
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( locale ) ;
String output = localDate.format( f ) ;
See this code run live at IdeOne.com.
23 janv. 2019
Date object is not formatted itself. You can return a formatted String containing the information.
I have a java component to format the date that I retrieve. Here is my code:
Format formatter = new SimpleDateFormat("yyyyMMdd");
String s = "2019-04-23 06:57:00.0";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss.S");
try
{
Date date = simpleDateFormat.parse(s);
System.out.println("Formatter: "+formatter.format(date));
}
catch (ParseException ex)
{
System.out.println("Exception "+ex);
}
The code works great as long as the String s has the format "2019-04-23 06:57:00.0";
My Question is, how to tweak this code so it will work for below scenarios ex,
my s string may have values like
String s = "2019-04-23 06:57:00.0";
or
String s = "2019-04-23 06:57:00";
Or
String s = "2019-04-23";
right now it fails if I don't pass the ms.. Thanks!
Different types
String s = "2019-04-23 06:57:00";
String s = "2019-04-23";
These are two different kinds of information. One is a date with time-of-day, the other is simply a date. So you should be parsing each as different types of objects.
LocalDateTime.parse
To comply with the ISO 8601 standard format used by default in the LocalDateTime class, replace the SPACE in the middle with a T. I suggest you educate the publisher of your data about using only ISO 8601 formats when exchanging date-time values as text.
LocalDateTime ldt1 = LocalDateTime.parse( "2019-04-23 06:57:00".replace( " " , "T" ) ) ;
The fractional second parses by default as well.
LocalDateTime ldt2 = LocalDateTime.parse( "2019-04-23 06:57:00.0".replace( " " , "T" ) ) ;
See this code run live at IdeOne.com.
ldt1.toString(): 2019-04-23T06:57
ldt2.toString(): 2019-04-23T06:57
LocalDate.parse
Your date-only input already complies with ISO 8601.
LocalDate ld = LocalDate.parse( "2019-04-23" ) ;
See this code run live at IdeOne.com.
ld.toString(): 2019-04-23
Date with time-of-day
You can strip out the time-of-day from the date.
LocalDate ld = ldt.toLocalDate() ;
And you can add it back in.
LocalTime lt = LocalTime.parse( "06:57:00" ) ;
LocalDateTime ldt = ld.with( lt ) ;
Moment
However, be aware that a LocalDateTime does not represent a moment, is not a point on the timeline. Lacking the context of a time zone or offset-from-UTC, a LocalDateTime cannot hold a moment, as explained in its class JavaDoc.
For a moment, use the ZonedDateTime, OffsetDateTime, or Instant classes. Teach the publisher of your data to include the offset, preferably in UTC.
Avoid legacy date-time classes
The old classes SimpleDateFormat, Date, and Calendar are terrible, riddled with poor design choices, written by people not skilled in date-time handling. These were supplanted years ago by the modern java.time classes defined in JSR 310.
In case of you have optional parts in pattern you can use [ and ].
For example
public static Instant toInstant(final String timeStr){
final DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH[:mm[:ss[ SSSSSSSS]]]")
.withZone(ZoneId.of("UTC"));
try {
return Instant.from(formatter.parse(timeStr));
}catch (DateTimeException e){
final DateTimeFormatter formatter2 = DateTimeFormatter
.ofPattern("yyyy-MM-dd")
.withZone(ZoneId.of("UTC"));
return LocalDate.parse(timeStr, formatter2).atStartOfDay().atZone(ZoneId.of("UTC")).toInstant();
}
}
cover
yyyy-MM-dd
yyyy-MM-dd HH
yyyy-MM-dd HH:mm
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd HH:mm:ss SSSSSSSS
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 ) ;
I'm trying to convert a String value (initially a LocalDateTime variable) that was stored in a database (as datetime) and parse it into a LocalDateTime variable. I've tried it with a formatter:
String dTP;
dTP=(rs.getString("arrivedate"));
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime dateTimeParked = LocalDateTime.parse(dTP,formatter);
And without a formatter:
String dTP;
dTP=(rs.getString("arrivedate"));
LocalDateTime dateTimeParked = LocalDateTime.parse(dTP);
But I get the same error each time:
Exception in thread "AWT-EventQueue-0" java.time.format.DateTimeParseException: Text '2016-07-09 01:30:00.0' could not be parsed at index 10
My thinking is that index 10 is the space between date and time.
Could anyone help me with this? I've been at it for hours :(
There is a error in the format of the that causes the issue. Please refer https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html.The ISO date time is of the format '2011-12-03T10:15:30' . The following will give you the idea
public static void main(String[] args) throws Exception {
String isoDate = "2016-07-09T01:30:00.0";
// ISO Local Date and Time '2011-12-03T10:15:30'
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime dateTimeParked = LocalDateTime.parse(isoDate, formatter);
System.out.println(dateTimeParked);
String date = "2016-07-09 01:30:00.0";
DateTimeFormatter formatterNew = DateTimeFormatter.ofPattern("yyyy-LL-dd HH:mm:ss.S");
LocalDateTime dateTimeParkedNew = LocalDateTime.parse(date, formatterNew);
System.out.println(dateTimeParkedNew);
}
This prints :
2016-07-09T01:30
2016-07-09T01:30
The other answers are correct, your string is in SQL format which differs from the canonical version of ISO 8601 format by using a space character in the middle rather than a T. So either replace the space with a T or define a formatting pattern for parsing.
Use smart objects, not dumb strings
But the bigger problem is that you are retrieving the date-time value from your database as a string. You should be retrieving date-time types of data as date-times types in Java.
For drivers compliant with JDBC 4.2 and later, you should be able to use setObject and getObject with java.time objects.
For SQL type of TIMESTAMP WITHOUT TIME ZONE use LocalDateTime. For TIMESTAMP WITH TIME ZONE, use Instant or perhaps ZonedDateTime depending on the database.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class );
Store in database.
myPreparedStatement.setObject( … , ldt ) ;
try this formatter:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
I'm not sure about the millisecond part though (In case it is more than 1 character long).