Convert current date & time to equivalent GMT date & time - java

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.

Related

SimpleDataForma ParseException: Unparseable date? [duplicate]

I'm trying to parse date like this:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
And I'm getting a value of 5 hours am, because i live in UTC+3 timezone. But i need to have value of 2am, however, with the same format string(date string given in a specified format, which i'm not allowed to change). How to do this?
Upd: I don't need to format the date in proper timezone, i need to COMPARE these dates by its values without timezones. I want exactly that date have parsed ignoring the timezone in original string - and be always in the same timezone (my, for example), no matter what contains original string: UTC or UTC+3 or something else.
The accepted Answer is working too hard. Manipulating offsets is the province of a date-time library. Doing such work yourself is a waste of your time, and likely to be a source of bugs.
The old java.util.Date/.Calendar classes are notoriously troublesome. Avoid them. Instead use either java.time or Joda-Time.
java.time
Java 8 and later has a new java.time framework built-in.
Confused Question
Your Question is confused. You say you want to ignore time zone, yet you accept an answer that does indeed parse and process the time zone. And that answer then adjusts the result by an offset. So, it seems that you do not want to ignore the time zone.
Indeed, ignoring the time zone rarely makes sense. Perhaps you want to compare a pair of factories in Berlin and in Detroit to see if they both take a lunch break at the same time. In this case you are comparing their respective wall-clock time. The java.time framework offers the “Local” classes for this purpose: LocalDate, LocalTime, and LocalDateTime. But this is rarely needed in most business scenarios in my experience. These objects are not tied to the timeline.
So it seems that what you do want is to be able to compare date-time values across various time zones. The java.time classes do that implicitly. ZonedDateTime objects with various assigned time zones can be compared to one another with isBefore, isAfter, and isEqual methods.
Example Code
First we parse the input string.
The z pattern code means to expect and parse a time zone. The resulting date-time object will also be assigned this object if no other specific time zone is specified.
We also assign a Locale object with a human language component matching the text we expect to see in the input string. In this case, we need any Locale with English.
String input = "Oct 04, 2015 2:11:58,757 AM UTC";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd, yyyy K:mm:ss,SSS a z" ).withLocale( Locale.ENGLISH );
ZonedDateTime then = ZonedDateTime.parse( input, formatter );
Next we get the current time for Québec. This arbitrary choice of time zone will demonstrate further below that we can compare this ZonedDateTime object to another with a different time zone. Specifically, comparing against the UTC time zone assigned to our then object above.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
Do the comparison.
Boolean isThenBeforeNow = then.isBefore( now );
By the way, generally-speaking, the best practice in date-time work is to convert all your date-time values to UTC time zone for business logic, storage, and data exchange. Adjust into a time zone only as need be to satisfy a user’s expectations on-screen or in reports.
ZonedDateTime nowUtc = now.withZoneSameInstant( ZoneOffset.UTC );
Dump to console.
System.out.println( "input: " + input );
System.out.println( "then: " + then );
System.out.println( "now: " + now );
System.out.println( "isThenBeforeNow: " + isThenBeforeNow );
System.out.println( "nowUtc: " + nowUtc );
When run.
input: Oct 04, 2015 2:11:58,757 AM UTC
then: 2015-10-04T02:11:58.757Z[UTC]
now: 2015-10-19T19:28:04.619-04:00[America/Montreal]
isThenBeforeNow: true
nowUtc: 2015-10-19T23:28:04.619Z
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.
Upd2: Solved
Okay, now i get what i want:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
long diff = TimeZone.getDefault().getRawOffset() - df.getTimeZone().getRawOffset();
date = new Date(date.getTime()-diff);
Anyway, thanks for everyone

Convert Calendar to Date - ignore timezone

