Java time in GMT - java

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.

Related

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.

Convert current date & time to equivalent GMT date & time

I used the below code where I've printed the modified GMT date in String & in Date format, it's giving me two different values.
Date initial = new Date();
DateFormat dateFormatter = DateFormat.getInstance();
dateFormatter.setTimeZone (TimeZone.getTimeZone("UTC"));
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + gmt);
System.out.println("Data type is String "+gmtS);
Output
gtm where value id of type Date = Thu Jul 03 23:15:00 EDT 2014
gmtS where value id of type String = 7/4/14 3:15 AM
But I want to see the value (7/4/14 3:15 AM) as a Date type.
Any help is really appreciated.
When you output a Date by calling toString() (which is what System.out.println("Data type is Date = " + gmt); does) you will get that Date according to the system time zone, because that is what Date.toString() returns.
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
where:
...
zzz is the time zone (and may reflect daylight saving time). Standard time
zone abbreviations include those recognized by the method parse. If time
zone information is not available, then zzz is empty - that is, it
consists of no characters at all.
So, to get the output you expect use your dateFormatter to format it again.
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + dateFormatter.format(gmt));
tl;dr
Instant.now().toString()
2019-02-07T19:15:29.123456Z
Avoid legacy date-time classes
You are using date-time classes that are terribly troublesome, with many flaws in design.
First, you should know that java.util.Date represents a moment in UTC, always in UTC by definition. But its toString method tells a lie, dynamically applying the JVM’s current default time zone while generating the text representing the moment in the Date object.
java.time
The modern approach uses the java.time classes.
Instant
For a moment in UTC, use Instant. Like java.time.Date it represents a moment always in UTC (but with a finer resolution of nanoseconds versus milliseconds). Indeed, you can convert easily back-and-forth between Date and Instant by using new methods added to the old class.
Unlike toString on Date, the toString method on Instant always tells the truth. The method generates text in standard ISO 8601 format. The T in the middle separates the date portion from the time portion. The Z on the end is short for UTC and is pronounced “Zulu”.
Instant.now().toString(): 2019-01-23T12:34:56.123456789Z
OffsetDateTime
The Instant class is a basic building-block class in java.time, with limited functionality. If you want more flexible formatting, use the OffsetDateTime class with the offset set to UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Or skip the Instant class.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
To generate text representing the value of the OffsetDateTime object, use the DateTimeFormatter class. Search Stack Overflow as this has been covered many many times already.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

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 Date() returns date in UTC" - what does it actually mean?

My question might be trivial but I'm just looking for clarifications. I read somewhere in SO that Java's Date() is actually always in UTC time, how come when I create a Date() object and print it using toString(), it displays the local time. If this is not the right way to print it, what should it be so I would get the UTC time?
For formatting, you should really use a DateFormat implementation (e.g. SimpleDateFormat). That will let you specify the time zone (and output format). Date itself has no concept of time zones - it represents an instant in time, using the "milliseconds since the Unix epoch" as storage. The toString() method just converts whatever instant is represented into a local time using the system default time zone.
Personally I'd advise moving away from the built-in date/time API entirely and using Joda Time as a far more sensible library.
“Java Date() returns date in UTC” - what does it actually mean?
UTC is the baseline against which we adjust the time-of-day around the globe.
Since the caveman days, noon, or 12:00, is when the sun is directly overhead. Of course, that means different moments in different places. Noon in Japan happens hours earlier than in Europe, and noon arrives even later in the Americas.
In the modern era, humans created time zones where noon would apply to a wide swath of land, so wide that the sun may not be overhead simultaneously across all of it. So the sun, or “solar time”, could no longer be used to define time. The modern time zone is defined as being a certain number of hours-minutes-seconds from the baseline.
What baseline? That baseline was arbitrarily chosen by the fate of history to be the latitude that runs through the Royal Observatory, Greenwich in London, England, UK. Time zones to the east are a certain number of hours-minutes-seconds ahead of UTC, and to the west a certain number behind UTC. For example, India is five and half hours ahead of UTC, and Martinique in the Caribbean is four hours behind UTC.
If the offset is zero hours-minutes-seconds, then we say we are “at UTC” or “in UTC”.
Java's Date() is actually always in UTC time
Yes, the java.util.Date class, despite its unfortunate name, represents a date with time-of-day with an offset-from-UTC of zero.
The Date class is now obsolete, by the way. The java.time.Instant class is now used as its replacement to represent a moment in UTC. Instant has a resolution of nanoseconds, finer than the milliseconds of Date.
when I create a Date() object and print it using toString(), it displays the local time
There are many problems with the legacy date-time classes. One is the poor naming, as mentioned above. Another is the well-intentioned by unfortunate design decision made that Date::toString should dynamically apply the JVM’s current default time zone to adjust from UTC while generating the text. This bad decision has caused no end of confusion and pain to Java programmers, as it creates the illusion that java.util.Date has a time zone assigned.
As an aside… Even worse, the java.util.Date does have a time zone, but buried deep in its source code with no accessor getter/setter methods. But that zone does affect some behavior such as determining equality between objects of this class. Confusing? Yes. As I said, these legacy date-time classes are riddled with poor design decisions.
If this is not the right way to print it, what should it be so I would get the UTC time?
The right way is to avoid the Date class entirely. Use only the java.time classes instead.
➥ To get the current moment in UTC, use Instant.now.
Instant instant = Instant.now() ;
Tip: If you want to alter the time for the purpose of artificial testing, pass an alternate Clock to Instant.now( Clock ).
To generate a String with text representing the value of that Instant in standard ISO 8601 format, simply call toString. Fortunately this class does not inject a time zone like Date does. The Instant::toString method tells the simple truth, text of the moment in UTC.
String output = instant.toString() ;
2019-12-03T10:15:30.032163Z
Be clear that date-time objects such as Instant do not have a “format”. Only text representing the value of those objects have a format. The text and the date-time object are distinct and separate from each other. A date-time object can generate such text, and can parse such text, but is not actually the text.
If you need flexibility in generating text in other formats, apply a ZoneOffset to get a OffsetDateTime object, or apply a ZoneId to get a a ZonedDateTime object. Apply a DateTimeFormatter object to generate the text.
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.
A java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String strDateNewYork = sdf.format(date);
System.out.println(strDateNewYork);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);
System.out.println(strDateUtc);
}
}
Output:
2021-06-20T09:43:39.517-04:00
2021-06-20T13:43:39.517Z
ONLINE DEMO
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
System.out.println(now);
}
}
Output:
2021-06-20T13:37:42.174352Z
ONLINE DEMO
An Instant represents an instantaneous point on the timeline in UTC. The Z in the output is the timezone designator for a zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

