Change the time based on the gmt area on Android - java

I'm a beginner in android development and I've been searching for hours to find an answer for my question but I didn't really understand anything I found.
The match between 2 teams is starting at 20:00 gmt and I want to make it + - based on the area. For example in germany +1 gmt the time should be 21:00. I only want the hours and minutes format like that.

tl;dr
OffsetDateTime
.of(
LocalDate.of( 2021 , Month.MARCH , 23 ) ,
LocalTime.of( 20 , 0 ) ,
ZoneOffset.UTC
) // Returns a `OffsetDateTime` object.
.atZoneSameInstant(
ZoneId.of( "Europe/Berlin" )
) // Returns a `ZonedDateTime` object.
.toLocalTime() // Returns a `LocalTime` object.
.toString() // Returns a `String` object, with text in standard ISO 8601 format.
21:00
Details
Location does not necessarily correlate to time zone. Users choose their time zone as a preference. Servers should generally be set to UTC (an offset of zero). You can get the JVM’s current default time zone by calling ZoneId.systemDefault. If crucial, you should explicitly ask the user to confirm their desired zone.
I only want the hours and minutes format like that.
Date-time objects are not text, and do not have a "format". Think in terms of the logic needed for handling date-time values rather than in terms of manipulating strings.
starting at 20:00 gmt and I want to make it + - based on the area
Representing that 8 PM in UTC (the new GMT):
LocalDate tomorrow = LocalDate.now( ZoneOffset.UTC ).plusDays( 1 ) ;
LocalTime eightPM = LocalTime.of( 20 , 0 ) ;
OffsetDateTime odt = OffsetDateTime.of( tomorrow , eightPM , ZoneOffset.UTC ) ;
For example in germany +1 gmt the time should be 21:00
Define your desired time zone.
ZoneId z = ZoneId.of( "Europe/Berlin" ) ;
Adjust from the OffsetDateTime to a ZonedDateTime.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
See that code run live at IdeOne.com.
odt.toString(): 2021-02-17T20:00Z
zdt.toString(): 2021-02-17T21:00+01:00[Europe/Berlin]
The odt & zdt objects seen here both refer to the very same simultaneous moment, the same point on the timeline.
This has all been covered many times before 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….

It's not Android specific but just a general question about Java.
Use Calendar and SimpleDateFormat like this:
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
calendar.set(2021, 1, 16, 20, 00, 00); // 2021-02-16T20:00:00 GMT
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+01:00"));
System.out.println(simpleDateFormat.format(calendar.getTime()));
Set (input) your date as GMT. Then format it GMT+01:00 with SimpleDateFormat and print (output) it.

Related

How to update a Timestamp field in MySql from a Java PreparedStatement?

