38

In Java, I want to get the current time in GMT.

I tried various options like this:

Date date = new Date();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
date1 = calendar.getTime();

But the date is always is interpreted in my local time zone.

What am I doing wrong and how can I convert a java Date to GMT?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
narayanan
  • 515
  • 2
  • 10
  • 19
  • 2
    System.currentTimeMillis(), or just new Date(). It's GMT already. – bestsss Mar 08 '11 at 17:44
  • 1
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 07 '19 at 00:13

12 Answers12

48

Odds are good you did the right stuff on the back end in getting the date, but there's nothing to indicate that you didn't take that GMT time and format it according to your machine's current locale.

final Date currentTime = new Date();

final SimpleDateFormat sdf =
        new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");

// Give it to me in GMT time.
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("GMT time: " + sdf.format(currentTime));

The key is to use your own DateFormat, not the system provided one. That way you can set the DateFormat's timezone to what you wish, instead of it being set to the Locale's timezone.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • 1
    I want the GMT date in Milliseconds any Idea?? – mayur rahatekar Oct 23 '12 at 09:26
  • 3
    `long millis = System.currentTimeMillis();` will return the number of milliseconds that have elapsed since `1 January 1970, 00:00:00.000 UTC`. UTC time is what most people really want when they say "GMT time". `java.util.Date` has a `getTime()` method which does the same thing for an arbitrary `Date`. You might need to use a `java.util.Calendar` to construct the `Date` object depending on your needs, if so `Calendar's` `getTime()` method will return a `Date` which you can then `getTime()` to get the milliseconds offset. – Edwin Buck Oct 23 '12 at 20:21
20

I wonder why no one does this:

Calendar time = Calendar.getInstance();
time.add(Calendar.MILLISECOND, -time.getTimeZone().getOffset(time.getTimeInMillis()));
Date date = time.getTime();

Update: Since Java 8,9,10 and more, there should be better alternatives supported by Java. Thanks for your comment @humanity

Harun
  • 667
  • 7
  • 13
  • I tried a couple of options to achieve this but only your solution works perfectly – Sankalp Jul 14 '17 at 12:53
  • 1
    One issue with this approach is that it doesn't change the timezone when the time is serialized. – humanity Oct 16 '18 at 16:07
  • 1
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 07 '19 at 00:13
10

From my experience, the bundled Calendar and Date classes in Java can yield undersired effect. If you wouldn't mind upgrading to Java 8, then consider using ZonedDateTime

like so:

ZonedDateTime currentDate = ZonedDateTime.now( ZoneOffset.UTC );
Damilola
  • 1,014
  • 2
  • 20
  • 22
10

tl;dr

Instant.now()

java.time

The Answer by Damilola is correct in suggesting you use the java.time framework built into Java 8 and later. But that Answer uses the ZonedDateTime class which is overkill if you just want UTC rather than any particular time zone.

The troublesome old date-time classes are now legacy, supplanted by the 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).

Simple code:

Instant instant = Instant.now() ;

instant.toString(): 2016-11-29T23:18:14.604Z

You can think of Instant as the building block to which you can add a time zone (ZoneID) to get a ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

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 java.time.

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 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.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
4

You can achieve it using Java 8 java.time package

Get current GMT time in Java:

ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println("Print current time in GMT: "+zonedDateTime); // 2021-08-30T03:58:05.815942377Z

Convert a java.util.Date to GMT

// use a formatter
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss O");

Date date = new Date(); //; java.util.Date object
Instant instant = date.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(ZoneOffset.UTC);
System.out.println("java.util.Date to GMT: "+customFormatter.format(zonedDateTime)); // 08/30/2021 03:58:05 GMT

Ref

Gaurav Kukade
  • 183
  • 2
  • 10
3

To get the time in millis at GMT all you need is

long millis = System.currentTimeMillis();

While the following work, they are inefficient. You can also do

long millis = new Date().getTime();

and

long millis = 
    Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis();
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 2
    this answer is incorrect. Tried printing new Date(millis) from long millis = Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis(); It still gives current time zone time. – Srujan Kumar Gulla Jun 24 '13 at 20:18
  • 1
    @JavaEnthusiast http://ideone.com/seLqnz it gives the time in GMT here regardless of the timezone. – Peter Lawrey Jun 24 '13 at 21:02
  • All of these give me my local timezone, which is not GMT. – Forseth11 Jun 07 '17 at 04:03
  • @Forseth11 That is not correct. They are all GMT unless your system clock has been set incorrectly. – Peter Lawrey Jun 07 '17 at 08:13
  • @PeterLawrey My bad. I was using a date format put in my local timezone to display the time. Sorry. – Forseth11 Jun 08 '17 at 03:02
  • For the third example, the "GMT" seems extraneous and confusing. Change it to any other zone and it still results in the millis in GMT. – Woodchuck Feb 17 '23 at 16:55
  • @Woodchuck I included it as it was an example I had seen. I have changed the text to make it clearer you should not do this. – Peter Lawrey Feb 20 '23 at 09:04
3

After trying a lot of methods, I found out, to get the time in millis at GMT you need to create two separate SimpleDateFormat objects, one for formatting in GMT and another one for parsing.

Here is the code:

 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 format.setTimeZone(TimeZone.getTimeZone("UTC"));
 Date date = new Date();
 SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 Date dateTime= dateParser.parse(format.format(date));
 long gmtMilliSeconds = dateTime.getTime();

This works fine. :)

