SimpleDateFormat not parsing milliseconds and MySql is rounding Date - java

I'm using SimpleDateFormat to parse string to Date.
After the parse, I'm loading this date to mysql. The problem is that milliseconds is not being parsed to Date and when I insert the object on Mysql its getting rounded.
myStringDate = "2018-02-02 23:59:59.700"
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.SSS");
myObject.setDate(fmt.parse(myStringDate );
When I debug the code I can see the Date as Sun Feb 02 23:59:59 BRST 2018 (its not storing milliseconds)
The data is stored on mysql as '2017-02-03 00:00:00'
My model is mapped as :
import javax.persistence.*;
import java.util.Date;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "date")
private Date date;
And column on MySqls is TYPE DATETIME.

I think the milliseconds are actually being parsed, you just aren't seeing them with the default formatting that you're getting when you're displaying the date for debugging purposes.
Using this code:
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String myStringDate = "2018-02-02 23:59:59.700";
Date date = fmt.parse(myStringDate);
System.out.println(date);
System.out.println(fmt.format(date));
I get this output:
Fri Feb 02 23:59:59 EST 2018
2018-02-02 23:59:59.700
Update: Make sure you use capital MM for the month, not mm.

tl;dr
myPreparedStatement.setObject(
… ,
LocalDateTime.parse(
"2017-02-03 00:00:00".replace( " " , "T" )
)
)
Smart types, not dumb strings
The data is stored on mysql as '2017-02-03 00:00:00'
No, the data is not stored that way. You said:
column on MySqls is TYPE DATETIME.
That means the date-time is not stored as text, and does not have a “format”.
As the documentation says:
The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format.
Key words there are: retrieves and displays. After extracting the date-time value, some text is constructed to represent that value. Do not conflate the textual representation of the date-time value with the date-time value. Both your database and Java have their own internally-defined way of storing a date-time, but neither use plain text. Both your database and Java can generate text to display a date-time value, as needed.
Unzoned
I am a Postgres user, not MySQL, but it seems that its DATETIME type is akin to the SQL-standard TIMESTAMP WITHOUT TIME ZONE type. This means it does not represent an actual moment, is not a point on the timeline. It represents potential moments along a range of about 26-27 hours. Without the context of a time zone or offset-from-UTC, it has no real meaning.
java.time classes
Avoid the legacy date-time types. Use only java.time classes instead. According to this Question, JPA & Hibernate now support the java.time types.
If you do have input text such as 2018-02-02 23:59:59.700, parse as a LocalDateTime, given the lack of zone/offset information. Like the MySQL type DATETIME and the SQL type TIMESTAMP WITHOUT TIME ZONE, this class lacks any concept of zone/offset. To parse, convert from SQL-style with a SPACE in the middle to ISO 8601 standard format with a T in the middle.
String input = "2018-02-02 23:59:59.700".replace( " " , "T" ) ;
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to define a formatting pattern.
LocalDateDate ldt = LocalDateTime.parse( input ) ;
No need for strings when communicating with your database. As of JDBC 4.2 and later, you can directly exchange java.time objects. (Or let JPA/Hibernate do so under-the-covers.)
myPreparedStatement.setObject( … , ldt ) ;
And retrieval.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
FYI, if you are actually trying to track specific moments in time, you are using the wrong types. You should be using TIMESTAMP in MySQL or TIMESTAMP WITH TIME ZONE in standard SQL, and in Java use Instant and ZonedDateTime.
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.

If you are using MySQL's version 5.6.4, you can see this happen by declaring columns with fractional-second time datatypes.
This documentation shows more in detail about this feature, and as far as a quick check is concerned - you may try SELECT NOW(3) should give you the present time from your MySQL server's operating system with millisecond precision and instead if you are getting an error then you are not using the right version.
Alongside to that, moving from the older Connector/J driver to mysql-connector-java-5.1.26.jar is very much suggested.
Hope this helps answer your question!

The pattern for month of the year should be MM (uppercase) not mm (lowercase) for SimpleDateFormat. It is possible your code is reading the month as a minutes value.

The date format in SQL is YY-MM-dd hh24:mi:ss:mmm while in Java is YY-MM-dd HH:mm:ss.SSS

I used LocalDateTime:
#Column(name = "date", columnDefinition = "DATETIME(3)")
private LocalDateTime date;

Related

Strings Dates in firebase, retrieve as miliseconds [duplicate]