My index.html has an <input type="datetime-local"> field and I need to update a MySql database with whatever value the user selects. My database field is currently a Timestamp. How can I create an update statement that allows me to update the database with this datetime-local value? I've tried many options and my current attempt is shown below; however, this does not work. I am doing this all in Java.
String updateStatement = "UPDATE cars SET reservation = ? WHERE uniqueID = ?";
pStmt = con.prepareStatement(updateStatement);
pStmt.setTimestamp(1, reservation);
pStmt.setTimestamp(2, someUniqueId);
tl;dr
To answer your specific code question (but this is the wrong way to handle appointments/reservations):
myPreparedStatement
.setObject(
1 ,
ZonedDateTime
.of
(
LocalDate.of( 2021 , Month.JANUARY , 23 ) ,
LocalTime.of( 15 , 30 ) ,
ZoneId.of( "Africa/Tunis" )
)
.toInstant()
.atOffset( ZoneOffset.UTC )
)
;
java.time
The TIMESTAMP type in MySQL is for tracking a moment, a specific point on the timeline, as seen from an offset of zero hours-minutes-seconds from UTC, resolving to microseconds. This maps to TIMESTAMP WITH TIME ZONE in standard SQL.
The appropriate match in Java would be java.time.Instant. This class also represents a moment as seen in UTC, but with finer resolution of nanoseconds.
Unfortunately, the JDBC 4.2 specification requires support for only one of the three types that track a moment: OffsetDateTime. Both Instant and ZonedDateTime are optional in JDBC 4.2. So your particular JDBC driver may or may not support Instant. This design decision by the JDBC team baffles me. Converting between Instant and OffsetDateTime is utterly simple, and should have been required by JDBC spec.
I am guessing you are letting users pick a date and a time-of-day within a particular time zone. But I'm not sure, as your neglected to detail your inputs.
LocalDate localDate = LocalDate.of( 2021 , Month.JANUARY , 23 ) ;
LocalTime localTime = LocalTime.of( 15 , 30 ) ;
ZoneId zoneId = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = ZonedDateTime.of( localDate, localTime , zoneId ) ;
To store in the database, let's adjust from a time zone to UTC (an offset of zero). Convert from ZonedDateTime to Instant, and then to OffsetDateTime with an offset of zero hours-minutes-seconds represented by the constant ZoneOffset.UTC.
OffsetDateTime odt = zdt.toInstant().atOffset( ZoneOffset.UTC ) ; // Use `OffsetDateTime` rather than `Instant` for maximum compatibility across JDBC 4.2 drivers.
Do not call PreparedStatement#setTimestamp. That method is now legacy, for the terrible java.sql.Timestamp class. Never use date-time classes outside the java.time package. Those legacy classes were supplanted years ago by the modern java.time classes defined in JSR 310.
Call PreparedStatement#setObject. The JDBC team has yet to define specific set… methods for the various java.time classes. Again, a design decision which baffles me. However, we can exchange the java.time objects using setObject/getObject.
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Tracking appointments
By the way, you mentioned the business problem is making restaurant reservations in the future. For this work, you are taking the wrong approach.
Such future appointments are not tracked as moments, are not specific points on the timeline. If politicians were to change the offset used by that time zone, your customers expect a restaurant reservation for 7 PM to stay at 7 PM, regardless of politicians moving the clock forward or backward. Similarly, a dental appointment for 3 PM four months from now should stay at 3 PM even if the politicians change the offset. And politicians around the world do enjoy changing their time zone offset. This happens surprisingly often, and with less and less forewarning.
Reservations/appointments should be tracked as date and time without time zone, storing time zone separately in second column of database. These types would be TIMESTAMP WITHOUT TIME ZONE in standard SQL, and DATETIME in MySQL. And use a text type for the time zone identifier. The matching type in Java would be LocalDateTime and ZoneId. At runtime for calendaring, combine to determine a moment with a ZonedDateTime.
I and other authors have covered this many times already on Stack Overflow. So 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….
Maybe your date format is incorrect.
reservation = System.currentTimeMillis();
UPDATE
Ok,I understand you.You should use String to receive the datetime-local value.
Because the format of datetime-local from frontend is yyyy-MM-ddTHH:mm, but the format of TimeStamp in Java(package java.sql) is yyyy-MM-ddTHH:mm:ss.
It lack the :ss, so can not receive.
Finally set timestamp after convert String to TimeStamp.
datetimeLocal = datetimeLocal.replaceAll("T", " ") + ":00";
Timestamp reservation = Timestamp.valueOf(datetimeLocal);

GregorianCalendar in Android (add Calendar.HOUR_OF_DAY vs Calendar.HOUR)

To add an hour to current time, can I use this?
Calendar mcalendar = new GregorianCalendar();
mcalendar.add(Calendar.HOUR_OF_DAY, 1); //I plan to use 24 hours format
I see many examples using instead:
Calendar mcalendar = Calendar.getInstance();
mcalendar.add(Calendar.HOUR, 1);
tl;dr
Duration duration = Duration.ofHours( 1 ) ;
ZoneId zoneId = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( zoneId ).plus( duration ) ;
DateTimeFormatter f = DateTimeFormatter
.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( Locale.GERMANY) ;
String output = zdt.format( f ) ;
Sonntag, 27. Dezember 2020 um 22:58:52 Nordamerikanische Ostküsten-Normalzeit
java.time
The modern solution uses the java.time classes. Never use Calendar or GregorianCalendar.
UTC
Capture the current moment as seen in UTC. Use Instant.
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
Define a span-of-time unattached to the timeline.
Duration duration = Duration.ofHours( 1 ) ;
Addition.
Instant instantHourLater = instant.plus( duration ) ;
Zoned
You may want to see the time-of-day and date of that moment as seen through the wall-clock time used by the people of a particular region. Apply a time zone (ZoneId) to get a ZonedDateTime object. Same moment, same point on the timeline, different wall-clock time.
ZoneId zoneId = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( zoneId ) ;
Or, skip the Instant and the Duration.
ZonedDateTime zdt = ZonedDateTime.now( zoneId ).plusHours( 1 ) ;
Text
You said:
I plan to use 24 hours format
The classes such as Instant, OffsetDateTime, and ZonedDateTime represent a moment, a point on the timeline. They have nothing to do with text. They do not have a “format”. They can parse text representing a moment, and they can produce text representing a moment. But internally they have their own way of representing that moment, without any formatted text.
To produce text in a particular format, use DateTimeFormatter class with FormatStyle and Locale. This has been covered many many times already on Stack Overflow. So search to learn more.
DateTimeFormatter f = DateTimeFormatter
.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
;
String output = zdt.format( f ) ;
See this code run live at IdeOne.com.
output: dimanche 27 décembre 2020 à 22 h 51 min 57 s heure normale de l’Est
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….
Calendar mcalendar = new GregorianCalendar();
The GreogorianCalendar is a subclass of the abstract class Calendar. Therefore what you are doing here is referencing an instance of the GregorianCalendar to the Calendar therefore all the abstract methods in Calendar will follow the implementation of GregorianCalendar
But since your purpose is to add Hours.
You can go ahead with Calendar mcalendar = Calendar.getInstance(); as it retrieves an instance to the current with the the current Locale.
However, if you want to change your Locale, pass in the parameter into the getInstance() method and an instance of the specified Locale will be generated for you.
Refer: https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getInstance(java.util.Locale)
And if you want to use Hours:
Do the following:
Do not use HOUR variable as this is only for 12 hour times. Use Calendar.HOUR_Of_DAY to deal with 24 hour timings.

