I am trying to get the timestamp value for 2018-09-04 13:43:32.922000 by doing
Timestamp.valueOf("2018-09-04 13:43:32.922000")
my expected output is 2018-09-04 13:43:32.922
but I am getting 2018-09-04 01:13:32.922
It might be due to different timezone because my team in India got the exact result but I am here in California gets the different result.
Suggest the changes that can solve this problem.
tl;dr
myPreparedStatement.setObject(
Instant
.parse(
"2018-09-04 13:43:32.922000"
.replace( " " , "T" )
.concat( "Z" )
)
.atZone(
ZoneOffset.UTC
)
)
java.time
Suggest the changes that can solve this problem.
Never use java.sql.Timestamp.
Among the many flaws of that class is that the method you call is not documented to explain its behavior while parsing. It appears your JVM’s current default time zone is being silently applied with some adjustment. But the issue is moot.
That terribly-designed class was supplanted years ago by the modern java.time classes with the adoption of JSR 310, specifically Instant and OffsetDateTime.
Change your input string to standard ISO 8601 format by replacing the SPACE in the middle with a T.
String input = "2018-09-04 13:43:32.922000".replace( " " , "T" ) ;
Was your input intended to represent a moment in UTC, an offset of zero? If so, append a Z (pronounced Zulu).
String input = "2018-09-04 13:43:32.922000".replace( " " , "T" ).concat( "Z" ) ;
The Instant class represents a moment in UTC, always in UTC by definition.
Instant instant = Instant.parse( input ) ;
Your JDBC driver may optionally accept a Instant object.
myPreparedStatement.setObject( instant ) ;
If your JDBC driver does not support Instant, use OffsetDateTime. Support is required in JDBC 4.2 and later.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( odt ) ;
Notice how your JVM’s current default time zone at runtime is irrelevant, with no impact on the code above.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I do not think the issue is due to different time zones. Its just that the output that you are getting is in 24 hour format and that needs to be converted to 12 hour format. Please refer How to convert 24 hr format time in to 12 hr Format? to convert the time to 12 hour format.
Related
i am trying to convert ISO datetime 2021-05-31T02:40:05.2Z to dd/MM/yyyy hh:mm:ss (GMT +7) in Java language (Android). I have tried many ways but still not working.
enter image description here
tl;dr
Instant // Represent a moment as seen in UTC, with a resolution of nanoseconds.
.parse(
"2021-05-31T02:40:05.2Z" // Standard ISO 8601 format. `Z` on end means UTC (an offset of zero).
) // Returns an `Instant` object.
.atZone( // Adjust from UTC to some time zone.
ZoneId.of( "Antarctica/Davis" ) // Specify desired/expected time zone.
) // Returns a `ZonedDateTime` object.
.toString() // Returns a `String` object whose text represents the value within the `ZonedDateTime` in standard ISO 8601 format extended to append the name of the zone in square brackets.
Run live at IdeOne.com.
2021-05-31T09:40:05.200+07:00[Antarctica/Davis]
Details
Never use the legacy classes Date, SimpleDateFormat, and so on.
Parse your standard ISO 8601 input string as a Instant, a moment as seen in UTC (an offset of zero hours-minutes-seconds). The Z on end tells us this date and time is meant to be seen as having an offset of zero.
Instant instant = Instant.parse( "2021-05-31T02:40:05.2Z" ) ;
Specify your intended time zone name. You mentioned an offset of +07:00. Many time zones may share that particular offset on particular dates. I will arbitrarily choose Asia/Tomsk.
ZoneId z = ZoneId.of( "Asia/Tomsk" ) ;
Apply that time zone (ZoneId) to the Instant object to obtain a ZonedDateTime object.
ZonedDateTime zdt = instant.atZone( z ) ;
See this code run live at IdeOne.com.
zdt.toString(): 2021-05-31T09:40:05.200+07:00[Asia/Tomsk]
All this has been addressed many times on Stack Overflow. Search to learn more.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 brought some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android (26+) bundle implementations of the java.time classes.
For earlier Android (<26), the process of API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
This question already has answers here:
Converting ISO 8601-compliant String to java.util.Date
(31 answers)
Java: Convert String to TimeStamp
(11 answers)
Closed 3 years ago.
I have the following timestamp in String format
2019-04-06T00:43:21+00:00
2019-04-04T21:24:33+00:00
2019-04-04T21:02:16+00:00
How can I parse the timestamp strings above to Java.sql.timestamp?
Use DateFormat to parse your String.
try{
String x="2019-04-04T21:24:33+00:00";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssX");
Date date = (Date) df.parse(x);
java.sql.Timestamp timeStamp = new java.sql.Timestamp(date.getTime());
}catch(ParseException pe){
pe.printStackTrace();
}
As mentioned by others in comments, there is a more updated way to do this.
String time="2019-04-04T21:02:16+00:00";
OffsetDateTime odt=OffsetDateTime.parse(time,DateTimeFormatter.ISO_OFFSET_DATE_TIME);
java.sql.Timestamp timestamp=new java.sql.Timestamp(odt.toEpochSecond()*1000);
tl;dr
Timestamp // Avoid this terrible legacy class if possible. Represents a moment in UTC.
.from( // Convert from modern `Instant` to legacy `Timestamp`. No data loss, as both resolve to nanoseconds.
OffsetDateTime // Modern way to represent a moment with an offset-from-UTC (hours, minutes, and seconds).
.parse( "2019-04-06T00:43:21+00:00" ) // Parse standard ISO 8601 strings. Returns a `java.time.OffsetDateTime` object.
.toInstant() // Extract an `Instant` from the `OffsetDateTime`, thereby adjusting to UTC (an offset of zero).
) // Returns a `Timestamp` object, if needed to interoperate with old code not yet updated to *java.time*.
Even better, skip the terrible Timestamp class entirely.
myPreparedStatement.setObject( // As of JDBC 4.2 and later, exchange *java.time* objects with your database.
1 , // Specify the nth placeholder in your SQL statement.
OffsetDateTime.parse( "2019-04-06T00:43:21+00:00" ) // Parse an ISO 8601 compliant string as a `OffsetDateTime` object, a moment with an offset-from-UTC. Pass to the database via the `setObject` call.
)
OffsetDateTime
Your input strings indicate an offset-from-UTC (a number of hours-minutes-seconds), that part at the end.
Your input strings are in standard ISO 8601 format. The java.time classes use these formats by default in parsing/generating strings. So no need to specify a formatting pattern.
OffsetDateTime odt = OffsetDateTime.parse( "2019-04-06T00:43:21+00:00" ) ;
java.sql.Timestamp
Never use java.util.Timestamp. That terrible class was supplanted years ago by the modern java.time classes.
If you must have a Timestamp object to interoperate with old code not yet updated to java.time, convert by calling new methods added to the old classes. Extract a Instant from the OffsetDateTime (thereby adjusting from any offset to an offset of zero, for UTC itself). Pass the Instant object to Timestamp.from.
java.sql.Timestamp ts = Timestamp.from( odt.toInstant() ) ;
JDBC 4.2
As of JDBC 4.2, we can exchange java.time objects with the database.
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
All this has been covered many many times already on Stack Overflow. So search for more info. And in the future, search thoroughly before posting.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I am trying to save a java.util.Date from an application to my SQL Server database using JDBC.
When I convert the java.util.Date to a java.sql.Date using the method below, it truncates the time part.
java.sql.Date javaSqlExpiryDate = new java.sql.Date(javaUtilExpiryDate.getTime());
System.out.println("javaUtilExpiryDate: " + javaUtilExpiryDate.toString());
System.out.println("javaSqlExpiryDate: " + javaSqlExpiryDate.toString());
The Console window reports the output as:
javaUtilExpiryDate: Thu Sep 01 18:19:08 IST 2016
javaSqlExpiryDate: 2016-09-01
How do I get it to retain the time part as well?
Yes, that's the expected and documented behavior.
Quote from the JavaDocs
To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
If you want to keep the time, you need to use java.sql.Timestamp (especially if the column in the database is defined as datetime).
Just change your import from java.sql.Date TO java.sql.Timestamp
tl;dr
myPreparedObject.setObject(
1 ,
myJavaUtilDate.toInstant() // Convert legacy object to modern java.time object, `Instant`.
)
Details
The other Answers are correct. The java.util.Date class represents a date and a time-of-day in UTC. The java.sql.Date represents only a date, without the time-of-day. Well, actually, the java.sql.Date pretends to represent only a date but actually, as a badly-designed hack, subclasses the java.util.Date class and therefore does have a time-of-day. Confusing? Yes. One of many reasons to avoid these awful old legacy classes.
Now we have a better way, the java.time classes.
java.time
In the old days you would convert your java.util.Date object to a java.sql.Timestamp.
Now, with a JDBC driver supporting JDBC 4.2 and later, you can send your java.time objects directly to/from the database. No need for either the java.util nor java.sql classes, just stick with java.time classes.
If you have to interface with old code using java.util.Date, convert to java.time.Instant using new methods added to the old classes.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = myJavaUtilDate.toInstant() ;
Exchange an Instant with the database via PreparedStatement::setObject and ResultSet::getObject.
myPreparedStatement.setObject( … , instant ) ;
And…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
To see this moment through some other time zone than UTC, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I have a Joda DateTime object representing a UTC time, and wish to store it in a Timestamp field in a MySql table.
I have the following code:
String ztime = "2013-10-07T08:00:00Z";
DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser();
DateTime dt = parser.parseDateTime(ztime).withZone(DateTimeZone.UTC);
PreparedStatement stmt = con.prepareStatement("insert into time_test (time) values (?)");
stmt.setTimestamp(1, Timestamp(dt.getMillis()));
stmt.execute();
However, when I look in the database, the time that gets store is out by the difference of my database's timezone from UTC.
e.g. when my database is running in UTC+1, and run the above code to save "08:00Z", in the database the Timestamp shows as 09:00.
DateTime's getMillis method says " Gets the milliseconds of the datetime instant from the Java epoch of 1970-01-01T00:00:00Z."
and MySql's Timestamp says: "MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.",
so I presume it's the MySql conversion that's causing the issue, because the millis it's being initialized with is relative to a fixed UTC time, so it has no need to convert from current time zone to UTC.
My code to read the data back out into a DateTime works fine, and I get the value out that I put in, but I also need this to work with some 3rd-party code over which
I have no control, which expects the Timestamp to be in the correct UTC time.
How do I get the Timestamp field in the database to match my original UTC date/time ?
tl;dr
Use java.time classes that supplant Joda-Time.
myPreparedStatement.setObject(
… ,
Instant.parse( "2013-10-07T08:00:00Z" )
)
Retrieve.
myResultSet.getObject(
… ,
Instant.class
)
java.time
The Joda-Time project is now in maintenance-mode, recommending migration to its successor, the java.time classes built into Java 8 and later. Both are led by the same man, Stephen Colebourne. You'll find many of the same concepts in play, so fairly easy to migrate.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Your input string happens to be in standard ISO 8601 format. The java.time classes use these standard formats by default when parsing/generating strings. So no need to specify a formatting pattern.
String input = "2013-10-07T08:00:00Z" ; // Standard ISO 8601 format.
Instant instant = Instant.parse( input ) ; // Parses standard ISO 8601 format by default.
The Instant class replaces both java.util.Date and java.sql.Timestamp. As of JDBC 4.2 and later, you can directly exchange java.time objects with the database.
myPreparedStatement.setObject( … , instant ) ;
And retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
The TIMESTAMP type in MySQL seems to be akin to the SQL-standard TIMESTAMP WITH TIME ZONE type. So the code above should work appropriately.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I have one Calendar object which is as per the user's time zone which may be PST etc, now i want to convert the same to GMT and retain the time i.e. is the calendar initially was set # 00:00:00 at PST it should be converted to 08:00:00 after the conversion taking into consideration the time/date difference . Can someone provide me some help on this.
Appreciate the help in advance.
Thanks,
Vaibhav
Just create a new Calendar in GMT, set the time in that calendar to the same as the original calendar, and you're done:
gmtCalendar.setTime(userCalendar.getTime());
That should be fine, as the getTime() call returns the instant in time (i.e. a java.util.Date with no associated time zone).
As ever though, if you're doing any significant amount of date/time work in Java you should strongly consider using Joda Time instead.
tl;dr
( ( GregorianCalendar ) myCal ) // Cast from a general `Calendar` to specific subclass `GregorianCalendar`.
.toZonedDateTime() // Convert from troublesome legacy class to modern java.time class, `ZonedDateTime`.
.toInstant() // Extract a UTC-specific value, an `Instant` object.
java.time
The modern approach uses java.time classes.
Convert your legacy Calendar object (if GregorianCalendar) to a ZonedDateTime. Call new conversion methods added to the old classes.
GregorianCalendar gc = ( GregorianCalendar ) myCal ;
ZonedDateTime zdt = gc.toZonedDateTime() ;
Now extract an Instant, a value always in UTC. You can think of it this way conteptually: ZonedDateTime = ( Instant + ZoneId )
Instant instant = zdt.toInstant() ;
For more flexibility such as generating strings in various formats, convert to an OffsetDateTime object.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.