java sql time stamp in UTC 0 date part coming wrong - java

I am using following code for getting current system time which needed to be passed to some sql queries
java.util.Date date = new java.util.Date();
long t = date.getTime();
java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(t);
log.info("Current Time:" + sqlTimestamp.toString());
Now i also needed to get UTC 0 time (not GMT 0)
log.info("Current Time:" + sqlTimestamp.toString());
Current Time:2019-01-04 15:04:50.735
I am trying following code but it looks like not getting date part correctly
log.info("Current UTC Time:" + new java.sql.Timestamp(Instant.now().atOffset( ZoneOffset.UTC ).toEpochSecond()).toString());
Current UTC Time:1970-01-19 02:36:36.299
Please let me know what correction i needed

tl;dr
Use the modern java.time classes instead.
Instant
.now()
.toString()
2019-01-23T01:23:45.123456789Z
java.time
You are using terrible old date-time classes that were supplanted years ago entirely by the java.time classes.
Capture the current moment.
Instant instant = Instant.now() ;
Generate text to represent that moment in standard ISO 8601 format.
String output = instant.toString() ;
If the T in the middle bothers you, replace it. But I encourage you to stick with the strict ISO 8601 format for logging.
String outputModified = output.replace( "T" , " " ) ;
get UTC 0 time (not GMT 0)
UTC is the same thing as GMT, practically speaking, for common business-oriented apps.

You are using toEpochSecond() instead toEpochMilli()
Javadoc for your Timestamp constructor
Timestamp(long time) Constructs a Timestamp object using a milliseconds time value.
So you can use Instant.now().toEpochMilli() as Instant.now() will return you Instant in UTC
(And of course, avoid using old date API if possible, use new date API from JDK8)

Why can't you use DateTimeFormatter
sqlTimestamp.toInstant().atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS"))

First avoid the classes Date and Timestamp. Instead of Timestamp pass a modern type from java.time to your SQL query. Depending on the details of your JDBC driver and the requirements of your query use either Instant, OffsetDateTime with an offset of UTC (zero) or LocalDateTime.
The Date and Timestamp classes have design issues and are long outdated. The Timestamp class can be very confusing, and there doesn’t seem to be agreement whether to interpret it as a timestamp (as the name says) or as a date and time of day. Fortunately since JDBC 4.2 you don’t need Timestamp anymore.
For example:
OffsetDateTime currentUtcTime = OffsetDateTime.now(ZoneOffset.UTC);
PreparedStatement ps = con.prepareStatement(
"select col1 from your_table where your_timestamp > ?;");
ps.setObject(1, currentUtcTime);
ResultSet rs = ps.executeQuery();

Related

Convert BigInt date into a Date

So Our database has a column BigInt REVISIONTS used as part of java Hibernate Envers
It initially contained timestamps from Java Date.
E.g) ts=1561637560383
I used to convert to Date using new Date(ts)
But since Date cannot contain timezones and we needed UTC date, we had to store UTC directly as BigInt and applied a fix suggested by hibernate. Because of this now our timestamps are like this
E.g) ts=20190827202449 now this is not a timestamp anymore but an actual UTC LocaleDateTime stored as bigint
Now querying this i get long and if I use new Date(ts) i am getting incorrect date of course since this is not a timestamp but Hibernate Date with Temporal.Timestamp stored the UTC as is.
I am thinking of converting Long to string and use formatting to convert back when retrieving.
Are there any other cleaner method of converting ?
UTC fix for Envers
How to save UTC (instead of local) timestamps for Hibernate Envers revision info?
You shouldn't be using Date at all. Never. Ever.
I think storing the time as a Unix Timestamp is pretty fine. They're always in UTC and represent a unique instant on the timeline.
Envers supports both Date and Long/long to be defined as revision timestamp. You should use Long.
Formatting it using a timezone or timezone offset can be easily done with the newer Java Date and Time API available in the java.time package.
With Instant.ofEpochSecond(yourTimestamp) you can create an Instant. With atOffset or atZone you can combine the bare timestamp with a certain timezone or timezone offset.
Your Question is quite unclear. But this might help.
Avoid legacy date-time classes
to convert to Date using new Date(ts)
Never use java.util.Date. That terrible class was supplanted years ago by the java.time classes, specifically by Instant.
Instant
E.g) ts=1561637560383
You are not clear about exactly what that value represents. I will guess it is a count of milliseconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z.
long count = 1_561_637_560_383L ;
If that is a textual value, parse using Long class.
long count = Long.parseLong( "1561637560383" ) ;
Instant instant = Instant.ofEpochMilli( count ) ;
See this code run live at IdeOne.com.
instant.toString(): 2019-06-27T12:12:40.383Z
Tip: In your database, store date-time values using date-time data type.
If your database is too primitive to support date-time types, store as text in UTC using ISO 8601 format.
String output = instant.toString() ; // Ex: 2019-06-27T12:12:40.383Z
…and…
Instant instant = Instant.parse( "2019-06-27T12:12:40.383Z" ) ;
Get count of milliseconds since epoch reference.
long count = instant.toEpochMilli() ;
Convert
When you must use Date to interoperate with old code not yet updated to java.time, convert. Call new to…/from… methods added to the old classes.
java.util.Date d = Date.from( instant ) ;
Instant instant = d.toInstant() ;