How to convert a string to date with UTC/GMT timezone

I have an android app that receives a string in this format:"MM-dd-yyyy HH:mm:ss" from my server. I want to convert this string to a Date object with UTC as timezone since the time in the string is UTC. I've already checked several similar questions but didn't find my answer
Here is what I'm using currently:
SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
Date date = new Date();
try {
date = format.parse(itemContent [3]);
entity.setValidTill(date);
}catch (Exception e){
}
But what it does when I print that date with Log is show it as:
Sun Aug 27 15:00:00 GMT+04:00 2017
I want it to be:
Sun Aug 27 15:00:00 GMT 00:00 2017
So here is the main question how to get DateTime for UTC using a string with format as above?
Edit:
Just put it in a better context. I'm trying to get users to see the difference between current datetime & the that datetime saved in server. So my solution was to get gmt time for users & compare with the server time(which is gmt) so everyone see same difference regardless of their timezone. With C# you can get DateTime.UtcNow while with java I couldn't find an alternative
Briefly, as your Question is really a duplicate of many others…
You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
Parse your input string as a LocalDateTime as it lacks any indicator of offset-from-UTC or time zone.
Define a formatter to parse your input string.
String input = "08-27-2017 15:00:00" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
ldt.toString(): 2017-08-27T15:00
A LocalDateTime is not a moment on the timeline, only a rough idea about a range of possible moments. Has no meaning without the context of an offset (or time zone).
If you are certain that input was intended for UTC, assign the constant ZoneOffset.UTC for a OffsetDateTime.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
odt.toString(): 2017-08-27T15:00Z
To calculate a delta between that moment and the current moment, use the Period class for coarser granularity in your span of time, or Duration for finer granularity. Both classes generate strings in standard ISO 8601 format of PnYnMnDTnHnMnS.
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC ) ;
Duration d = Duration.between( odt , now ) ;
now.toString(): 2017-08-27T21:16:56.396Z
d.toString(): PT6H16M56.396S
See this code run live at IdeOne.com.
In the standard strings seen above, the Z is short for Zulu and means UTC.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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….
just add this code under the first line of your code:
format.setTimeZone(TimeZone.getTimeZone("UTC"));

Gregorian Calendar and date before 1970