How to make date.getTime() returns UTC time?

I have a Date object which represents a UTC time. When I use the method getTime() to get the long value of this object, the value returned corresponds to our local time (central US). What is the correct way to get the value back which corresponds to the original UTC time?
Thanks
tl;dr
Instant.now()
…and…
Instant.ofEpochMilli( n )
…and…
instant.toEpochMilli()
Date is always in UTC
When I use the method getTime() to get the long value of this object, the value returned corresponds to our local time (central US).
No, the value returned from Date::getTime() always corresponds to UTC (virtually the same thing as GMT in this context). To quote the class doc:
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
So your Question is nonsensical in that a Date is already in UTC. No need to “get the value back which corresponds to the original UTC time”,
You may be confusing the behavior of getTime with that of the toString method. The toString method annoyingly and confusingly applies the current default time zone in the process of generating the String. So the string output appears with a time zone while in fact there is no time zone to be set or gotten from the Date itself. (There actually is a zone deep within the Date but that is irrelevant to this discussion here. This class is a confusing mess!)
java.time
The modern way to do this is using java.time classes.
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).
Get the current moment.
Instant instant = Instant.now();
You can convert a Date to its modern replacement by calling one of the new conversion methods added to the old date-time classes. Just call toInstant, quite easy.
Instant instant = myJavaUtilDate.toInstant();
I do not recommend at all using a count-from-epoch number as a way of tracking time. Stick with the java.time objects instead. When outside Java, serialize to text use the ISO 8601 formats.
But if you must, you can extract a count of milliseconds since epoch of 1970-01-01T00:00:00Z. Note that this may involve data loss! An Instant has a finer resolution of nanoseconds. So going to milliseconds may lop off a fraction of the fraction of a second.
long millisecondsSinceEpoch = instant.toEpochMilli(); // Caution: Possible data-loss in going from nanoseconds to milliseconds.
Going the other direction, from a count to an Instant.
Instant instant = Instant.ofEpochMilli( millisecondsSinceEpoch ) ;
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….
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.
The DateFormat class has a method for setting your preferred time zone, and there's a time zone class that has a setting for UTC time.
So, for example,
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Date yourUtcDate = sdf.parse(yourOriginalDate);
java.util.Date has no concept of timezone. It simply holds time relative to epoch, which is Jan 1 1970 00:00:00 UTC. Date is a model, separate from the view. When you display the date, the concept of timezone then is applied. Date's toString() displays a human readable date in the default timezone. You can either use a DateFormat to display a Date in a different timezone (such as UTC), or change the JVM's default timezone.
getTime() returns "the number of milliseconds since January 1, 1970, 00:00:00 GMT", nothing more, nothing less (obviously, you have to create it correctly). You can format it however you want, starting with e.g. the GregorianCalendar(TimeZone) constructor.
Most of the Date class functions are deprecated as they are now shifted in Calendar class.
Here is code to get UTC time from Calendar.
Date date = new Date(timeStamp);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(date);
Here is the sample code to get the year, month, etc.
System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH));
Calendar also has support for many other useful information like, TIME, DAY_OF_MONTH, etc. Here the documentation listing all of them Please note that the month are 0 based. January is 0th month.
LocalDateTime now = LocalDateTime.now(Clock.systemUTC());
Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
Date formattedDate = Date.from(instant);
return formattedDate;

Categories