Converting java.sql.Timestamp to Instant Time

From my database i retrieve value as :
20-DEC-17 10.15.53.000000000 AM
I want above java.sql.Timestamp to be converted to Instant time as :
2017-12-20T10:15:53Z
I tried following with current time stamp
Timestamp ts2 = new Timestamp(date1.getTime());
Date tradeDate1=new Date(ts2.getTime());
Instant tradeInstant = tradeDate1.toInstant();
System.out.println("Tade Instant"+ tradeInstant);
Actual time stamp: Fri Jun 22 16:07:35 IST 2018
What is prints in instan : Tade Instant2018-06-22T10:37:35.420Z
The hours/mins/seconds are updated which I dont want - is there a way this can be retained as is?
I am assuming that you are using at least Java 8 and at least JDBC 4.2. I am further assuming that the timestamp doesn’t have time zone or offset information in the database, but is to be understood as a timestamp in UTC (which is a recommended practice). In this case I would consider it safest to add the information about UTC offset explicitly in Java:
PreparedStatement yourPreparedStatement
= yourConnection.prepareStatement("select trade_timestamp from your_table");
ResultSet rs = yourPreparedStatement.executeQuery();
while (rs.next()) {
LocalDateTime tradeDateTime = rs.getObject(1, LocalDateTime.class);
Instant tradeInstant = tradeDateTime.atOffset(ZoneOffset.UTC).toInstant();
System.out.println("Trade Instant: " + tradeInstant);
}
Note that the code avoids the outdated Timestamp class completely. A LocalDateTime is a date and time of day without time zone or offset. If your database datatype had been timestamp with time zone, you could have passed either Instant.class or OffsetDateTime.class to rs.getObject and have got an Instant or an OffsetDateTime back. JDBC 4.2 only specifies support for OffsetDateTime, but many drivers support Instant too. Obviously with Instant you need no further conversion. With OffsetDateTime do
Instant tradeInstant = tradeDateTime.toInstant();
Depending on your database and its capabilities it is also possible that you can set UTC as offset/time zone on the database session so you can get the correct instant even from timestamp without time zone.
Discussion: Arvind Kumar Avinash in a comment recommends that one should rely only on the types officially supported by JDBC 4.2, that is, LocalDateTime and OffsetDateTime for our purposes. The types are mentioned at the bottom of the article Why do we need a new date and time library? on Oracle’s web site, there’s a link at the bottom. Arvind Kumar Avinash further refers us to PSQLException: Can't infer the SQL type to use for an instance of java.time.Instant, also linked to at the bottom. Since comments are fragile, I wanted to include the essence here in the answer.
What went wrong in your code?
It seems your database session understood the timestamp as a date and time in your local time zone (IST, I assume it’s for India Standard Time (other interpretations exist)). According to Mark Rotteveel’s informative comment this behaviour is required by JDBC, but it doesn’t agree with your need when the value is in UTC. Therefore it gave you the wrong point in time, though it looked right when you printed it. The conversion in itself was correct.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Why do we need a new date and time library?
PSQLException: Can't infer the SQL type to use for an instance of java.time.Instant. on doobie’s GitHub page (doobie is a JDBC layer for Scala)
Building from the comment about not using SimpleDateFormat, I have moved to DateTimeFormatter:
Date today = new Date();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss") // same format
.withLocale(Locale.UK) // UK locale
.withZone(ZoneId.systemDefault());
String output = dateTimeFormatter.format( today.toInstant() );
System.out.println( output );
Running gives you:
2018-06-22T14:14:26
I have created a SimpleDateFormat, which only prints "up to seconds":
/* simple date format */
DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
/* get toInstant() and convert to date */
Date myDate = Date.from(today.toInstant());
/* myDate formatted using DATE_FORMAT */
String formattedDate = DATE_FORMAT.format(myDate);
System.out.println(formattedDate);