This question already has answers here:
Android parsing String to Date time with SimpleDateFormat
(3 answers)
ParseException; must be caught (Try/Catch) (Java) [duplicate]
(1 answer)
Closed 2 years ago.
I have some dates in firebase and i need to retrieve as Miliseconds and do some operations with it.
the Date are like String in format "dd/MM/yyyy"
I tryed with a code like this, :
String myDate = "2014/10/29 18:10:45";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(myDate);
long millis = date.getTime();
My code, basically i tryed to get the storeged String from firebase and convert to a Date for compare with the current day and show the diference of days. the error that I have, is only in the word "parse" of my code
refresh.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String mydate = model.getParto();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse(mydate);
}
});
but parse set an error
image of code and the string date in firebase
hope, someone can help
tl;dr
LocalDateTime
.parse(
"2014/10/29 18:10:45".replace( " " , "T" )
)
.atOffset( ZoneOffset.UTC )
.toInstant()
.toEpochMilli()
Need epoch reference
Representing a moment as a count of milliseconds requires a point in time as an epoch reference. You need to state the reference needed in your situation. I will assume the commonly used point of first moment of 1970 in UTC. But there are a couple dozen other points used by various systems. So you need to find out the meaning of your own data.
Need time zone or offset
Determining a moment requires more than a date and a time-of-day. You also need the context of a time zone or offset-from-UTC. Again, you need to specify this but did not. Is your example of ten minutes past six in the evening in Tokyo Japan, Toulouse France, or Toledo Ohio US? I will assume you mean an offset of zero hours-minutes-seconds. But again, you need to find out the meaning of your own data.
Avoid legacy date-time classes
Never use SimpleDateFormat, Date, or the other terrible date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310.
Date versus moment
Your Question in confused, referring to a date-only value as well as a date with time-of-day represented as milliseconds. These are two different kinds of data.
If representing a date-only, use LocalDate in Java and a type in your database akin to the SQL-standard DATE. I will ignore this date-only, and focus on tracking a moment.
Example code
Parse your input as LocalDateTime, after complying with standard ISO 8601 format by replacing SPACE in middle with a T.
A LocalDateTime does not represent a moment, is not a point on the timeline. You need to discover the zone/offset intended for you input, and apply. Apply the time zone intended for your input, to produce a ZonedDateTime. Or, if UTC (an offset of zero) was intended, apply a ZoneOffset to get an OffsetDateTime object. At this point we have determined a moment.
Extract a Instant object from the OffsetDateTime. Interrogate for a count of milliseconds since the epoch reference of 1970-01-01T00:00Z.
String myDate = "2014/10/29 18:10:45".replace( " " , "T" ) ; // Comply with ISO 8601 standard formatting.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ; // Assuming your data was intended to represent a moment as seen in UTC, with an offset of zero hours-minutes-seconds.
Instant instant = odt.toInstant() ; // Basic building-block class in java.time, representing a moment as seen in UTC.
long millisecondsSinceEpoch1970 = instant.toEpochMilli() ;
Your title mentions Firebase, but that seems irrelevant to your Question. so I will ignore that topic.
All the content in this Answer has been covered many times already 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), a process known as 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….

Converting time to UTC time goes the opposite way

