I know how to retrieve timestamp with milliseconds:
to_char(systimestamp ,'YYYY-MM-DD HH24:MI:SS,FF9')
Can anyone please advise, is the timestamp data type sufficient to store the date with milliseconds or can I use varchar2? I am trying to insert this value from Java.
Yes, TIMESTAMP allows precision down to nanoseconds if you want it.
If you only need milliseconds, you just want a TIMESTAMP(3) column.
Use a java.sql.Timestamp (which again goes down to nanoseconds, if you need it to) on the Java side. Note that you should avoid doing your to_char conversion if possible - perform any string conversions you need client-side; fetch data as a timestamp, and send it as a timestamp.
tl;dr
Use smart objects, not dumb strings. Use java.time for nanosecond resolution.
myResultSet.getObject( … , LocalDateTime.class )
java.time
The Answer by Jon Skeet is correct, but now outdated. The java.sql.Timestamp class is supplanted by the java.time classes such as Instant and LocalDateTime.
The java.time classes have a resolution of nanoseconds, more than enough for your milliseconds.
Oracle database seems to have a TIMESTAMP type that is equivalent to the SQL-standard type TIMESTAMP WITHOUT TIME ZONE. That means it lacks any concept of time zone or offset-from-UTC. For such a column, use LocalDateTime in Java as it too lacks any concept of zone/offset.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
For storing into a field of type similar to SQL-standard TIMESTAMP WITH TIME ZONE where do have respect for zone/offset, use Instant:
Instant instant = Instant.now() ; // Capture current moment as fine as nanoseconds. In practice, we get microseconds in Java 9, but only milliseconds in Java 8.
As of JDBC 4.2 and later, we can directly exchange java.time objects with the database via PreparedStatement.setObject and ResultSet.getObject. So use these smart objects rather than mere strings to communicate date-time values.
The java.time classes generate strings in standard ISO 8601 formats. Just call toString.
String output = instant.toString() ;
String output = ldt.toString() ;
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, 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.
Related
I am developing a hospital management system for an assignment.I want to view patient details and display "not discharged" if the column date_of_discharge is null.I'm using mysql as database.Do I want to convert sql date to java util date before checking it null?
NULL is nothing
Do I want to convert … before checking it null?
No.
As others commented, NULL means “nothing at all”. A NULL is the same across all data types. So no need to convert, cast, or parse when simply asking if the value is NULL or not.
Instead of checking not null,can I directly check whether it is null
Yes. Use IS NULL or IS NOT NULL.
SELECT * FROM patient WHERE date_of_discharge IS NULL ;
…or…
SELECT * FROM patient WHERE date_of_discharge IS NOT NULL ;
Avoid NULLs
display "not discharged" if the column date_of_discharge is null.
Following Dr. Chris Date’s advice, I avoid using NULL wherever possible, as if it were the work of the devil (which it may be!).
Instead, assign a certain value of your own arbitrary choosing to signify no-value-yet-assigned. Perhaps the epoch reference date of Unix time and other systems: the first moment of 1970 in UTC, 1970-01-01T00:00Z.
In Java, we have available as pre-defined constants: LocalDate.EPOCH and Instant.EPOCH.
Never cast between java.util.Date & java.sql.Date
convert sql date to java util date before checking it null
No, never cast between these types. You should ignore the fact that java.sql.Date inherits from java.util.Date. By inheriting, the java.sql.Date actually carries a time-of-day. Yet java.sql.Date portrays itself as representing a date-only value without time-of-day and without time zone — but this is only a pretense. As a workaround, to fulfill that pretense, that time-of-day is set to midnight of some time zone. But the java.util.Date always represents a moment in UTC. So by casting, you will inadvertently be mixing in the effect of some time zone.
Confusing? Yes. This is a terribly bad design, an awful hack, and is one of many reasons to avoid these old legacy date-time classes. Use java.time classes instead.
JDBC 4.2
As of JDBC 4.2 we can directly exchange java.time objects with the database. Use PreparedStatement::setObject and ResultSet::getObject methods.
The java.sql.Date class that pretends to hold a date-only value is supplanted by the java.time.LocalDate. The LocalDate class actually does hold only a date, without a time-of-day and without a time zone.
LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;
…and…
myPreparedStatement.setObject( … , localDate ) ;
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 for example 30 users and for everyone i want to set vacation with random start_day and random end_day of vacation. I want to use Date, not LocalDate. If i must do with LocalDate this is the answer.
LocalDate date = LocalDate.now();
List<VacationUser> collectVacationUser = allVacationUsers.stream()
.map(user -> {
if (inVacation()) {
return new VacationUser(date.minusDays(ThreadLocalRandom.current().nextInt(1, 5)),
date.plusDays(ThreadLocalRandom.current().nextInt(1, 5)));
} else {
return new VacationUser(user.getPrimaryEmail());
}
}).collect(toList());
return collectVacationUser;
}
I want to do this with Date, because in JSON date format with 'Date' is this "yyyy/mm/dd", in the other hand if I use LocalDate a format in JSON is something like this
"year":2018,"month":"AUGUST","era":"CE","dayOfMonth":16,"dayOfWeek":"THURSDAY","dayOfYear":228,"leapYear":false,"monthValue":8,"chronology":{"id":"ISO","calendarType":"iso8601"
tl;dr
Use types appropriate to your values: LocalDate
Never use the terrible legacy class java.util.Date
Learn to use converters/adapters in your Java⇔JSON serialization framework
Use standard ISO 8601 formats for date-time values whenever possible
Details
Use appropriate types to represent your data values. For a date-only value, without a time-of-day and without a time zone, the appropriate type is LocalDate.
Never use java.util.Date. That terrible class was supplanted years ago by the java.time classes.
As for generating textual representations in JSON, that is an entirely separate issue.
JSON has very few data types and none of them are date-time related. So whatever JSON output you are getting for your LocalDate input is a function of your particular Java-to-JSON library you are using. You do not divulge what library, so we cannot provide further assistance.
I can tell you that there is an established practical international standard for representing date-time values: ISO 8601. I strongly suggest always using these standard formats when serializing your date-time values to text.
For a date-only value, the standard format is YYYY-MM-DD such as 2018-01-23.
The java.time classes use these standard formats by default when parsing/generating strings.
LocalDate.parse( "2018-01-23" ) ;
And:
myLocalDate.toString()
2018-01-23
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
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 am trying to get current time in other time zone. I used this code for this:
GregorianCalendar calender = new
GregorianCalendar(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println(calender.getTime());
But, when I am running this code, this code provides the current time in CET as the time in my local machine is in CET.
I am confused. Then why there is scope to provide a TimeZone in constructor?
Ahh, the joys of the Java Date/Time API ...
What you want (aside from a better API, such as Joda Time) is a DateFormat. It can print dates in a time zone you specify. You don't need Calendar for that.
dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
dateFormat.format(new Date());
Calendar is for time manipulations and calculations. For example "set the time to 10 AM". Then it needs the timezone.
When you are done with these calculations, then you can get the result by calling calendar.getTime() which returns a Date.
A Date is essentially a universal timestamp (in milliseconds since 1970, with no timezone information attached or relevant). If you call toString on a Date it will just print something in your default timezone. For more control, use DateFormat.
What you are doing right now is:
Getting a calendar in Bangkok time zone
get the Date object for this time( which is in ms since some date January 1, 1970, 00:00:00 GMT)
print out this Date in your timezone (Date.toString())
You should use a Formatter class to get the result you want. e.g. SimpleDateFormat
An alternative solution would be to use a less confusing Date/Time library. e.g. JodaTime or the new java.time package of Java8
tl;dr
ZonedDateTime.now( ZoneId.of( "Asia/Bangkok" ) )
java.time
The legacy date-time classes you are using are simply terrible, flawed in design and in implementation, built by people who did not understand date-time handling. Avoid those classes entirely.
Use only the modern java.time classes defined in JSR 310.
ZoneId z = ZoneId.of( "Asia/Bangkok" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Generate text in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.
String output = zdt.toString() ;
For other formats, use DateTimeFormatter as seen on hundreds of other Questions and Answers.
See this code run live at IdeOne.com.
2020-02-15T12:27:31.118127+07:00[Asia/Bangkok]
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'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.
I am in need of a method to convert GregorianCalendar Object to Unix Time (i.e. a long). Also need a method to convert Unix Time (long) back to GregorianCalendar Object. Are there any methods out there that does this? If not, then how can I do it? Any help would be highly appreciated.
Link to GregorianCalendar Class --> http://download.oracle.com/javase/1.4.2/docs/api/java/util/GregorianCalendar.html
Thanks.
The methods getTimeInMillis() and setTimeInMillis(long) will let you get and set the time in milliseconds, which is the unix time multiplied by 1000. You will have to adjust manually since unix time does not include milliseconds - only seconds.
long unixTime = gregCal.getTimeInMillis() / 1000;
gregCal.setTimeInMillis(unixTime * 1000);
Aside: If you use dates a lot in your application, especially if you are converting dates or using multiple time zones, I would highly recommend using the JodaTime library. It is very complete and quite a bit more natural to understand than the Calendar system that comes with Java.
I believe that GregorianCalendar.getTimeInMillis() and GregorianCalendar.SetTimeInMillis() will let you get and set long values the way you want.
Check out the setTimeInMillis and getTimeInMillis functions: http://download.oracle.com/javase/6/docs/api/java/util/Calendar.html#getTimeInMillis()
Calendar.getTimeInMillis() should be what you're looking for.
tl;dr
myGregCal.toZonedDateTime().toEpochSecond() // Convert from troublesome legacy `GregorianCalendar` to modern `ZonedDateTime`.
And going the other direction…
GregorianCalendar.from( // Convert from modern `ZonedDateTime` to troublesome legacy class `GregorianCalendar`.
Instant.ofEpochSecond( yourCountOfWholeSecondsSinceEpoch ) // Moment in UTC.
.atZone( // Apply `ZoneId` to `Instant` to produce a `ZonedDateTime` object.
ZoneId.of( "Africa/Tunis" )
)
)
Avoid legacy date-time classes
The other Answers are correct and short. But, FYI, the troublesome old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat are now legacy, supplanted by the java.time classes built into Java 8 & Java 9.
So here is how to convert and use the modern classes instead for your problem.
java.time
Convert from the legacy class GregorianCalendar to the modern class ZonedDateTime. Call new methods added to the old classes.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
And going the other direction…
GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;
If by “Unix time” you meant a count of whole seconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00:00Z, then call toEpochSecond.
long secondsSinceEpoch = zdt.toEpochSecond() ;
If you meant a count of milliseconds since 1970 started in UTC, then extract an 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).
Instant instant = zdt.toInstant() ;
Now ask for the count of milliseconds.
long millisecondsSinceEpoch = instant.toEpochMill() ;
Keep in mind that asking for either whole seconds or milliseconds may involve data loss. The ZonedDateTime and Instant both resolve to nanoseconds. So any microseconds or nanoseconds that may be present will be ignored as you count your whole seconds or milliseconds.
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.