ISO 8601 datetime now

I need exactly that format in java which in C# is
DateTime.Now.ToString("o"). Sample returned date for DateTime.Now.ToString("o") is
2016-03-10T11:24:59.7862749+04:00
and then in sql it's inserted as
2016-03-10 11:24:59.786
I'm trying to insert same date format from java. I use that:
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
and it returns this
2016-03-10T07:29+0000
Because of that format then it goes in error. How can I change format to be exactly which I want?
For Java 7 you can use:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
System.out.println(df.format(new Date()));
This uses the pattern symbol XXX which will print the colon inside the offset, too. However, for Java-6 this feature is not offered. And the precision is always constrained to milliseconds.
For Java-8, you can also use:
DateTimeFormatter dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
System.out.println(OffsetDateTime.now().format(dtf)); // 2016-03-10T08:46:44.849+01:00
This enables nanosecond precision if such a clock is available (starting with Java-9).
For Java-6 either apply a hack based on SimpleDateFormat or use external libraries:
// Java-6 (SimpleDateFormat)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String text = sdf.format(new Date());
text = text.substring(0, text.length() - 2) + ":" + text.substring(text.length() - 2);
System.out.println(text);
// Joda-Time
DateTime now = DateTime.now();
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").print(now));
// Time4J
Moment now = SystemClock.currentMoment();
System.out.println(Iso8601Format.EXTENDED_DATE_TIME_OFFSET.withStdTimezone().format(now));
The Answer by Meno Hochschild is correct. I'll just add some more comments and some SQL-specific code.
Avoid Old Date-Time Classes
The old date-time classes, java.util.Date/.Calendar & java.text.SimpleDateFormat, are poorly designed, confusing, and troublesome. Avoid them.
The old clases have been supplanted by the java.time framework built into Java 8 and later.
For use before Java 8, check out the ThreeTen-Backport project.
Nanoseconds
The java.time classes have nanosecond resolution. So you will not have the problem of data loss where 2016-03-10T11:24:59.7862749+04:00 gets truncated to 2016-03-10 11:24:59.786 because of millisecond resolution used by the old classes.
Getting the current moment in Java 8 is limited to milliseconds, three digits of decimal fraction of second, due to legacy issue. Java 9 will get the current moment in nanoseconds, up to nine digits of decimal fraction (provided your computer’s hardware clock can provide such fine resolution).
ISO 8601
The ISO 8601 standard defines sensible text formats for date-time values. For example, 2016-03-09T23:24:33Z or 2016-03-09T22:24:33-01:00. The java.time classes use these by default, so no need to define parsing patterns.
Instant
An Instant is a moment on the timeline in UTC.
Instant instant = Instant.now();
Call Instant::toString to generate a string in standard format.
String output = instant.toString();
2016-03-09T23:24:33.123Z
OffsetDateTime
Apply a ZoneOffset to get an OffsetDateTime.
ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes( -5 , 30 );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
If you know the full time zone rather than just the offset-from-UTC, apply a ZoneId to get a ZonedDateTime.
Use proper time zone names.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ); // "Europe/Paris", "America/Montreal", etc.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
java.sql.Timestamp
Hopefully the JDBC drivers will be updated to directly use the java.time types. Until then we convert to java.sql types for transferring data in/out of database.
As noted above, java.time can handle nanoseconds. So does java.sql.Timestamp. But your database may not. Some databases are limited to whole seconds, milliseconds, or microseconds. When data is passed via JDBC to the database, the database may truncate.
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
…and going the other direction…
Instant instant = ts.toInstant();
Note that an Instant is always in UTC by definition. So no need to perform the kind of code attempted at the end of the Question.
Work Flow
You should minimize your use of strings when working with date-time. Maximize your use of helpful date-time classes/objects, namely java.time classes. Stop thinking of strings as date-time values -- they are a textual representation of a date-time value.
Do not insert/retrieve date-time values to/from your database as strings. Use the java.sql objects such as java.sql.Timestamp and java.sql.Date. Use PreparedStatement and the "set/get" methods such as setTimestamp/getTimestamp. And virtually always define your columns in database as TIMESTAMP WITH TIME ZONE rather than “without time zone”.
When getting data from database, use the java.sql types. But as soon as is possible, convert to java.time types. The java.sql types are a mess, a dirty hack, and should be used only for data transfer not business logic.
Generally best to use UTC in your business logic, data storage, data exchange, API calls, and so on. Adjust into a time zone only when expected by a user or required by a data sink.
use this format "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
Example:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
System.out.println(df.format(new Date()));

