How to maintain "-6" as UTC offset during CDT? - java

I want to retain CST time always with offset -6, at present I am getting as 2018-03-15T05:08:53-05:00.
But I want to change it as with offset -6 like 2018-03-15T05:08:53-06:00 through out the year.
TimeZone tz= TimeZone.getdefault();
if(tz.inDayLightTime())
{
getCSTDate(cal)
// I would like to change the logic here.
}
public XMLGregorianCalendar getCSTDate(Calendar cal)
{
return XMLGregorianCalendar;
}
my input type : calendar
output : XMLGregorianCalendar

Then don't use a timezone that tracks Daylight Saving Time changes (which is probably the case of yours TimeZone.getDefault()).
If you want a fixed offset, you can do:
TimeZone tz = TimeZone.getTimeZone("GMT-06:00");
Not sure why you want that, because if you're dealing with timezones, you must consider DST effects. And 2018-03-15T05:08:53-06:00 is not the same instant as 2018-03-15T05:08:53-05:00, so changing the offset while keeping all the other fields is usually wrong - as it's not clear why you want that and what you want to achieve, I can't give you more advice on that.

tl;dr
If you want the current moment as seen through a fixed offset-from-UTC, use OffsetDateTime with ZoneOffset.
OffsetDateTime.now(
ZoneOffset.ofHours( -6 )
)
Details
always with offset -6
The Answer by watssu is correct: If you don’t want the effects of Daylight Saving Time (DST), don’t use a time zone that respects DST.
If you always want an offset-from-UTC fixed at six hours behind UTC, use an OffsetDateTime.
ZoneOffset offset = ZoneOffset.ofHours( -6 ) ;
OffsetDateTime odt = OffsetDateTime.now( offset ) ; // Ignores DST, offset is fixed and unchanging.
Be clear that an offset is simply a number hours, minutes, and seconds displacement from UTC. In contrast, a time zone is a history of past, present, and future changes in offset used by the people of a particular region. So generally, you should be using a time zone rather than a mere offset. Your insistence on a fixed offset is likely unwise.
The 3-4 letter abbreviations such as CST are not time zones. They are used by mainstream media to give a rough idea about time zone and indicate if DST is in effect. But they are notstandardized. They are not even unique! For example, CST means Central Standard Time as well as China Standard Time or Cuba Standard Time.
Use real time zones with names in the format of continent/region.
Avoid all the legacy date-time classes such as TimeZone now supplanted by the java.time classes. Specifically, ZoneId.
ZoneId z = ZoneId.of( "America/Chicago" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Respects DST changes in offset.
If your real issue is wanting to detect DST to alter your logic, I suggest you rethink the problem. I suspect you are attacking the wrong issue. But if you insist, you can ask for the offset currently in effect on your ZonedDateTime, and you can ask a ZoneId if DST is in effect for any particular moment via the ZoneRules class.
ZoneOffset offsetInEffect = zdt.getOffset() ;
And…
Boolean isDstInEffect = zdt.getZone.getRules().isDaylightSavings( zdt.toInstant() ) ;
On that last line, note the incorrect use of plural with s on isDaylightSavings.
The XMLGregorianCalendar class is part of the troublesome old legacy date-time classes, now supplanted by the java.time classes, specifically ZonedDateTime. To inter-operate with old code not yet updated to java.time, convert to the modern class via the legacy class GregorianCalendar.
ZonedDateTime zdt = myXmlCal.toGregorianCalendar().toZonedDateTime() ;
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

Get Date from a DataObject (SDO) without losing the hour (JAVA)

I'm trying to get a date from a DataObject (Service Date Object (SDO)) that comes to me as an input and insert it into an Oracle database. The problem has been that the Date I get does not seem to have the introduced hour.
I am using the setDate() method from DataObject with the following value: 2019-05-22T13:30:00Z.
For some reason, when using getDate() what is returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I'm not sure if it's due to the input format or something related to the Date class from java.utils.
An easy solution would be to pass it as String and convert it into Date using a format but I would like to save this intermediate step.
java.util.Date versus java.sql.Date
Your Question does not provide enough detail to know for sure, but I can take an educated guess.
returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I suspect your code calling setDate and/or getDate is using a java.sql.Date object rather than a java.util.Date object.
➥ Check your import statements. If you used the wrong class by accident, that would explain the time-of-day getting set to 00:00.
java.util.Date represents a moment in UTC (a date, a time-of-day, and an offset-from-UTC of zero hours-minutes-seconds).
java.sql.Date pretends to represent a date-only, without a time-of-day and without a time zone or offset-from-UTC. Actually does contain a time-of-day and offset, but tries to adjust the time to 00:00:00.0 as part of the pretense.
Confusing? Yes. These old date-time classes from the earliest days of Java are a bloody awful mess, built by people who did not understand the complexities of date-time handling. Avoid these legacy date-time classes!
These legacy classes were supplanted years ago by the modern java.time classes defined in JSR 310. Try to do all your work in java.time. When interoperating with old code such as SDO that is not yet updated for java.time, call on new conversion methods added to the old classes.
The modern replacement of a java.util.Date is java.time.Instant. Both represents a moment in UTC, though Instant has a finer resolution of nanoseconds versus milliseconds.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Convert from modern class to legacy class. Beware of data-loss: Any microseconds or nanoseconds in the fractional second are truncated to milliseconds (as noted above).
java.util.Date d = java.util.Date.from( instant ) ; // Convert from modern to legacy. Truncates any microseconds or nanoseconds.
Pass to your SDO object.
mySdoDataObject.setDate( d ) ;
Going the other direction, retrieve the legacy java.util.Date object and immediately convert to an Instant.
Instant instant = mySdoDataObject.getDate().toInstant() ;
To see that same moment through the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
An easy solution would be to pass it as String
No! Use smart objects, not dumb strings. We have the industry-leading date-time library built into Java, so use it.
Database
As of JDBC 4.2, we can directly exchange java.time objects with the database.
Your JDBC driver may optionally handle Instant. If not, convert to OffsetDateTime.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

How to manually set the Daylight Saving (DST) shift date in Java

My country changed the the Daylight Saving shift date from "October 21" to "November 4" and we need to apply this in our back-end.
The appropriate solution is to update the Operating System configuration, but we have restrictions to do so (legacy dependencies). We are looking for a workaround.
Is it possible to use code and change the DST shift date programmatically?
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(0);
gc.set(2018, Calendar.OCTOBER, 21, 0, 0, 0);
gc.setTimeZone(TimeZone.getTimeZone("Brazil/East"));
XMLGregorianCalendar xml = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
System.out.println("XML Date: " + xml.toString());
Output must be -03:00:
XML Date: 2018-10-21T01:00:00.000-02:00
OS irrelevent
Your operating system configuration is irrelevant. Most Java implementations by default pick up their initial default time zone from the host OS upon launch. But the definition of the time zones is stored within the Java implementation.
Java time zone updater
So you need to update the time zone definitions within your Java implementation. Most implementations use the tz database also known as tzdata.
For the Oracle-branded Java implementation, Oracle provides the Timezone Updater Tool. That landing page has an as-of date of 2018-08, so perhaps your time zone’s changes have been included. But I suggest you investigate more closely to verify.
For other implementations, check with the vendor. They may have provided an updated version of the JVM to include the fresh tzdata. Or perhaps they too provide an updater tool. Or perhaps you can replace the tzdata file manually.
Avoid mangling zone with code
I strongly suggest you avoid trying to make artificial adjustments to the offset yourself in code. You will likely get it wrong. Date-time work in surprisingly tricky and confusing.
But if you insist, firstly avoid the terrible old legacy date-time classes such as GregorianCalendar & Calendar & Date. These were supplanted years ago by JSR 310. If you must interoperate with old code not yet updated to java.time, do your work in the modern classes and then at the end convert via new methods added to the old classes.
Use the modern the java.time classes, specifically:
Instant (for a moment in UTC)
OffsetDateTime (for a moment with an offset-from-UTC of hours-minutes-seconds but no time zone)
ZonedDateTime (for a moment in a particular time zone)
You can search Stack Overflow for many existing examples and explanations using these classes. You should focus on OffsetDateTime, ZoneOffset (rather than ZoneId), and Instant since you must avoid ZonedDateTime if your know your tzdata file to be outdated.
Same moment, different wall-clock time
OffsetDateTime::withOffsetSameInstant​
OffsetDateTime odt = OffsetDateTime.parse( "2018-10-21T01:00:00.000-02:00" ) ;
ZoneOffset offset = ZoneOffset.ofHours( -3 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstant​( offset ) ; // Same moment, same point on the timeline, different wall-clock time.
odt.toString(): 2018-10-21T01:00-02:00
odt2.toString(): 2018-10-21T00:00-03:00
In that example, both odt and odt2 represent the same simultaneous moment, the same point on the timeline. If you extract an Instant (a value in UTC), your results will be the same moment. Only their wall-clock time is different.
Instant instant1 = odt.toInstant() ; // Adjust to UTC.
Instant instant2 = odt2.toInstant() ;
boolean sameMoment = instant1.equals( instant2 ) ;
instant1.toString(): 2018-10-21T03:00:00Z
instant2.toString(): 2018-10-21T03:00:00Z
sameMoment = true
The Z on the end means UTC, an offset-from-UTC of zero, +00:00. The Z is pronounced “Zulu”. Defined by the ISO 8601 standard.
Different moment, same wall-clock time
OffsetDateTime::withOffsetSameLocal​
In contrast, you may want to force the time-of-day thereby representing a different moment. For that, use withOffsetSameLocal method. Be very aware that you are changing the meaning of data, you are moving to another point on the timeline.
OffsetDateTime differentMomentButSameTimeOfDay = odt. withOffsetSameLocal( offset ) ;
differentMomentButSameTimeOfDay.toString(): 2018-10-21T01:00-03:00
Extract the instant to see we have a different moment.
Instant differentInstant = differentMomentButSameTimeOfDay.toInstant() ;
differentInstant.toString(): 2018-10-21T04:00:00Z
Notice the 4 AM UTC versus 3 AM UTC seen above. This moment here occurs an hour after the moment above. Two different points on the timeline.
Do not attempt this work until you fully comprehend the concept of points on the timeline, and changing between points being entirely different than adjusting offsets. Practice extensively before doing real work. Half-hearted guessing will land you in a world of hurt and headache.
And, as I suggested above, your time would be much better spent installing updated tzdata files rather than hacking these offsets.
Live code
See all the code above run live at IdeOne.com.
Update tzdata everywhere
For best results, you should be updating the tzdata (or equivalent) in all these various places:
Your operating systems
Your JVMs
Your database engines, such as Postgres
Any libraries bundling their own time zone info (ex: Joda-Time)
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
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), the process of 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….
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.

Timestamp.from not heeding timezone from Instant

When I try to convert a ZonedDateTime to a Timestamp everything is fine until I call Timestamp.from() in the following code:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.minusSeconds(currentTimeUTC.getSecond());
currentTimeUTC = currentTimeUTC.minusNanos(currentTimeUTC.getNano());
return Timestamp.from(currentTimeUTC.toInstant());
ZonedDateTime.now(ZoneOffset.UTC); -> 2018-04-26T12:31Z
currentTimeUTC.toInstant() -> 2018-04-26T12:31:00Z
Timestamp.from(currentTimeUTC.toInstant()) -> 2018-04-26 14:31:00.0
// (with Timezone of Europe/Berlin, which is currently +2)
Why is Timestamp.from() not heeding the timezone set in the instant?
The Instant class doesn't have a timezone, it just has the values of seconds and nanoseconds since unix epoch. A Timestamp also represents that (a count from epoch).
why is the debugger displaying this with a Z behind it?
The problem is in the toString methods:
Instant.toString() converts the seconds and nanoseconds values to the corresponding date/time in UTC - hence the "Z" in the end - and I believe it was made like that for convenience (to make the API more "developer-friendly").
The javadoc for toString says:
A string representation of this instant using ISO-8601 representation.
The format used is the same as DateTimeFormatter.ISO_INSTANT.
And if we take a look at DateTimeFormatter.ISO_INSTANT javadoc:
The ISO instant formatter that formats or parses an instant in UTC, such as '2011-12-03T10:15:30Z'
As debuggers usually uses the toString method to display variables values, that explains why you see the Instant with "Z" in the end, instead of the seconds/nanoseconds values.
On the other hand, Timestamp.toString uses the JVM default timezone to convert the seconds/nanos values to a date/time string.
But the values of both Instant and Timestamp are the same. You can check that by calling the methods Instant.toEpochMilli and Timestamp.getTime, both will return the same value.
Note: instead of calling minusSeconds and minusNanos, you could use the truncatedTo method:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.truncatedTo(ChronoUnit.MINUTES);
This will set all fields smaller than ChronoUnit.MINUTES (in this case, the seconds and nanoseconds) to zero.
You could also use withSecond(0) and withNano(0), but in this case, I think truncatedTo is better and more straight to the point.
Note2: the java.time API's creator also made a backport for Java 6 and 7, and in the project's github issues you can see a comment about the behaviour of Instant.toString. The relevant part to this question:
If we were really hard line, the toString of an Instant would simply be the number of seconds from 1970-01-01Z. We chose not to do that, and output a more friendly toString to aid developers
That reinforces my view that the toString method was designed like this for convenience and ease to use.
Instant does not hold the Timezone information. It only holds the seconds and nanos.
To when you convert your ZonedDateTime into an Instant the information is lost.
When converting into Timestamp then the Timestamp will hold the default Timezone, which is, in your case, Europe/Berlin.
tl;dr
You are being confused by the unfortunate behavior of Timestamp::toString to apply the JVM’s current default time zone to the objects internal UTC value.
➡ Use Instant, never Timestamp.
A String such as 2018-04-26T12:31Z is in standard ISO 8601 format, with the Z being short for Zulu and meaning UTC.
Your entire block of code can be replaced with:
Instant.now()
…such as:
myPreparedStatement.setObject( … , Instant.now() ) ;
Details
The Answer by wowxts is correct. Instant is always in UTC, as is Timestamp, yet Timestamp::toString applies a time zone. This behavior is one of many poor design choices in those troubled legacy classes.
I'll add some other thoughts.
Use Instant for UTC
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
While technically correct, this line is semantically wrong. If you want to represent a moment in UTC, use Instant class. 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.
Avoid legacy Timestamp class
Timestamp.from(currentTimeUTC.toInstant());
While technically correct, using my suggest above, that would be:
Timestamp.from( instant ); // Convert from modern *java.time* class to troublesome legacy date-time class using new method added to the old class.
Nothing is lost going between Instant and Timestamp, as both represent a moment in UTC with a resolution of nanoseconds. However…
No need to be using java.sql.Timestamp at all! That class is part of the troublesome old date-time classes that are now legacy. They were supplanted entirely by the java.time classes defined by JSR 310. Timestamp is replaced by Instant.
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
Insert/Update.
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.

Java Date and time

I am making a change to some code which runs on a unix box. It sets the time for a field in a database based on the current date and time for London.
The methods I am using are as follows;
private static Date getCurrentTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-kk:mm:ss.SSS");
format.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Calendar cal = Calendar.getInstance();
Date currentDate = cal.getTime();
try {
return format.parse(format.format(currentDate));
} catch (ParseException e) {
log.error("Error occured while parsing date-->" + e.getMessage());
}
return new Date();
}
private String getStringFromDate(Date date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-kk:mm:ss.SSS");
return sdf.format(date);
}
When the message is processed by the java app on the production unix box (which is set to north america time as thats where it is hosted) then when it is inserted into the database it is an hour behind (not being set to BST).
If I run the same code in Eclipse on my desktop, I get the correct time in the database.
I am unsure what might be causing this issue and was hoping someone might be able to help.
Thanks
edit*** at second glance, even the log files on the unix box are an hour behind so on that basis i assume its unix that is causing the issue opposed to my code.
A Date instance is always in UTC (or, it should be unless you've done something wrong). you should store your dates in the db in UTC and convert them to whatever timezone you desire when presenting them to the user. anything else is just asking for trouble.
your code which formats and then parses the Date instance in the same TimeZone is just meaningless.
tl;dr
A Date (and Instant) are always in UTC by definition. So no need to futz with time zone.
Instant.now() // Capture current moment in UTC.
Or, if you must use the troublesome legacy class Date:
java.util.Date.from( Instant.now() ) // Avoid the legacy classes whenever possible. When required, you can convert back-and-forth via new methods added to the old classes as seen here.
Always specify time zone
Never rely on the current default time zone of either your host OS or your JVM. That default value is out of your control and can change at any moment during runtime.
Instead:
Always use the java.time classes rather than the troublesome old legacy classes seen in your code.
Always specify your desired/expected time zone as an optional argument to the various java.time methods rather than rely implicitly on the JVM’s current default.
java.time
You appear to be trying to get the current moment as a java.util.Date object. That legacy class represents a value in UTC, so the time zone is irrelevant.
Instant
The modern replacement for that class is java.time.Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Capturing the current moment is simple: Instant.now.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
If you must have Date to inter-operate with old code not yet updated to java.time, convert by calling new methods added to the old classes.
java.util.Date javaUtilDate = java.util.Date.from( instant ) ;
Either way, be very aware that both a Date and an Instant represent a point on the timeline in UTC, always UTC.
UTC versus London Time
Also, be aware that UTC is not London time, a common misconception given that UTC/GMT is tracked from a point at the Royal Observatory, Greenwich. Actually, London has a history of anomalies in its offset-from-UTC, including the adoption of Daylight Saving Time (DST).
To get London time, assign a ZoneId to get a ZonedDateTime.
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( "Europe/London" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, but viewed with a different wall-clock time used by the people of a particular region (time zone).
Generally, best practice is to keep your servers in UTC, and to do as much of your business logic, storage, and exchange of date-time values in UTC. Use a zoned value such as London time only when required either by business logic or presentation to user.
Notice in the code seen above that the current default time zone of any computer or JVM is irrelevant. A change in that default has no effect on your code.
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.

How can I convert from Gregorian Calendar to Unix Time, in Java?

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.

Categories

Resources