We receive a GregorianCalendar object from a 3rd party library. We need to turn that into a Date for use in another 3rd party library. And we're on Java 1.6 so we don't have the new time/instant classes available.
The problem is calling Calendar.getTime() gives a different date, offset by (I think) our timezone. So the next day by 8 hours.
How can we do this without this shift?
Update: We get the date from an OData call. The date being returned is an employee birthdate (Northwind) and therefore shouldn't have a time. But it's returned as a GregorianCalendar object with a time of 1992-05-01 00:00:00. GMT timezone it appears.
And the getTime() is returning a Date of "Thu Apr 30 18:00:00 MDT 1992" - I'm in the Mountain Time Zone.
The problem is I need to get from the calendar object a Date object of 1992-05-01, not 1992-04-30. And preferably with the time offset matching too.
Get get the Date value in your default time zone, call setTimeZone().
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
cal.clear();
cal.set(1992,4,1); // 1992-05-01 00:00:00 GMT
// "Fix" time zone
cal.setTimeZone(TimeZone.getDefault());
System.out.println(cal.getTime());
Output
Fri May 01 00:00:00 EDT 1992
tl;dr
No shift
java.util.Date date = myGregorianCalendar.getTime() ; // Same moment, same point on the timeline. `Date` is in UTC, `GregorianCalendar` may be in some other time zone.
String output = date.toString() ; // This new string is a lie, dynamically applying the JVM’s current time zone while the `Date` is actually in UTC, always, by definition.
There is no shift. Calling GregorianCalendar.getTime produced a java.util.Date. The Date object is always in UTC, by definition. Unfortunately the Date::toString method lies, injecting the JVM’s current default time zone while producing a String.
Be clear that the Date and String are two separate distinct objects. One holds a moment in UTC, the other is a textual representation of that moment after being adjusted into some time zone.
The GregorianCalendar, the Date, and the String all represent the same moment, same point on the timeline, but different wall-clock time.
Use java.time for clarity
Date-time handling is much easier and clear if you use modern java.time classes rather than awful mess that is the legacy classes Date, Calendar, and GregorianCalendar.
java.time
The GregorianCalendar class is one of the troublesome old date-time classes supplanted by the java.time classes built into Java 8 and later. Much of the java.time functionality is back-ported to Java 6 and Java 7 in the ThreeTen-Backport project.
Convert from legacy class to modern java.time using new methods added to the old classes, specifically GregorianCalendar::toZonedDateTime. If using the back-port, use the DateTimeUtils class.
ZonedDateTime zdt = DateTimeUtils.toZonedDateTime( myCalendar ) ;
A ZonedDateTime object is the replacement for GregorianCalendar. This class is conceptually the combination of a Instant (a moment in UTC) with an assigned time zone, a ZoneId object.
If you want the same moment as seen in UTC, extract the Instant.
Instant instant = zdt.toInstant() ;
You can convert back to a java.util.Date from an Instant, for compatibility with old code not yet updated to java.time.
java.util.Date date = DateTimeUtils.toDate( instant ) ; // Convert from modern `Instant` class to legacy `Date` class.
If you want just the date portion, without the time-of-day and without the time zone, create a LocalDate object.
LocalDate ld = zdt.toLocalDate() ;
The problem is calling Calendar.getTime() gives a different date, offset by (I think) our timezone. So the next day by 8 hours.
How can we do this without this shift?
…
And the getTime() is returning a Date of "Thu Apr 30 18:00:00 MDT 1992" - I'm in the Mountain Time Zone.
What you are seeing is an illusion. The GregorianCalendar::getTime method returns to you a java.util.Date object. Then you implicitly called toString on that Date object. That java.util.Date::toString method has an unfortunate behavior of applying your JVM’s current default time zone while generating a string to represent its value. The value of the Date is actually UTC, always UTC, by definition. That toString method creates the illusion that the Date harbors a time zone when in fact it does not†.
†Actually, the java.util.Date class does harbor a time zone, but deep within its source code. Used for stuff like the equals method implementation. But the class has no getter or setter, so it seems invisible to us. And in the context of your Question, is irrelevant.
Confusing? Yes. This is one of many reasons to avoid these terrible old date-time classes. Use only java.time classes instead.
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.

SimpleDateFormat fails to format Date interval?

I try to format a time interval using SimpleDateFormat.
import java.text.*;
import java.util.*;
public class DateFormatTest {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
long interval = 1000;
System.out.println("Interval in millis: " + interval);
System.out.println("Expected result: 00:00:01");
System.out.println("Result using Date and SimpleDateFormat: " +
sdf.format(new Date(interval)));
}
}
I get the following result:
Interval in millis: 1000
Expected result: 00:00:01
Result using Date and SimpleDateFormat: 01:00:01
I am in GMT+1 time zone. But it should not be reflected in the result.
Of course it can be solved with System.out.printf, but what I am searching is the reason.
I am in GMT+1 time zone. But should not be reflected in the result.
What makes you think so? new Date(0) is at 00:00AM GMT on Jan 1st 1970. So it is at 01:00AM if your default timezone is GMT + 1.
I am in GMT+1 time zone. But it should not be reflected in the result.
Then you should set the time zone in the SimpleDateFormat. SimpleDateFormat is doing exactly the right thing - it's formatting the instant in time (just after midnight UTC 1970) in the time zone it's working in.
To change the time zone, just use:
sdf.setTimeZone(TimeZone.getTimeZone("etc/UTC"));
It's not clear whether you should really be using SimpleDateFormat at all, though. You're not trying to format a date/time - you're trying to format an interval, given your variable name.
I suggest you use Joda Time which has a much richer type system, and will allow you to express what you really want.
Also, if you really want to use SimpleDateFormat, you probably want to use HH instead of hh in your format string. (hh is a 12-hour value, 1-12. You want 00:00:01, not 12:00:01.) hh is rarely appropriate when you don't also have an am/pm designator in your pattern.
Wrong data type
You are using the wrong class. You are trying to represent a duration of milliseconds and a time-of-day. Neither fits the Date class. That class represents a moment (a date, with time-of-day, in context of UTC).
Also, java.util.Date is a terrible class, designed by people who did not understand date-time handling. Now obsolete.
java.time
The modern solution uses java.time classes.
LocalTime
Specifically, LocalTime for a time-of-day using a generic 24-hour day, without a date, and without the context of a time zone or offset-from-UTC.
The start of a day for generic days is 00:00:00. We have a constant for that: LocalTime.MIN. But know that in various time zones, on various dates, the day may start at another time such as 01:00:00.
LocalTime lt = LocalTime.of( 15 , 30 ) ; // 3:30 PM.
Duration
To represent a span-of-time unattached to the timeline, on a scale of hours-minutes-seconds, use Duration class.
Duration d = Duration.ofMilliseconds( 1_000 ) ;
We can do math with date-time objects.
LocalTime lt = LocalTime.MIN.plus( d ) ;
You should know that java.time classes use a resolution of nanoseconds, much finer than the milliseconds used by the legacy date-time classes.
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.