Convert UTC date into milliseconds

I am not interested in what the current UTC time is in milliseconds, nor do I need to mess with timezones. My original date is already stored as a UTC timestamp.
I have a date stored in a database in UTC time, "2012-06-14 05:01:25".
I am not interested in the datetime, but just the date portion of the it. So, after retrieving the date in Java, and excluding the hours, minutes, and seconds - I am left with "2012-06-14".
How can I convert this into UTC milliseconds?
EDIT: I'd missed the "ignoring the time of day" part. It's now present, but near the end...
The simplest approach is probably to use SimpleDateFormat, having set the time zone appropriately:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = format.parse(text);
long millis = date.getTime();
(Setting the time zone is the important bit here, as otherwise it will interpret the value to be in the local time zone.)
Alternatively, if you're doing anything less trivial than this, use Joda Time which is a much better date/time API. In particular, SimpleDateFormat isn't thread-safe whereas DateTimeFormatter is:
// This can be reused freely across threads after construction.
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withLocale(Locale.US)
.withZoneUTC();
// Option 1
DateTime datetime = formatter.parseDateTime(text);
long millis = dateTime.getMillis();
// Option 2, more direct, but harder to diagnose errors
long millis = formatter.parseMillis(text);
Now so far, we've parsed the whole whole caboodle. The easiest way of ignoring the date part is just to round it off - after all, Java doesn't observe leap seconds, so we can just truncate it:
long millisPerDay = 24L * 60L * 60L * 1000L; // Or use TimeUnit
long dayMillis = (millis / millisPerDay) * millisPerDay;
That will "round towards 1970" so if you have a date before 1970 it will round to the end of the day - but I suspect that's unlikely to be a problem.
With the Joda Time version you could just use this instead:
DateTime dateTime = formatter.parseDateTime(text);
long millis = dateTime.toLocalDate().getLocalMillis();
I would personally not go with the idea of just taking a substring. Even though you're not actually interested in preserving the hour/minute/second, I think it's appropriate to parse what you've been given and then throw away information. Aside from anything else, it makes your code fail appropriately with bad data, e.g.
"2012-06-100"
or
"2012-06-14 25:01:25"
indicate problems in whatever's supplying you data, and it's good to spot that rather than to continue blindly just because the first 10 characters are okay.
UPDATE: See the modern solution using java.time classes in the correct Answer by Ole V.V..
Simpler
The answer by Jon Skeet is correct. And he makes a good point about including, rather than truncating, the time-of-day info while parsing.
However, his code could be simplified. Especially so because Joda-Time gained an important new method in the latest versions: withTimeAtStartOfDay. This method supplants all the "midnight"-related classes and methods which are now deprecated.
Specifying a Locale is a good habit, as shown in his code. But in this particular case a Locale is not necessary.
His answer correctly suggests the Joda-Time library, far superior to using java.util.Date, .Calendar, and java.text.SimpleTextFormat. Those classes are notoriously troublesome, and should be avoided. Instead use either Joda-Time or the new java.time package built into Java 8 (inspired by Joda-Time, defined by JSR 310).
First Moment Of The Day
You cannot ignore time-of-day if what you want is a count of milliseconds-since-epoch. I suspect what you want is to change the time to first moment of the day. In UTC, this always means the time 00:00:00.000. But note that in local time zones, the first moment may be a different time because of Daylight Saving Time and possibly other anomalies.
ISO 8601
Your string is nearly in standard ISO 8601 format, but we need to swap a T for the SPACE in the middle. Then we can feed the resulting string directly to Joda-Time as Joda-Time has built-in formatters used by default for standard strings.
Example Code
The following example code assumes the intent of your question is to parse a string as a date-time value in UTC time zone, adjust the time to the first moment of the day, and then convert to number of milliseconds since Unix epoch (beginning of 1970 in UTC).
String inputRaw = "2012-06-14 05:01:25";
String input = inputRaw.replace( " ", "T" ); // Replace SPACE with a 'T'.
DateTime dateTime = new DateTime( input, DateTimeZone.UTC ); // Parse, assuming UTC.
DateTime dateTimeTopOfTheDay = dateTime.withTimeAtStartOfDay(); // Adjust to first moment of the day.
long millisecondsSinceUnixEpoch = dateTimeTopOfTheDay.getMillis(); // Convert to millis. Use a 'long', not an 'int'.
java.time and JDBC 4.2
I am providing the modern answer. These days (and for the last several years) you should use java.time, the modern Java date and time API, for your date and time work. And since JDBC 4.2 you can directly retrieve java.time objects from your database (and also store them into it). A modern JPA implementation (Hibernate at least since Hibernate 5) will be happy to do the same. So forget about SimpleDateFormat, Date and other old classes used in most of the old answers. The mentioned ones are poorly designed, and java.time is so much nicer to work with.
Retrieve proper date-time objects from your database
I also recommend that you don’t retrieve your UTC time as a string from the database. If the datatype in SQL is timestamp with time zone (recommended for UTC times), retrieve an OffsetDateTime. For example:
PreparedStatement pStmt = yourDatabaseConnection
.prepareStatement("select utc_time from your_table where id = 7;");
ResultSet rs = pStmt.executeQuery();
if (rs.next()) {
OffsetDateTime utcDateTime = rs.getObject("utc_time", OffsetDateTime.class);
long millisecondsSinceEpoch = utcDateTime.truncatedTo(ChronoUnit.DAYS)
.toInstant()
.toEpochMilli();
System.out.println("Milliseconds since the epoch: " + millisecondsSinceEpoch);
}
If the type in SQL is dateTime or timestamp without time zone, we probably need to retrieve a LocalDateTime instead (details depending on your JDBC driver and the time zone of your database session). It goes in the same manner. For converting your LocalDateTime to OffsetDateTime, see the conversion below.
If you need to convert from a string
If you cannot avoid getting your UTC time as a string as in the question, parse it into a LocalDateTime and convert from there. For example:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String utcTimeString = "2012-06-14 05:01:25";
long millisecondsSinceEpoch = LocalDateTime.parse(utcTimeString, formatter)
.atOffset(ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
System.out.println("Milliseconds since the epoch: " + millisecondsSinceEpoch);
Output:
Milliseconds since the epoch: 1339650085000
Link
Oracle tutorial: Date Time explaining how to use java.time.
Use the Date object in combination with SimpleDateFormat.
There is a method named getTime() in Date which will return the milliseconds for you.
Example that solves your problem :
Date truc = new SimpleDateFormat( "y-m-d").parse( "2010-06-14");
System.out.println(truc.getTime());
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); //or whatever format you have
Date t = ft.parse('2014-03-20');
String result = String.format("%tQ", t);
System.out.printf("%tQ", t);
There are two methods here:
you put the result milliseconds into a variable result
printing it straight off.
I use a simple and straight forward approach:
Date date = new Date(utcDateInString);
long utcDateInMilliSeconds = date.getTime();