How can i fix the variable "time" for the gregorian calendar date before 1970. Or what was the unit of the variable "time" of gregorian calendar for the date before 1970?
I use hibernate for the object-relational mapping. And the data I'm trying to Save to my database is a date type gregorian calendar. But whenever the date is less than 1970, my application crash.
Timestamps before Epoch (1970 Jan 1st) are represented by negative numbers. Have a look at this SO answer to see an example.
If your application "crashes" (whatever that means), you need to look how is it represented in the database and how is it mapped.
tl;dr
ZonedDateTime.of(
LocalDate.of( 1969 , Month.DECEMEBER , 25 ) ,
LocalTime.NOON ,
ZoneId.of( "Africa/Tunis" )
).toInstant()
Crash?
You have not presented enough information to diagnose your crash.
Beware that the date-time capabilities of various databases varies widely. The SQL standard barely touches on the topic of date-time handling, so little is required. Some databases have quite limited support. Any serious enterprise-oriented database should be able to easily store moments going many centuries both in the past as well as the future.
java.time
Use the java.time classes added to Java 8 and later. These types are apparently now supported in Hibernate (I’m not a user).
Internally, moments after the epoch of 1970-01-01T00:00Z (first moment of 1970 in UTC) are represented as a count of nanoseconds, a positive number. For moment before the epoch, a negative number of nanoseconds. But you should not really care. Just use the java.time classes as intended, and never see that count number.
If you were to want noon of Christmas Day in 1969 in New Zealand:
LocalTime lt = LocalTime.NOON ;
LocalDate ld = LocalDate.of( 1969 , Month.DECEMEBER , 25 ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Database
With JDBC 4.2 and later, you can directly exchange these java.time types with your database. No need for numbers or strings. The old java.sql.Timestamp and related classes are now legacy, and can be forgotten.
Adjust your moment from its time zone to UTC, extract a Instant. Same simultaneous moment, same point on the timeline, but viewed through the lens of the wall-clock time used by the people of a particular region.
Instant instant = zdt.toInstant() ;
Pass to your database for a column of type TIMESTAMP WITH TIME ZONE.
myPreparedStatement.setObject( … , instant ) ;
And retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( ZoneId.of( "America/Montreal" ) ) ;
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.
Cant you use Calender class?
public class DatePrint {
public static void main(String[] argv) {
Calendar c = new GregorianCalendar(1900, 10, 11);
System.out.println(c.get(Calendar.DAY_OF_MONTH) + " "
+ c.get(Calendar.MONTH) + ", " + c.get(Calendar.YEAR) + " "
+ c.get(Calendar.ERA));
}
}

java Calendar compare incorrect

I am comparing 2 Calendar objects in java. This the way i am setting each of them
Calendar calendar1 = Calendar.getInstance();
calendar1.set(2012, 6, 17, 13, 0);
And i am getting the following value from table column '2012-07-17 13:00:00' and setting it into Date Java object and then this Date object i am using to set second Calander object.
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(/*Above date object who value is '2012-07-17 13:00:00'*/);
Now when i compare i expect this to be true since both the Calender object are same
calendar2.compareTo(calendar1) >= 0
but instead i am seeing this is becoming true
calendar2.compareTo(calendar1) < 0
Can somebody help?
The following will give you the idea of what's going on (assuming you are parsing the string to produce the date object for calendar1):
Calendar calendar1 = Calendar.getInstance();
calendar1.set(2012, 6, 17, 13, 0);
System.out.println(calendar1.getTime());
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-07-17 13:00:00");
System.out.println(date);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date);
System.out.println(calendar2.compareTo(calendar1));
calendar1.set(Calendar.SECOND, 0); //setting second to 0
calendar1.set(Calendar.MILLISECOND, 0); //setting millisecond to 0
System.out.println(calendar2.compareTo(calendar1));
Test run result:
Tue Jul 17 13:00:47 CDT 2012
Tue Jul 17 13:00:00 CDT 2012
-1
0
After suggestion from #Bhesh Gurung i used the following
calendar1.set(Calendar.MILLISECOND, 0);
calendar1.set(Calendar.SECOND, 0);
calendar2.set(Calendar.MILLISECOND, 0);
calendar2.set(Calendar.SECOND, 0);
and it worked.
tl;dr
ZonedDateTime.of( // Represent a specific moment using the wall-clock time observed by the people of a specific region (a time zone).
2012 , Month.JULY , 17, 13 , 0 , 0 , 0 , // Hard-code the date and time-of-day, plus zone.
ZoneId.of( "America/Montreal" ) // Specify time zone by Continent/Region name, never by 3-4 letter pseudo-one such as PST or CST.
) // Returns a `ZonedDateTime` object.
.toInstant() // Adjust into UTC.
.equals(
myResultSet.getObject( … , Instant.class ) // Retrieve an `Instant` object for a date-time value stored in your database.
)
Time zone
You do not provide enough info for a definitive answer, but as others suggested you likely are seeing a problem with time zones. Your code does not address this crucial issue explicitly. But, implicitly, your creation of a Calendar item assigns a time zone.
java.time
More importantly, you are using troublesome old date-time classes now supplanted by the java.time classes.
Replace your use use of Calendar with Instant and ZonedDateTime.
For a ZonedDateTime, specify your desired/expected time zone explicitly rather than have the JVM’s current default time zone be applied implicitly. 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" ) ;
ZonedDateTime zdt = ZonedDateTime.of( 2012 , Month.JULY , 17, 13 , 0 , 0 , 0 , z );
Adjust into UTC by extracting a 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() ;
Database
From your database, exchange objects rather than mere strings. As of JDBC 4.2 and later, you can exchange java.time objects.
Most databases store a moment such as the SQL-standard type TIMESTAMP WITH TIME ZONE as a value in UTC. So using an Instant object is usually best.
Store your Instant object’s value.
myPreparedStatement.setObject( … , instant ) ;
Retrieval.
Instant instantDb = myResultSet.getObject( … , Instant.class ) ;
Compare using the Instant methods equals, isBefore, and isAfter.
boolean sameMoment = instant.equals( instantDb ) ;
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.

Categories