I'm trying to parse an offset time using Java 8 DateTimeFormatter.
I live in EST time which is UTC-5, so when I try to convert
2019-01-22T13:09:54.620-05:00 should be --> 2019-01-22T18:09:54.620
However, with my code, it gets the current time and goes back 5 hours, resulting in 2019-01-22 08:09:54.620
Code:
import java.sql.Timestamp
import java.time._
import java.time.format.DateTimeFormatter
import scala.util.{Failure, Success, Try}
class MyTimeFormatter(parser: DateTimeFormatter) {
def parse(input: String): Try[Timestamp] = {
Try(new Timestamp(Instant.from(parser.withZone(ZoneOffset.UTC).parse(input)).toEpochMilli))
}
}
Test:
new MyTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxx")).parse("2019-01-22T13:09:54.620-05:00") shouldEqual Timestamp.valueOf("2019-01-22T18:09:54.620")
where parser is of type DateTimeFormatter and input string is just "2019-01-22T13:09:54.620-05:00"
I want to use this parser.parse method and not with specific temporalAccessors like OffsetDateTime.parse(input, parser) so I can handle all cases like LocalTime, LocalDateTime, ZonedDateTime, OffsetDateTime, etc..
It seems like the code just grabs the time, subtracts the offset, and brands it as UTC instead of calculating the offset with respect to UTC.
Also, is there a way to apply this UTC conversion only if the input format is of ZonedDateTime/OffsetDateTime format? If I input a LocalDateTime (which doesn't have an offset) such as 2017-01-01 12:45:00 the parser will still apply the UTC offset conversion because I told the parser to parse with zone UTC.
tl;dr
Use modern java.time classes. Convert to legacy class only if necessary to work with old code.
Specifically, parse your input string as a OffsetDateTime object, adjust to UTC by extracting an Instant, and lastly, convert to java.sql.Timestamp (only if you must).
java.sql.Timestamp ts = // Avoid using this badly-designed legacy class if at all possible.
Timestamp // You can convert back-and-forth between legacy and modern classes.
.from( // New method added to legacy class to convert from modern class.
OffsetDateTime // Represents a moment with an offset-of-UTC, a number of some hours-minutes-seconds ahead or behind UTC.
.parse( "2019-01-22T13:09:54.620-05:00" ) // Text in standard ISO 8601 format can be parsed by default, without a formatting pattern.
.toInstant() // Adjust from an offset to UTC (an offset of zero) by extracting an `Instant`.
) // Returns a `Timestamp` object. Same moment as both the `OffsetDateTime` and `Instant` objects.
;
See this code run live at IdeOne.com, resulting in:
ts.toString(): 2019-01-22 18:09:54.62
If using JDBC 4.2 or later, skip the Timestamp altogether.
myPreparedStatement.setObject( … , myOffsetDateTime ) ;
Zulu
2019-01-22T13:09:54.620-05:00 should be --> 2019-01-22T18:09:54.620
If you meant that second value to represent a moment in UTC, append the offset-from-UTC to indicate that fact. Either +00:00 or Z (pronounced “Zulu”): 2019-01-22T18:09:54.620Z.
Reporting a moment without an offset-from-UTC or time zone indicator is like reporting an amount of money without a currency indicator.
OffsetDateTime
A string with an offset-from-UTC should be parsed as a OffsetDateTime object.
Your input string happens to comply with the ISO 8601 standard formats for textual date-time values. The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
OffsetDateTime odt = OffsetDateTime.parse( "2019-01-22T13:09:54.620-05:00" ) ;
Timestamp
Apparently you want a java.sql.Timestamp object. This is one of the terrible date-time classes bundled with the earliest versions of Java. These classes are now legacy, supplanted entirely by the modern java.time classes with the adoption of JSR 310. Avoid these legacy classes whenever possible.
If you must have a Timestamp to interoperate with old code not yet updated to work with java.time, you can convert. To convert, call new methods added to the old classes.
Instant
The java.sql.Timestamp class carries a from( Instant ) method. An Instant is a moment in UTC. To adjust from the offset of our OffsetDateTime to UTC, just extract an Instant.
Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = Timestamp.from( instant ) ;
We have three objects ( odt, instant, & ts ) that all represent the same moment. The first has a different wall-clock time. But all three are the same simultaneous point on the timeline.
JDBC 4.2
As of JDBC 4.2, we can directly exchange java.time objects with the database. So no need to use Timestamp.
myPreparedStatement.setObject( … , odt ) ;
…and…
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.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, 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.
While I cannot reproduce your issue precisely (even with changing my clock to EST), this is what I am observing:
Instant instant = Instant.from(parser.withZone(ZoneOffset.UTC).parse("2019-01-22T13:09:54.620-05:00"));
This is producing the time you would expect (2019-01-22T18:09:54.620Z).
Timestamp ts = new Timestamp(instant.toEpochMilli());
Because this is based on java.util.Date, which displays as your local time.
A better way to convert an Instant to a Timestamp is via the LocalDateTime, like so:
Timestamp ts = Timestamp.valueOf(instant.atZone(ZoneOffset.UTC).toLocalDateTime());

java simple date pattern TO oracle sql date pattern

I have following web application:
Users can enter java simple date format patterns and a date (of course matching to the java simple date format pattern) and I want to store these date in an oracle database.
Therefore I need to translate the java simple date format pattern into the oracle pattern.
E.g:
"dd-MM-yyyy HH:mm:ss" into "DD-MM-YYYY HH24:MI:SS"
"dd-MM-yy HH:mm:ss" into "DD-MM-YY HH24:MI:SS"
"dd-MM-yy HH:mm" into "DD-MM-YY HH24:MI"
and so on.
Instead of the following code just having one SimpleDateFormat I would like to have all or at least a big bunch of SimpleDateFormatPatterns translated into Oracle pattern:
SimpleDateFormat sFormat = new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss");
String sqlSnippet = "TO_DATE('" + sFormat.format(date) + "','DD-MM-YYYY HH24:MI:SS')";
Is there a library or maybe just a mapping list to do this?
Thanks.
Edit:
I need to build the SQL by hand as the user defines the criteria, compare operators and joins in the user interface.
In the end I have something like this
AND col2 > TO_DATE('26-09-2012','DD-MM-YYYY')
Therefore I need to translate the java simple date format pattern into the oracle pattern
No, you don't. You should instead use a PreparedStatement, and call setDate or setTimestamp on it to specify the value you're interested in.
Avoid string conversions unless they're fundamentally part of what you're trying to do (e.g. displaying a date/time in a UI). For simply transferring information from your app to your database or vice versa, you should reduce the number of conversions required as far as possible.
The Answer by Jon Skeet is correct but is now outdated in referring to some legacy classes. The java.sql.Date and java.sql.Timestamp and related classes are now supplanted by the java.time classes, LocalDate and Instant respectively. But your Question demands the LocalDateTime class.
Smart objects, not dumb strings
You objects to represent your date-time values. As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
Your inputs lack any indicator of time zone or offset-from-UTC. So parse in Java as a LocalDateTime for storage in a column of a type similar to SQL-standard TIMESTAMP WITHOUT TIME ZONE.
DateTimeFormatter f1 = DateTimeFormatter.ofPattern( "dd-MM-uuuu HH:mm:ss" ) ;
DateTimeFormatter f2 = DateTimeFormatter.ofPattern( "dd-MM-uu HH:mm:ss" ) ;
DateTimeFormatter f3 = DateTimeFormatter.ofPattern( "dd-MM-uu HH:mm" ) ;
Choose a formatter by length of the input string.
LocalDateTime ldt = LocalDateTime.parse( myInputString , f2 ) ;
I need to build the SQL by hand as the user defines the criteria, compare operators and joins in the user interface. In the end I have something like this
String sqlSnippet = "TO_DATE('" + sFormat.format(date) + "','DD-MM-YYYY HH24:MI:SS')";
No, do not embed your date-time value as text in a String of SQL. Instead, use a PreparedStatement with ? placeholders replaced with your LocalDateTime object.
String sql = "SELECT when FROM tbl WHERE when > ? ;" ;
Pass the object to be slipped into that placeholder at runtime.
myPreparedStatement.setObject( … , ldt ) ;
Retrieval:
LocalDateTime ldt = myResultSet.getObject( … ; LocalDateTime.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, 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.

Convert current date & time to equivalent GMT date & time

I used the below code where I've printed the modified GMT date in String & in Date format, it's giving me two different values.
Date initial = new Date();
DateFormat dateFormatter = DateFormat.getInstance();
dateFormatter.setTimeZone (TimeZone.getTimeZone("UTC"));
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + gmt);
System.out.println("Data type is String "+gmtS);
Output
gtm where value id of type Date = Thu Jul 03 23:15:00 EDT 2014
gmtS where value id of type String = 7/4/14 3:15 AM
But I want to see the value (7/4/14 3:15 AM) as a Date type.
Any help is really appreciated.
When you output a Date by calling toString() (which is what System.out.println("Data type is Date = " + gmt); does) you will get that Date according to the system time zone, because that is what Date.toString() returns.
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
where:
...
zzz is the time zone (and may reflect daylight saving time). Standard time
zone abbreviations include those recognized by the method parse. If time
zone information is not available, then zzz is empty - that is, it
consists of no characters at all.
So, to get the output you expect use your dateFormatter to format it again.
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + dateFormatter.format(gmt));
tl;dr
Instant.now().toString()
2019-02-07T19:15:29.123456Z
Avoid legacy date-time classes
You are using date-time classes that are terribly troublesome, with many flaws in design.
First, you should know that java.util.Date represents a moment in UTC, always in UTC by definition. But its toString method tells a lie, dynamically applying the JVM’s current default time zone while generating the text representing the moment in the Date object.
java.time
The modern approach uses the java.time classes.
Instant
For a moment in UTC, use Instant. Like java.time.Date it represents a moment always in UTC (but with a finer resolution of nanoseconds versus milliseconds). Indeed, you can convert easily back-and-forth between Date and Instant by using new methods added to the old class.
Unlike toString on Date, the toString method on Instant always tells the truth. The method generates text in standard ISO 8601 format. The T in the middle separates the date portion from the time portion. The Z on the end is short for UTC and is pronounced “Zulu”.
Instant.now().toString(): 2019-01-23T12:34:56.123456789Z
OffsetDateTime
The Instant class is a basic building-block class in java.time, with limited functionality. If you want more flexible formatting, use the OffsetDateTime class with the offset set to UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Or skip the Instant class.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
To generate text representing the value of the OffsetDateTime object, use the DateTimeFormatter class. Search Stack Overflow as this has been covered many many times already.
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.