How to convert TimeStamp to Date in Java?

How do I convert 'timeStamp' to date after I get the count in Java?
My current code is as follows:
public class GetCurrentDateTime {
public int data() {
int count = 0;
java.sql.Timestamp timeStamp = new Timestamp(System.currentTimeMillis());
java.sql.Date date = new java.sql.Date(timeStamp.getTime());
System.out.println(date);
//count++;
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/pro", "root", "");
PreparedStatement statement = con.prepareStatement("select * from orders where status='Q' AND date=CURDATE()");
ResultSet result = statement.executeQuery();
while (result.next()) {
// Do something with the row returned.
count++; //if the first col is a count.
}
} catch (Exception exc) {
System.out.println(exc.getMessage());
}
return count;
}
}
This is my database:
Here the output I got was 2012-08-07 0, but the equivalent query returns 3. Why do I get 0?
Just make a new Date object with the stamp's getTime() value as a parameter.
Here's an example (I use an example timestamp of the current time):
Timestamp stamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(stamp.getTime());
System.out.println(date);
// timestamp to Date
long timestamp = 5607059900000; //Example -> in ms
Date d = new Date(timestamp );
// Date to timestamp
long timestamp = d.getTime();
//If you want the current timestamp :
Calendar c = Calendar.getInstance();
long timestamp = c.getTimeInMillis();
Just:
Timestamp timestamp = new Timestamp(long);
Date date = new Date(timestamp.getTime());
I have been looking for this since a long time, turns out that Eposh converter does it easily:
long epoch = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000;
Or the opposite:
String date = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new java.util.Date (epoch*1000));
tl;dr
LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
.toEpochSecond()
…
LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
.plusDays( 1 )
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
.toEpochSecond()
…
"SELECT * FROM orders WHERE placed >= ? AND placed < ? ; "
…
myPreparedStatement.setObject( 1 , start )
myPreparedStatement.setObject( 2 , stop )
java.time
You are using troublesome old date-time classes that are now legacy, supplanted by the modern java.time classes.
Apparently you are storing a moment in your database in a column of some integer type. That is unfortunate. You should instead be using a column of a type such as the SQL-standard TIMESTAMP WITH TIME ZONE. But, for this Answer, we will work with what we have.
If your records represent moments with a resolution of milliseconds, and you want all the records for an entire day, then we need a time range. We must have a start moment and a stop moment. Your query has only a single date-time criterion where it should have had a pair.
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
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 today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
With a LocalDate in hand, we next need to transform that into a pair of moment, the start and stop of the day. Do not assume the day starts at 00:00:00 time-of-day. Because of anomalies such as Daylight Saving Time (DST), the day may start at another time such as 01:00:00. So let java.time determine the first moment of the day. We pass a ZoneId argument to LocalDate::atStartOfDay to look up any such anomalies. The result is a ZonedDateTime.
ZonedDateTime zdtStart = ld.atStartOfDay( z ) ;
Generally the best approach to defining a span of time is the Half-Open approach where the beginning is inclusive while the ending is exclusive. So a day starts with its first moment and runs up to, but not including, the first moment of the next day.
ZonedDateTime zdtStop = ld.plusDays( 1 ).atStartOfDay( z ) ; // Determine the following date, and ask for the first moment of that day.
Our query for an entire day cannot make use of SQL command BETWEEN. That command is Fully-Closed ([]) (both beginning and ending are inclusive) where as we want Half-Open ([)). We use a pair of criteria >= and <.
Your column is poorly named. Avoid any of the thousand words reserved by various databases. Let’s use placed in this example.
Your code should have used ? placeholders in which to specify our moments.
String sql = "SELECT * FROM orders WHERE placed >= ? AND placed < ? ; " ;
But we have ZonedDateTime objects in hand, while your database apparently is storing integers as discussed above. If you had defined your column properly we could simply pass the ZonedDateTime objects with any JDBC driver supporting JDBC 4.2 or later.
But instead we need to get a count-from-epoch in whole seconds. I will assume your epoch reference date is the first moment of 1970 in UTC. Beware of possible data loss, as the ZonedDateTime class is capable of nanosecond resolution. Any fractional second will be truncated in the following lines.
long start = zdtStart().toEpochSecond() ; // Transform to a count of whole seconds since 1970-01-01T00:00:00Z.
long stop = zdtStop().toEpochSecond() ;
Now we are ready to pass those integers to our SQL code defined above.
PreparedStatement ps = con.prepareStatement( sql );
ps.setObject( 1 , start ) ;
ps.setObject( 2 , stop ) ;
ResultSet rs = ps.executeQuery();
When you retrieve your integer values from the ResultSet, you can transform into Instant objects (always in UTC), or into ZonedDateTime objects (with an assigned time zone).
Instant instant = rs.getObject( … , Instant.class ) ;
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
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.
try to use this java code :
Timestamp stamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(stamp.getTime());
DateFormat f = new SimpleDateFormat("yyyy-MM-dd");
DateFormat f1 = new SimpleDateFormat("yyyy/MM/dd");
String d = f.format(date);
String d1 = f1.format(date);
System.out.println(d);
System.out.println(d1);
First of all, you're not leveraging the advantage of using a PreparedStatement. I would first suggest that you modify your PreparedStatement as follows:
PreparedStatement statement = con.prepareStatement("select * from orders where status=? AND date=?")
You can then use statement.setXX(param_index, param_value) to set the respective values. For conversion to timestamp, have a look at the following javadocs:
PreparedStatement.setTimeStamp()
Timestamp
Hope this helps!
In Android its very Simple .Just use the Calender class to get currentTimeMillis.
Timestamp stamp = new Timestamp(Calendar.getInstance().getTimeInMillis());
Date date = new Date(stamp.getTime());
Log.d("Current date Time is " +date.toString());
In Java just Use System.currentTimeMillis() to get current timestamp
Not sure what you're trying to select in the query, but keep in mind that UNIX_TIMESTAMP() without arguments returns the time now. You should probably provide a valid time as argument, or change the condition.
EDIT:
Here is an example of a time bound query based on the question:
PreparedStatement statement = con
.prepareStatement("select * from orders where status='Q' AND date > ?");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2000");
statement.setDate(1, new java.sql.Date(date.getTime()));
EDIT: timestamp column
In case of timestamp use java.sql.Timestamp and PreparedStatement.setTimestamp(), ie:
PreparedStatement statement = con
.prepareStatement("select * from orders where status='Q' AND date > ?");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2000");
Timestamp timestamp = new Timestamp(date.getTime());
statement.setTimestamp(1, timestamp);
new Date(timestamp.getTime()) should work, but the new fancy Java 8 way (which may be more elegant and more type safe, as well as help lead you to use the new time classes) is to call Date.from(timestamp.toInstant()).
(Do not rely on the fact that Timestamp itself is an instance of Date; see explanation in the comments of another answer .)
Timestamp tsp = new Timestamp(System.currentTimeMillis());
java.util.Date dateformat = new java.util.Date(tsp.getTime());
I feel obliged to respond since other answers seem to be time zone agnostic which a real world application cannot afford to be. To make timestamp-to-date conversion correct when the timestamp and the JVM are using different time zones you can use Joda Time's LocalDateTime (or LocalDateTime in Java8) like this:
Timestamp timestamp = resultSet.getTimestamp("time_column");
LocalDateTime localDateTime = new LocalDateTime(timestamp);
Date trueDate = localDateTime.toDate(DateTimeZone.UTC.toTimeZone());
The example below assumes that the timestamp is UTC (as is usually the case with databases). In case your timestamps are in different timezone, change the timezone parameter of the toDatestatement.
Assuming you have a pre-existing java.util.Date date:
Timestamp timestamp = new Timestamp(long);
date.setTime( l_timestamp.getTime() );
You can use this method to get Date from Timestamp and Time-zone of particular area.
public String getDayOfTimestamp(long yourLinuxTimestamp, String timeZone) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(yourLinuxTimestamp * 1000);
cal.setTimeZone(TimeZone.getTimeZone(timeZone));
Date date = cal.getTime();
}
String timestamp="";
Date temp=null;
try {
temp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(getDateCurrentTimeZone(Long.parseLong(timestamp)));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int dayMonth=temp.getDate();
int dayWeek=temp.getDay();
int hour=temp.getHours();
int minute=temp.getMinutes();
int month=temp.getMonth()+1;
int year=temp.getYear()+1900;
import java.sql.Timestamp
new Timestamp(1234567890123L)
// java.sql.Timestamp = 2009-02-14 10:31:30.123
(new Timestamp(1234567890123L)).toLocalDateTime().toLocalDate().toString()
// 2009-02-14
What is a different result from one of the previous most voted answers:
import java.time.format.DateTimeFormatter
import java.time.ZoneId
import java.time.ZoneOffset
(DateTimeFormatter.ISO_LOCAL_DATE).withZone(ZoneId.from(ZoneOffset.UTC)).format(new Timestamp(1234567890123L).toInstant())
// String = 2009-02-13
In my case, I was expecting the "2009-02-14" instead of the "2009-02-13". So the top result worked better for me.
Date updated = timestamp.toDate();
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
Date fecha = getDateInTimestamp();

Categories