Boern
  • 7,233
  • 5
  • 55
  • 86
Firdous Ahmad
  • 49
  • 1
  • 8
1

You can’t

First, you are asking the impossible. An old-fashioned Date object hasn’t got, as in cannot have a time zone or GMT offset.

But the date is always is interpreted in my local time zone.

I suppose that you have printed the Date or done something else that implicitly calls it toString method. I believe that this is the only time that the Date is interpreted in your time zone. More precisely in the current default time zone of your JVM. On the other hand this is unavoidable. Date.toString() does behave in that way, it picks up the JVM’s time zone setting and uses it for rendering the string to be returned.

You can with java.time

You shouldn’t use a Date, though. That class is poorly designed and fortunately long outdated. Also java.time, the modern Java date and time API that replaces it, has a class or two for dates and times with offset from GMT or UTC. I am considering GMT and UTC synonymous for now, strictly speaking they are not.

    OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
    System.out.println("Time now in UTC (GMT) is " + now);

When I ran this snippet just now, the output was:

Time now in UTC (GMT) is 2019-06-17T11:51:38.246188Z

The trailing Z of the output means UTC.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

This is pretty simple and straight forward.

Date date = new Date();
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
date = cal.getTime();

Now date will contain the current GMT time.

Divyesh Kanzariya
  • 3,629
  • 3
  • 43
  • 44
Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104
0

Useful Utils methods as below for manage Time in GMT with DST Savings:

public static Date convertToGmt(Date date) {
    TimeZone tz = TimeZone.getDefault();
    Date ret = new Date(date.getTime() - tz.getRawOffset());

    // if we are now in DST, back off by the delta.  Note that we are checking the GMT date, this is the KEY.
    if (tz.inDaylightTime(ret)) {
        Date dstDate = new Date(ret.getTime() - tz.getDSTSavings());

        // check to make sure we have not crossed back into standard time
        // this happens when we are on the cusp of DST (7pm the day before the change for PDT)
        if (tz.inDaylightTime(dstDate)) {
            ret = dstDate;
        }
    }
    return ret;
}

public static Date convertFromGmt(Date date) {
    TimeZone tz = TimeZone.getDefault();
    Date ret = new Date(date.getTime() + tz.getRawOffset());

    // if we are now in DST, back off by the delta.  Note that we are checking the GMT date, this is the KEY.
    if (tz.inDaylightTime(ret)) {
        Date dstDate = new Date(ret.getTime() + tz.getDSTSavings());

        // check to make sure we have not crossed back into standard time
        // this happens when we are on the cusp of DST (7pm the day before the change for PDT)
        if (tz.inDaylightTime(dstDate)) {
            ret = dstDate;
        }
    }
    return ret;
}
Kalpesh
  • 1,767
  • 19
  • 29
0

After java 8, you may want to get the formatted time as below:

DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(LocalTime.now(ZoneId.of("GMT")));
Denis Wang
  • 965
  • 12
  • 13
0

The following code will get the date minus timezone offset:

protected Date toGmt0(ZonedDateTime time) {
    ZonedDateTime gmt0 = time.minusSeconds(time.getOffset().getTotalSeconds());
    return Date.from(gmt0.toInstant());
}

@Test
public void test() {

    ZonedDateTime now = ZonedDateTime.now();
    Date dateAtSystemZone = Date.from(now.toInstant());
    Date dateAtGmt0 = toGmt0(now);

    SimpleDateFormat sdfWithoutZone = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    SimpleDateFormat sdfWithZoneGmt0 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ITALIAN);
    sdfWithZoneGmt0.setTimeZone(TimeZone.getTimeZone("GMT"));

    System.out.println(""
            + "\ndateAtSystemZone          = " + dateAtSystemZone
            + "\ndateAtGmt0                = " + dateAtGmt0
            + "\ndiffInMillis              = " + (dateAtSystemZone.getTime() - dateAtGmt0.getTime())
            + "\n"
            + "\ndateWithSystemZone.format = " + sdfWithoutZone.format(dateAtSystemZone)
            + "\ndateAtGmt0.format         = " + sdfWithoutZone.format(dateAtGmt0)
            + "\n"
            + "\ndateFormatWithGmt0        = " + sdfWithZoneGmt0.format(dateAtSystemZone)
    );

output :

dateAtSystemZone          = Thu Apr 23 14:03:36 CST 2020
dateAtGmt0                = Thu Apr 23 06:03:36 CST 2020
diffInMillis              = 28800000

dateWithSystemZone.format = 2020-04-23 14:03:36.140
dateAtGmt0.format         = 2020-04-23 06:03:36.140

dateFormatWithGmt0        = 2020-04-23 06:03:36.140

My system is at GMT+8, so diffInMillis = 28800000 = 8 * 60 * 60 * 1000

btpka3
  • 3,720
  • 2
  • 23
  • 26
  • Wrong. From a `ZonedDateTime` of `2020-04-22T00:00+08:00[Asia/Shanghai]` I got `Tue Apr 21 08:00:00 GMT 2020`. It’s the same hour of day, but it’s not the same time. Also an old-fashioned `Date` has got neither zone offset nor time zone, so it doesn’t make any sense to say that it is or isn’t in GMT. – Ole V.V. Apr 21 '20 at 16:59
  • 1
    While this code may answer the question, it would be better to include some context, explaining how it works and when to use it. Code-only answers are not useful in the long run. – Mustafa Apr 22 '20 at 02:11