I'm attempting to insert a datetime into a mysql database for the current UTC time via the GETUTCDATE() function in sql. It's failing with "FUNCTION GETUTCDATE DOES NOT EXIST".
Is a way for me to get the current UTC time in sql datetime format from Java, and simply insert it as a string?
Another big issue I'm having is I need to convert the above utc datetime object into local time zones and I don't really know how to do that through standard java api's.
tl;dr
myPreparedStatement // Using a `PreparedStatement` avoids SQL-injection security risk.
.setObject( // As of JDBC 4.2, we can exchange java.time objects with a database via `getObject`/`setObject` methods.
… , // Indicate which `?` placeholder in your SQL statement.
OffsetDateTime.now( ZoneOffset.UTC ) // Capture the current moment in UTC.
) ;
java.time
The modern solution uses the java.time classes that years ago supplanted the terrible old date-time classes.
Get the current moment in UTC using OffsetDateTime.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
MySQL 8.0 uses a resolution of microseconds, for six decimal places in a fractional second. The java.time classes carry a finer resolution of nanoseconds. So you may want to truncate any existing nanos from your OffsetDateTime. Specify your desired resolution with ChronoUnit.
OffsetDateTime odt =
OffsetDateTime
.now(
ZoneOffset.UTC
)
.truncatedTo( ChronoUnit.MICROS )
;
Send to your database via a PreparedStatement to a column of a type akin to the SQL-standard TIMESTAMP WITH TIME ZONE data type. For MySQL 8.0, that would be the type TIMESTAMP.
myPreparedStatement.setObject( … , odt ) ;
And retrieval via a ResultSet.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
To see this moment through the lens of the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ; // Same moment, same point on the timeline, different wall-clock time.
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.
You can do it as follows:
OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);
String sql_date = utc.format(DateTimeFormatter.ofPattern("MM/dd/yyyy")); //here, you can change the format of SQL date as you need
You would need to import the classes as follows:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
Hope it helps.
Related
In my application i want get some data from server and i should cast date and time!
I receive date and time with this format end_date: "2020-04-08 13:11:14" from server.
I want get now date and time from my device and to calculate with above date (end_date), if this time under 24h i should show for example 15 hour later, but if this time more than 24h i should show 2 days later!
But i don't know how can i it?
Can you help me with send code or send to me other tutorials?!
I searched that but I didn't find anything.
java.time
The modern approach uses java.time classes.
Parse the input string as a LocalDateTime.
To parse, replace the SPACE in the middle with a T to comply with ISO 8601 standard.
String input = "2020-04-08 13:11:14".replace( " " , "T" ) ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
Your input lacks an indicator of any time zone or offset-from-UTC. So we do not know if this was meant to be 1 PM in Tokyo Japan, 1 PM in Toulouse France, or 1 PM in Toledo Ohio US. So you cannot reliably compare this to the current date and time.
If you want to presume this string was meant to tell time in your time zone, then assign a time zone to get a ZonedDateTime.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime then = ldt.atZone( z ) ;
Capture the current moment in the same zone.
ZonedDateTime now = ZonedDateTime.now( z ) ;
Calculate 24 hours later.
ZonedDateTime twentyFourHoursFuture = now.plusHours( 24 ) ;
Compare.
boolean within24Hours = then.isBefore( twentyFourHoursFuture ) ;
Determine elapsed time using the Duration class.
Duration duration = Duration.between( then , now ) ;
If you want to trust the JVM’s current default time zone, call ZoneId.systemDefault. Beware that this default can be changed by other Java code during execution of your app.
ZoneId z = ZoneId.systemDefault() ;
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.
Try using the datetime library, or you can see this answer.
Also if you can choose, it's a good habit to pass the times in UTC from/to the server, it'll save some localization and timezone troubles.
I'm trying to get a date from a DataObject (Service Date Object (SDO)) that comes to me as an input and insert it into an Oracle database. The problem has been that the Date I get does not seem to have the introduced hour.
I am using the setDate() method from DataObject with the following value: 2019-05-22T13:30:00Z.
For some reason, when using getDate() what is returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I'm not sure if it's due to the input format or something related to the Date class from java.utils.
An easy solution would be to pass it as String and convert it into Date using a format but I would like to save this intermediate step.
java.util.Date versus java.sql.Date
Your Question does not provide enough detail to know for sure, but I can take an educated guess.
returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I suspect your code calling setDate and/or getDate is using a java.sql.Date object rather than a java.util.Date object.
➥ Check your import statements. If you used the wrong class by accident, that would explain the time-of-day getting set to 00:00.
java.util.Date represents a moment in UTC (a date, a time-of-day, and an offset-from-UTC of zero hours-minutes-seconds).
java.sql.Date pretends to represent a date-only, without a time-of-day and without a time zone or offset-from-UTC. Actually does contain a time-of-day and offset, but tries to adjust the time to 00:00:00.0 as part of the pretense.
Confusing? Yes. These old date-time classes from the earliest days of Java are a bloody awful mess, built by people who did not understand the complexities of date-time handling. Avoid these legacy date-time classes!
These legacy classes were supplanted years ago by the modern java.time classes defined in JSR 310. Try to do all your work in java.time. When interoperating with old code such as SDO that is not yet updated for java.time, call on new conversion methods added to the old classes.
The modern replacement of a java.util.Date is java.time.Instant. Both represents a moment in UTC, though Instant has a finer resolution of nanoseconds versus milliseconds.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Convert from modern class to legacy class. Beware of data-loss: Any microseconds or nanoseconds in the fractional second are truncated to milliseconds (as noted above).
java.util.Date d = java.util.Date.from( instant ) ; // Convert from modern to legacy. Truncates any microseconds or nanoseconds.
Pass to your SDO object.
mySdoDataObject.setDate( d ) ;
Going the other direction, retrieve the legacy java.util.Date object and immediately convert to an Instant.
Instant instant = mySdoDataObject.getDate().toInstant() ;
To see that same moment through the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
An easy solution would be to pass it as String
No! Use smart objects, not dumb strings. We have the industry-leading date-time library built into Java, so use it.
Database
As of JDBC 4.2, we can directly exchange java.time objects with the database.
Your JDBC driver may optionally handle Instant. If not, convert to OffsetDateTime.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
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.
how to mock following code? i dont want to change my code.
Date date = new Date();
String res_timestamp=new Timestamp(date.getTime()).toString();
my code:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("PST"));
Date NOW = sdf.parse("2019-02-11 00:00:00");
Timestamp time=new Timestamp(NOW.getTime());
whenNew(Timestamp.class).withNoArguments().thenReturn(time);
how can i mock it? am finding hard to mock it.
how can i solve it?
note: i do not want to change my code. without changing my code i have to mock those two lines.
tl;dr
Use java.time.Clock, ZonedDateTime, Instant, ZoneId.
Inject an altered Clock object as a dependency: Clock.fixed( … ).
Never use Date, Calendar, SimpleDateFormat, Timestamp, TimeZone.
Pass an altered Clock object as a dependency
You are using terrible date-time classes that were supplanted years ago by the java.time classes defined by JSR 310.
The java.time.Clock class offers several alternate behaviors suitable for testing. These included a fixed point in time, altered cadences, and and adjustment from the current moment.
Pass one of these Clock objects to the various methods in the java.time classes for your testing purposes.
PST is not a time 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 2-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/Los_Angeles" ) ;
Build up the specific moment you have in mind for your testing.
LocalDate ld = LocalDate.of( 2019 , 2 , 11 ) ;
LocalTime lt = LocalTime.MIN ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
zdt.toString(): 2019-02-11T00:00-08:00[America/Los_Angeles]
Calling Clock.fixed requires an Instant, a moment in UTC. We can adjust from our zoned value to UTC by extracting an Instant. Same moment, same point on the timeline, different wall-clock time.
Instant instant = zdt.toInstant() ;
instant.toString(): 2019-02-11T08:00:00Z
Specify a Clock that forever reports the current moment as that specific moment, without incrementing.
Clock clock = Clock.fixed( instant , z ) ;
clock.toString(): FixedClock[2019-02-11T08:00:00Z,America/Los_Angeles]
Inject the fixed clock as a dependency.
Instant now = Instant.now( clock ) ; // Tell me a lie.
now.toString(): 2019-02-11T08:00:00Z
See this code run live at IdeOne.com.
JDBC 4.2
If you were instantiating java.sql.Timestamp for use with a database, instead use the java.time classes. As of JDBC 4.2, we can exchange java.time objects with a database.
Your JDBC driver might have optional support for Instant.
myPreparedStatement.setObject( … , instant ) ; // Storing data.
Instant instant = myResultSet.get( … , Instant.class ) ; // Retrieving data.
Your driver must support OffsetDateTime.
myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ; // Storing data.
OffsetDateTime odt = myResultSet.get( … , OffsetDateTime.class ) ; // Retrieving data.
Adjust into a time zone.
ZonedDateTime zdt = odt.atZoneSameInstant( 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.
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 have this piece of code
while(activecheck.next()){
Date status;
String vincheck;
Date curr = new Date();
int datecheck;
status = activecheck.getDate(8);
vincheck = activecheck.getString(2);
String update = "UPDATE Auctions SET status = '"+inactive+"' WHERE vin = '"+vincheck+"'";
datecheck = status.compareTo(curr);
if(datecheck < 0){
stmt6.executeUpdate(update);
}
}
Which iterates through a mysql table checking for inactive bids. I am trying to check whether the date and time listed in the sql row has been passed by the current time. However, whenever I do this, it seems to only be comparing the dates, and not the times. What could be the cause of this?
This is the format I am using : yyyy-MM-dd HH:mm:ss`
You should use type which is called Timestamp instead of the date. This way you will cover the date and the current time
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
tl;dr
if(
myResultSet.getObject( … , Instant.class ) // Retrieve `Instant` (a moment in UTC) from database using JDBC 4.2 or later.
.isBefore( Instant.now() ) // Comparing to the current moment captured in UTC.
)
{
…
}
java.util.Date versus java.sql.Date
You may be confusing this pair of unfortunately mis-named classes. The first is a date-with-time type, in UTC. The second is a date-only type. Actually the second pretends to be a date-only type but actually has a time-of-day set to 00:00:00. Even worse, the second inherits from the first, but the documentation instructs us to ignore that fact.
Confusing? Yes. These awful classes are very poorly designed. Avoid them.
java.time
You are using terribly troublesome old date-time classes that were supplanted years ago by the java.time classes.
Instant
The java.util.Date class is replaced by java.time.Instant. 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).
LocalDate
The java.sql.Date class is replaced by java.time.LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time classes with your database. No need to ever use java.sql or java.util date-time types again.
Tip: Make a habit of always using a PreparedStatement to avoid SQL Injection risk. Not really any more work once you get used to it.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
myPreparedStatement.setObject( … , instant ) ;
And retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Smart objects, not dumb strings
This is the format I am using : yyyy-MM-dd HH:mm:ss`
Date-time values stored in a database do not have a “format”. Those values are stored by some internally-defined mechanism that does not concern us. They are not strings (not in any serious database, that is).
Your database, and your Java date-time objects, can parse a string representing a date-time value to create that value. And they can generate a string to represent that value. But the string and the date-time value are distinct and separate, and should not be conflated.
Use java.time objects to exchange date-time values with your database, not mere strings, just as you would for numbers and other data types your database comprehends. Use strings only for communicating textual values.
Compare
To compare your retrieved values against the current moment, use the isBefore, isAfter, and equals methods of Instant class.
Instant now = Instant.now() ;
…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
boolean isPast = instant.isBefore( now ) ;
if ( isPast ) {
…
}
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'm trying to assign a XMLGregorianCalendar date to a java.sql.Timestamp var, like this...
var1.setTimeStamp(Timestamp.valueOf(var2.getXMLGregorianCalendar().toString()))
But apparently, this is not working, and throws an exception...
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
And I've tried this, as well:
var1.setTimeStamp((Timestamp) var2.getXMLGregorianCalendar().getTime())
but...
java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Timestamp
Any ideas..? Thanks!
I've found the answer:
Timestamp timestamp = new Timestamp(var2.getXMLGregorianCalendar().toGregorianCalendar().getTimeInMillis());
var1.setTimeStamp(timestamp);
tl;dr
Try to avoid legacy date-time classes. But if handed a javax.xml.datatype.XMLGregorianCalendar, convert to modern java.time.Instant class. No need to ever use java.sql.Timestamp.
myPreparedStatement.setObject(
… ,
myXMLGregorianCalendar // If forced to work with a `javax.xml.datatype.XMLGregorianCalendar` object rather than a modern java.time class…
.toGregorianCalendar() // …convert to a `java.util.GregorianCalendar`, and then…
.toZonedDateTime() // …convert to modern `java.time.ZonedDateTime` class.
.toInstant() // Adjust to UTC by extracting an `Instant` object.
)
Retrieving from a database, as of JDBC 4.2 and later.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
java.time
FYI, the terribly troublesome old date-time classes have been supplanted by the java.time classes.
javax.xml.datatype.XMLGregorianCalendar is replaced by java.time.ZonedDateTime.
java.util.GregorianCalendar is replaced by java.time.ZonedDateTime. Note new conversions methods added to the old class.
java.sql.Timestamp is replaced by java.time.Instant, both representing a moment in UTC with a resolution of nanoseconds.
Avoid using XMLGregorianCalendar. But if you must interface with old code not yet updated for java.time types, convert. As an intermediate step, convert to GregorianCalendar as seen in the code of your Question.
java.util.GregorianCalendar gc = myXMLGregorianCalendar.toGregorianCalendar() ;
Now use the new convenient conversion method added to the old GregorianCalendar class, to get a modern java.time.ZonedDateTime object.
ZonedDateTime zdt = gc.toZonedDateTime() ; // Convert from legacy class to modern class.
Adjust from that particular time zone to UTC. Extract an Instant object which is a moment always in UTC, by definition.
Instant instant = zdt.toInstant() ; // Adjust from some time zone to UTC.
As of JDBC 4.2, we can directly exchange java.time objects with the database. So no need to ever touch java.sql.Timestamp again.
myPreparedStatement.setObject( … , instant ) ;
Retrieval:
Instant instant = myResultSet.getObject( … , Instant.class ) ;
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.