Weird Date Format To Java Date

I got the following date format that I get from an API (Yes I tried to get them to change the API... dailywtf story):
\/Date(1310481956000+0200)\/
How can I convert this into a Java Date? (java.util.Date)
This comes from a .NET JSON web service.
Without knowing what the date/time string stands for, let me make a guess.
The 1310481956000 looks to be milliseconds after epoch, and the +0200 an offset relative to GMT.
The following code seem to indicate it as well:
final TimeZone tz = TimeZone.getTimeZone("GMT+0200");
final Calendar cal = Calendar.getInstance(tz);
cal.setTimeInMillis(1310481956000L);
final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
f.setTimeZone(tz);
System.out.println(f.format(cal.getTime()));
Prints 2011-07-12 16:45:56 GMT+02:00
How can I convert this into a Java Date? (java.util.Date)
First, get "them" to clearly and precisely tell you exactly what that date format means. (If they won't or can't you could guess; see below.)
Next write a custom parser to parse the String and extract the information content.
Finally, convert the information content into a form that matches one of the Date constructors and create an instance.
My guess is that the 1310481956000 part is the number of milliseconds since the UNIX epoch (1970/01/01T00:00) and that the 0200 represents a timezone offset of 2 hours (MET?). However, you shouldn't rely on a guess. Get "them" to give you the specification, or at least a number of examples and the actual times/timezones that they correspond to.
You'll have to get the format from the API provider but it seems like a epoch + an offset for time zones. To convert it you could try.
final String fromAPI = "1310481956000+0200"
final String epochTime = fromAPI.substring(0, fromAPI.indexOf("+"));
final String timeZoneOffSet = fromAPI.substring(fromAPI.indexOf("+"), fromAPI.size());
Date date = new Date(Long.parseLong(epochTime));
Notice i'm not doing anything with the time zone (if that's what it is). You'll have to deal with that but this should get you on the right path.
tl;dr
Instant.ofEpochMilli(
java.lang.Long.parseLong( "1310481956000" )
).atOffset( ZoneOffset.of( "+0200" ) )
Using java.time
The accepted Answer is correct but outdated. The modern way to handle this is through the java.time classes.
The input is ambiguous. Is it a count from the Unix epoch reference date-time of first moment of 1970 in UTC 1970-01-01T00:00:00:Z and then adjusted by two hours ahead of UTC? If so, this example code seen here works.
First parse that input number as 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).
Extract the first portion of your string and parse as a long.
long millisSinceEpoch = java.lang.Long.parseLong( "1310481956000" );
Instant instant = Instant.ofEpochMilli( millisSinceEpoch );
instant.toString(): 2011-07-12T14:45:56Z
Extract the last portion of your string and parse as a ZoneOffset.
ZoneOffset offset = ZoneOffset.of( "+0200" );
Apply the offset to the Instant to get an OffsetDateTime.
OffsetDateTime odt = instant.atOffset( offset );
odt.toString(): 2011-07-12T16:45:56+02:00
Note that an offset-from-UTC is not a time zone. A zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
Avoid java.util.Date whenever possible. But if you must use one, you can convert to/from java.time. Look to new conversion methods added to the old classes.
java.util.Date d = java.util.Date.from( odt.toInstant() );
d.toString(): Tue Jul 12 14:45:56 GMT 2011
See live code at IdeOne.com covering this entire example.
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 and 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 SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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