Java time in GMT

I have a Grails application with the following code:
Date now = Calendar.getInstance().getTime() //Also tried new Date()
println "now: " + now
When I do this, I get now: Thu Aug 18 12:47:09 CDT 2011. I need the date to be in GMT, not local time because I need to store the GMT time in a database. I can use a simpleDateFormat object to print out the time in GMT, but I need to actually store it as GMT.
Question: How do I convert a Date object to a Date object using GMT?
This accentuates why Java sucks at time. The previous posts are all close, but we need to be very careful about getting the current time in GMT, and getting the current time in CDT and calling it GMT.
TimeZone reference = TimeZone.getTimeZone("GMT");
Calendar myCal = Calendar.getInstance(reference);
This is the current time in GMT, with a timezone context of GMT.
To convert to a Date object which keeps the zone intact you'll need to call:
TimeZone.setDefault(reference);
This setting will last as long as your current JVM. Now calling get Time should produce the desired result.
myCal.getTime();
Well, if you really want time in GMT, you need to get it as GMT (#jpredham is right. Kudos to you! Editing my post to reflect this)
So do the following
//this option uses TimeZone
TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
TimeZone.setDefault(gmtTimeZone);
Calendar calendar = Calender.getInstance(gmtTimeZone);
Date myDate = calendar.getTime();
Try this:
println Calendar.getInstance(TimeZone.getTimeZone('GMT')).format('HH:mm:ss')
Note that when you convert to a date, you lose the timezone information. When Java/Groovy formats your Date for printing, it automatically formats it for your local timezone. Don't worry, your date doesn't have a timezone associated with it. You can add the proper timezone back in when you display it like so:
Date now = Calendar.getInstance(TimeZone.getTimeZone('GMT')).time
def formatter = new java.text.SimpleDateFormat('HH:mm:ss')
formatter.timeZone = TimeZone.getTimeZone('GMT')
println formatter.format(now)
Internally a Calendar object stores the time in UTC (the modern name for GMT). getTimeInMillis() returns a UTC value, and is probably what you want to store.
You should try GregorianCalendar#setTimeZone(TimeZone timeZone).
Using System.currentTimeMillis() is not only much faster than using Calendar or Date, it always gives you the GMT time. If you want to display this time, you can use SimpleDateFormat, setting the time zone to what ever you want.
You are confusing date-time object with its string representation. All common date-time libraries in Java (java.util.Date, Joda-Time, java.time in Java 8) internally track a fractional number of seconds since the first moment of 1970 in UTC while ignoring leap seconds. So in all three libraries, the date-time is internally always in UTC/GMT.
So your question of how to convert a Date object to a Date object in GMT (UTC) makes no sense.
The two better libraries (Joda-Time and java.time) also track a time zone inside the date-time object. The notoriously troublesome java.util.Date has no time zone assigned yet confusingly applies the JVM's current default time zone when it's toString method is invoked.
For the record, Joda-Time makes short work of this.
DateTime nowUtc = DateTime.now( DateTimeZone.UTC );
Calling that object's toString method generates a string in ISO 8601 format in Zulu (UTC) time.
Search StackOverflow for "Joda" and "formatter" to find many examples of adjusting to other time zones.
tl;dr
Instant.now() // Capture current moment in UTC.
.toString() // Generate a String object in standard ISO 8601 format, YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ.
2018-02-16T23:28:01.101324Z
java.time
The modern approach uses java.time classes. Avoid the troublesome legacy date-time classes entirely.
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 = Instant.now() ; // Capture the current moment in UTC.
Generate a string in standard ISO 8601 format by calling toString.
String output = instant.toString() ;
If you need more flexibility than Instant provides, such as formatting while generating strings, use OffsetDateTime with the constant ZoneOffset.UTC.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ; // Capture the current moment in UTC.
To generate strings in non-standard formats, use a DateTimeFormatter.
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.

Categories