576

When I create a new Date object, it is initialized to the current time but in the local timezone. How can I get the current date and time in GMT?

Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
Behrang
  • 9,789
  • 6
  • 24
  • 19
  • I know these types of topics are completely over discussed, but I found the commons-lang package really handles these common java issues well. http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/time/ Check out the various packages they have. –  Mar 26 '12 at 15:44
  • Which local time do you want, and to what precision. Most timezones are defined relative to UTC with a fixed offset measured in [SI](https://en.wikipedia.org/wiki/SI_base_unit) seconds, but the relationship of GMT which is based on solar observation and a (slightly) variable length second is more complex. The two differ by up to 0.9 seconds. – mc0e Feb 27 '17 at 04:34
  • 4
    A `Date` doesn’t hold a time zone, so "but in the local timezone” is not correct (or inaccurate at best). See [All about java.util.Date](https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/). – Ole V.V. Jul 04 '18 at 05:06

34 Answers34

500

tl;dr

Instant.now()   // Capture the current moment in UTC. 

Generate a String to represent that value:

Instant.now().toString()  

2016-09-13T23:30:52.123Z

Details

As the correct answer by Jon Skeet stated, a java.util.Date object has no time zone. But its toString implementation applies the JVM’s default time zone when generating the String representation of that date-time value. Confusingly to the naïve programmer, a Date seems to have a time zone but does not.

The java.util.Date, j.u.Calendar, and java.text.SimpleDateFormat classes bundled with Java are notoriously troublesome. Avoid them. Instead, use either of these competent date-time libraries:

java.time (Java 8)

Java 8 brings an excellent new java.time.* package to supplant the old java.util.Date/Calendar classes.

Getting current time in UTC/GMT is a simple one-liner…

Instant instant = Instant.now();

That Instant class is the basic building block in java.time, representing a moment on the timeline in UTC with a resolution of nanoseconds.

In Java 8, the current moment is captured with only up to milliseconds resolution. Java 9 brings a fresh implementation of Clock captures the current moment in up to the full nanosecond capability of this class, depending on the ability of your host computer’s clock hardware.

It’s toString method generates a String representation of its value using one specific ISO 8601 format. That format outputs zero, three, six or nine digits digits (milliseconds, microseconds, or nanoseconds) as necessary to represent the fraction-of-second.

If you want more flexible formatting, or other additional features, then apply an offset-from-UTC of zero, for UTC itself (ZoneOffset.UTC constant) to get a OffsetDateTime.

OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );

Dump to console…

System.out.println( "now.toString(): " + now );

When run…

now.toString(): 2014-01-21T23:42:03.522Z

Table of date-time types in Java, both modern and legacy.


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?

Table of which java.time library to use with which version of Java or 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.


Joda-Time

UPDATE: The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

Using the Joda-Time 3rd-party open-source free-of-cost library, you can get the current date-time in just one line of code.

Joda-Time inspired the new java.time.* classes in Java 8, but has a different architecture. You may use Joda-Time in older versions of Java. Joda-Time continues to work in Java 8 and continues to be actively maintained (as of 2014). However, the Joda-Time team does advise migration to java.time.

System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );

More detailed example code (Joda-Time 2.3)…

org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );

Dump to console…

System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );

When run…

Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z

For more example code doing time zone work, see my answer to a similar question.

Time Zone

I recommend you always specify a time zone rather than relying implicitly on the JVM’s current default time zone (which can change at any moment!). Such reliance seems to be a common cause of confusion and bugs in date-time work.

When calling now() pass the desired/expected time zone to be assigned. Use the DateTimeZone class.

DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );

That class holds a constant for UTC time zone.

DateTime now = DateTime.now( DateTimeZone.UTC );

If you truly want to use the JVM’s current default time zone, make an explicit call so your code is self-documenting.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

ISO 8601

Read about ISO 8601 formats. Both java.time and Joda-Time use that standard’s sensible formats as their defaults for both parsing and generating strings.


Actually, java.util.Date does have a time zone, buried deep under layers of source code. For most practical purposes, that time zone is ignored. So, as shorthand, we say java.util.Date has no time zone. Furthermore, that buried time zone is not the one used by Date’s toString method; that method uses the JVM’s current default time zone. All the more reason to avoid this confusing class and stick with Joda-Time and java.time.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 4
    `DateTime.now().toDateTime(DateTimeZone.UTC)` was what I was looking for! Thanks! – Managarm Jul 08 '15 at 09:59
  • 3
    @Managarm You can shorten that to: `DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;` – Basil Bourque Jul 08 '15 at 16:29
  • How to get this with Pure Java 8 `2014-01-21T15:34:29.933-08:00` in the example you used `new org.joda.time.DateTime()` – GOXR3PLUS Apr 22 '19 at 12:13
  • 1
    @GOXR3PLUS `ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString()` We get the current moment for a specified time zone. Next, lop off any micros/nanos. Then we convert to having only a mere offset-from-UTC (number of hours-minutes-seconds) rather than a full-blown time zone (a history of past, present, and future changes in the offset used by the people of a particular region). Lastly, we generate text representing the value in that `OffsetDateTime` per the standard ISO 8601 format used by default in its `toString` method. – Basil Bourque Apr 26 '19 at 04:15
  • See also [this similar answer from the same user](https://stackoverflow.com/a/39379431/6243352) – ggorlen Sep 20 '21 at 23:50
  • Does the Java 8 java.time.* package returns time from the system clock or from any server? Like if I want to use it to get current time, without relying on system clock as it could be changed to something else, would it also give me the changed time from the system clock or would it return the correct time? – Rudra Tiwari Mar 21 '22 at 06:54
  • 1
    @RudraTiwari *java.time* uses the host OS’ to get the current time. If you cannot trust the local system’s clock, then make a network call to a [time server](https://en.wikipedia.org/wiki/Time_server). This topic has been addressed in several existing Questions and Answers on Stack Overflow, so search to learn more. – Basil Bourque Mar 21 '22 at 11:55
442

java.util.Date has no specific time zone, although its value is most commonly thought of in relation to UTC. What makes you think it's in local time?

To be precise: the value within a java.util.Date is the number of milliseconds since the Unix epoch, which occurred at midnight January 1st 1970, UTC. The same epoch could also be described in other time zones, but the traditional description is in terms of UTC. As it's a number of milliseconds since a fixed epoch, the value within java.util.Date is the same around the world at any particular instant, regardless of local time zone.

I suspect the problem is that you're displaying it via an instance of Calendar which uses the local timezone, or possibly using Date.toString() which also uses the local timezone, or a SimpleDateFormat instance, which, by default, also uses local timezone.

If this isn't the problem, please post some sample code.

I would, however, recommend that you use Joda-Time anyway, which offers a much clearer API.

Cuga
  • 17,668
  • 31
  • 111
  • 166
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    I used a new Date() object and inserted into a DB table. DB is MySQL and when I use UTC_TIMESTAMP() function in MySQL, it works correctly, but when I insert the value of a new Date(), it is inserted in my local timezone. – Behrang Nov 21 '08 at 13:58
  • 6
    Then that's probably a driver issue. You may need to set your connection to UTC, or something like that. I've seen problems like this before, but the problem is not in java.util.Date. – Jon Skeet Nov 21 '08 at 14:07
  • Thanks. You are right. I looked at connection properties of mysql but I couldn't find the correct configuration. I asked another question: How to store a java.util.Date into a MySQL timestamp field in the UTC/GMT timezone? If you can, please help me there. – Behrang Nov 21 '08 at 16:06
  • Unfortunately I don't know - it's ages since I've done *any* JDBC, and none on MySQL, ever... – Jon Skeet Nov 21 '08 at 16:10
  • 15
    Behrang, according to http://stackoverflow.com/questions/4123534/before-writing-a-java-date-to-an-sql-timestamp-column-does-jdbc-translate-the-da/4124620#4124620, the MySQL JDBC driver converts a given `java.util.Timestamp` (or `java.util.Date`) to the server time zone. – Derek Mahar Dec 07 '10 at 21:02
  • 5
    @Mr. Cat: How are you determining that? Is it by writing `System.out.println(new Date())`? If so, you should be aware that it's the `toString()` method which is applying the time zone there... if that's not it, please give more details. – Jon Skeet Sep 07 '11 at 13:59
  • 6
    The `Date` documentation states : "Although the Date class is intended to reflect coordinated universal time (UTC), it may not do so exactly, depending on the host environment of the Java Virtual Machine.". For instance in my machine or my android phone, when I initialize a new Date object is set to GMT not UTC. No downvote from me, maybe I understood it wrong. – Ovidiu Latcu May 17 '12 at 13:04
  • 3
    @OvidiuLatcu: That's just talking about the fact that the accuracy of the system clock may be limited. I suspect you're referring to the results of `Date.toString()`, which again is just a display matter. But GMT and UTC are effectively the same time zone anyway. (There are some very subtle discrepancies, but nothing to concern ourselves with here.) – Jon Skeet May 31 '12 at 05:11
  • @JonSkeet Can you please point me to some resource that helps to understand why Joda time is thought to give a much clearer api ? – Geek Nov 06 '12 at 10:34
  • 1
    @Geek: I don't have a resource to hand, but the fact that Joda Time supports immutable types and has a much broader *range* of types is a good start. The Date and Calendar APIs are simply *awful*. – Jon Skeet Nov 06 '12 at 10:36
  • @Jon Skeet So you mean to say new Date().getTime() will return UTC milliseconds irrespsctive of tz? What makes you think Date's in UTC? – Kanagavelu Sugumar Dec 28 '12 at 11:00
  • 2
    @KanagaveluSugumar: Um, the documentation? The docs for `getTime()` state: "Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object." – Jon Skeet Dec 28 '12 at 11:08
  • @JonSkeet Thanks Jon. If date.toString() prints "Tue Dec 25 10:00:00 IST 2012" date.getTime() prints 1356409800000; Then date.getime() is the same "Tue Dec 25 10:00:00" in milliseconds or "Tue Dec 25 04:30:00" (IST-5.30 = GMT) ? Please help me to understand. – Kanagavelu Sugumar Dec 28 '12 at 12:19
  • 8
    @KanagaveluSugumar: `toString()` always uses the default time zone. `date.getTime()` definitely returns milliseconds since the Unix epoch, in UTC. It's most accurate to say that `Date` itself doesn't have a time zone at all - it's *just* an instant in time, which could be regarded in multiple time zones. But when you create an instance, it *doesn't* depend on your time zone. – Jon Skeet Dec 28 '12 at 12:33
  • @JonSkeet Thank you very much. Could you please tell me how java.sql.TimeStamp() will behave. This also don't have timezone in it? and ts.toString will take localTimezone()? and ts.getTime() will be in UTC ? – Kanagavelu Sugumar Dec 28 '12 at 13:02
  • 1
    @KanagaveluSugumar: We're well away from the original question now. Please ask a *new* question, following http://tinyurl.com/so-list – Jon Skeet Dec 28 '12 at 13:26
  • @JonSkeet http://stackoverflow.com/questions/14070572/does-java-sql-timestamp-is-timezone-specific – Kanagavelu Sugumar Dec 28 '12 at 13:54
  • 1
    This is a little nit-picky, but time/date conversions are a never-ending source of confusion for people who are just getting a handle on them, so I wanted to point this out. JonSkeet sprach: "date.getTime() definitely returns milliseconds since the Unix epoch, in UTC". The "in UTC" is redundant, here. The epoch happened when it was midnight in Greenwich (and elsewhere). At any given moment, "new Date().getTime()", anywhere on earth, should give you the same number. It's one of those rare bits of solid ground you can stand in this strange universe of calendar conversions. – Jemenake May 01 '13 at 15:03
  • 6
    @Jemenake: Actually it didn't happen when it was midnight in Greenwich, because the UK was on UTC+1 at the time. Just one of the odd bits of history. But I take your point - it's better to say "new Date().getTime() returns the milliseconds since the Unix epoch, which was midnight at the start of January 1st 1970, UTC". So the UTC is part of pinning down the epoch to a particular instant in time, not part of the result. – Jon Skeet May 01 '13 at 15:05
  • Correct background but the code answer is here http://stackoverflow.com/a/5236123/1643558 Make an SDF - UTC timezone, format date using that. SDF patterns - http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html – tgkprog Aug 19 '14 at 11:43
  • 2
    @tgkprog: You're assuming the OP wants a string. There's no indication that that's the case. – Jon Skeet Aug 19 '14 at 11:45
  • String or not - that answer says it more succinctly. Read your first, then that, then yours again, and it made more sense. some people can understand with code better. – tgkprog Aug 19 '14 at 12:48
  • `Date dt2 = new Date();` `System.out.println(" Hr " + dt2.getHours() + ", tz offset :" + dt2.getTimezoneOffset());` Runnung this code shows me local hour(UTC hour +5.5 hour) and timezone offset sas -330 which is correct local time as I'm in India. So apparently need to change the Date object's time to get UTC – tgkprog Aug 19 '14 at 12:56
  • 2
    @tgkprog: Did you read the documentation for the deprecated methods that you're calling there? (Note: "as interpreted in the local time zone".) Your conclusion about needing to change the contents of the `Date` to get UTC is entirely incorrect. – Jon Skeet Aug 19 '14 at 13:02
  • Hmm well I need this. Don't want to use Joda. Don't need internationalization so thought can ignore Date classes depreciated note (it says deprecated due to not able to internationalize). Just need current GMT time. so use new GreogorianCalender() OR ? Something in Java 6. Thanks for your time BTW : ) – tgkprog Aug 20 '14 at 15:56
  • Needs this == needs UTC time – tgkprog Aug 20 '14 at 20:56
  • 3
    @tgkprog: I suggest you ask a new question with your precise requirements, what you've tried etc. At the moment we don't know whether you're really looking for a textual representation, integer values so that you can test things like "Is it August?" etc. And you absolutely *shouldn't* ignore the `Date` methods deprecation - internationalization is just part of what's wrong with them, although it's one symptom of the fact that it always uses the system default time zone. Poor documentation there :( – Jon Skeet Aug 20 '14 at 21:09
  • Got answer from http://stackoverflow.com/questions/20482267/parsing-unix-time-to-java-on-android long to milli - set to Calendar. In the question cal.setTimeInMillis(long); – tgkprog Aug 21 '14 at 16:48
  • 3
    @tgkprog: Well I'm glad it helped you, even if you never really explained your problem... – Jon Skeet Aug 21 '14 at 16:49
  • I understand what the OP was asking. To say the JRE has no time zone I don't think is accurate. It has the TZ of the local machine it's running on. The JRE sources its time from the underlying OS, which is usually set to a local TZ. Although the JRE is aware of that TZ, it returns the local OS time to 'System.currentTimeMillis()' http://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/time-zone001.html#CBBIEBDG The OP was asking how they shift that local time back to UTC. This Class might help for that https://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html – Eurospoofer Mar 16 '17 at 05:01
  • @Eurospoofer: Where did anyone say the JRE has no time zone? Your comment is the one place that "JRE" appeared in this question (when I'm starting to add this comment). A `java.util.Date` value has no time zone, but that's entirely different. And no, `System.currentTimeMillis()` does *not* reflect the local time - it reflects the number of elapsed milliseconds since the Unix epoch, which does *not* depend on time zone. The docs you referred to are just saying that obtaining the value from the system clock is OS-specific. – Jon Skeet Mar 16 '17 at 09:25
283
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

//Local time zone   
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
Dan
  • 2,847
  • 1
  • 15
  • 2
  • 11
    Why do you parse with dateFormatLocal after using dateFormatGmt format... does not make sense by reading it. I am sure it works, but just wondering? – MindWire Jun 15 '12 at 21:20
  • 2
    setTimeZone did it (I guess you can also use getTimeZone("UTC") same thing as GMT?) – rogerdpack Feb 06 '13 at 00:05
  • 6
    but the time is dependent on device set time. If user has set wrong time on his device then you will get wrong UTC .correct me if am wrong – Basavaraj Hampali Aug 21 '13 at 16:48
  • @BasavarajHampali but in todays world most of the devices are connected to the internet which corrects incorrect time – Akshat Agarwal Oct 30 '13 at 15:18
  • 3
    There is no time difference between Coordinated Universal Time (UTC) and Greenwich Mean Time (GMT) – slott Dec 16 '14 at 10:11
  • SimpleDateFormat is for formatting what a time looks like, it doesn't shift the time. the code above simply formats the local time to the pattern in the SimpleDateFormat. The time itself, from the new Date(), must be shifted to UTC first – Eurospoofer Mar 16 '17 at 05:10
  • UTC and GMT may be interchangeable for now, but to put it in Java terms, GMT is 'deprecated' and may go out of sync with UTC in the future. – JN01 May 08 '17 at 11:35
  • Greenwich Mean Time (GMT) is often interchanged or confused with Coordinated Universal Time (UTC). But GMT is a time zone and UTC is a time standard. https://www.timeanddate.com/time/gmt-utc-time.html – axiopisty Oct 19 '18 at 23:00
91

This definitely returns UTC time: as String and Date objects !

static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

public static Date getUTCdatetimeAsDate() {
    // note: doesn't check for null
    return stringDateToDate(getUTCdatetimeAsString());
}

public static String getUTCdatetimeAsString() {
    final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    final String utcTime = sdf.format(new Date());

    return utcTime;
}

public static Date stringDateToDate(String StrDate) {
    Date dateToReturn = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);

    try {
        dateToReturn = (Date)dateFormat.parse(StrDate);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return dateToReturn;
}
Sagar Chapagain
  • 1,683
  • 2
  • 16
  • 26
Someone Somewhere
  • 23,475
  • 11
  • 118
  • 166
  • In my answer I forgot to show how DATEFORMAT is defined: `static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";` – Someone Somewhere Jul 26 '11 at 19:39
  • 21
    Please avoid starting method names with uppercase in Java. See the [Java coding conventions](http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-135099.html#367) for method names. – Florian Schrofner May 02 '15 at 14:42
  • 2
    As am redirected to this answer, Calling `new Date()` will never return the correct UTC time, if the device time is wrong. – Sanoop Surendran Mar 02 '17 at 08:55
  • does this method get time depend upon device calendar? – Arnold Brown Nov 09 '18 at 04:24
  • One thing to note. Any solution that needs to get a Date or Timestamp in UTC, it looks like the key is to not re-use the SimpleDateFormat, but rather use one to get UTC into a string, then create another UTC when converting the string to either a Date or Timestamp Object. I noticed that if you try to reuse the same SimpleDateFormat then the resulting Date/Timestamp Object will revert to the local timezone instead of UTC. – Brian Begun Feb 26 '19 at 04:28
68
    Calendar c = Calendar.getInstance();
    System.out.println("current: "+c.getTime());

    TimeZone z = c.getTimeZone();
    int offset = z.getRawOffset();
    if(z.inDaylightTime(new Date())){
        offset = offset + z.getDSTSavings();
    }
    int offsetHrs = offset / 1000 / 60 / 60;
    int offsetMins = offset / 1000 / 60 % 60;

    System.out.println("offset: " + offsetHrs);
    System.out.println("offset: " + offsetMins);

    c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
    c.add(Calendar.MINUTE, (-offsetMins));

    System.out.println("GMT Time: "+c.getTime());
Eugene Lazutkin
  • 43,776
  • 8
  • 49
  • 56
Ahmad Nadeem
  • 2,056
  • 1
  • 18
  • 19
57

Actually not time, but it's representation could be changed.

SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));

Time is the same in any point of the Earth, but our perception of time could be different depending on location.

Anthony
  • 12,407
  • 12
  • 64
  • 88
  • Yep, nice and clean solution. It just worries me, if its ineffective to create a new Date object instead of just getting Calendar instance? – Beemo Oct 06 '15 at 14:53
  • It will be optimized by JVM and HotSpot will execute the most effective x86 code possible – Anthony Oct 07 '15 at 04:49
  • Right, one time but many presentations, depends on location. – Iceberg Nov 30 '20 at 18:20
  • A bit clarification, `UTC` is a time **standard**,rather than a *timezone*. Actually "GMT" is the *timezone* which in same time as UTC practically. – phray2002 Sep 13 '21 at 03:52
19

This works for getting UTC milliseconds in Android.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
moberme
  • 669
  • 7
  • 13
18

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); Then all operations performed using the aGMTCalendar object will be done with the GMT time zone and will not have the daylight savings time or fixed offsets applied

Wrong!

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
aGMTCalendar.getTime(); //or getTimeInMillis()

and

Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();

will return the same time. Idem for

new Date(); //it's not GMT.
javanna
  • 59,145
  • 14
  • 144
  • 125
simpatico
  • 10,709
  • 20
  • 81
  • 126
17

This code prints the current time UTC.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;


public class Test
{
    public static void main(final String[] args) throws ParseException
    {
        final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        f.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(f.format(new Date()));
    }
}

Result

2013-10-26 14:37:48 UTC
Adam
  • 2,616
  • 33
  • 29
10

Here is what seems to be incorrect in Jon Skeet's answer. He said:

java.util.Date is always in UTC. What makes you think it's in local time? I suspect the problem is that you're displaying it via an instance of Calendar which uses the local timezone, or possibly using Date.toString() which also uses the local timezone.

However, the code:

System.out.println(new java.util.Date().getHours() + " hours");

gives the local hours, not GMT (UTC hours), using no Calendar and no SimpleDateFormat at all.

That is why is seems something is incorrect.

Putting together the responses, the code:

System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
                           .get(Calendar.HOUR_OF_DAY) + " Hours");

shows the GMT hours instead of the local hours -- note that getTime.getHours() is missing because that would create a Date() object, which theoretically stores the date in GMT, but gives back the hours in the local time zone.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Dana Wilson
  • 125
  • 1
  • 3
  • 9
    I hadn't seen this answer before, but if you read the documentation for the deprecated `Date.getHours()` method, it makes it very clear: "The returned value is a number (0 through 23) representing the hour within the day that contains or begins with the instant in time represented by this Date object, **as interpreted in the local time zone**." (Emphasis mine.) It's the `getHours()` method which interprets the value within the local time zone - it's not part of the state of the `Date` object itself. – Jon Skeet May 11 '13 at 13:57
  • 3
    As Jon Skeet correctly stated, a java.util.Date object **has no time zone**. But confusingly, the methods `toString` and `getHours` apply the default time zone to their output. So, naïve programmers are easily fooled as it *seems* a Date has a time zone but in fact does not. – Basil Bourque Jan 22 '14 at 01:14
  • The `getHours()` method has been deprecated for more than 25 years exactly because it works unreliably across time zones. So what you are showing is not that Jon Skeet was wrong (which he wasn’t), but that there was good reason for the deprecation. – Ole V.V. Mar 26 '22 at 12:19
7

If you want a Date object with fields adjusted for UTC you can do it like this with Joda Time:

import org.joda.time.DateTimeZone;
import java.util.Date;

...

Date local = new Date();
System.out.println("Local: " + local);
DateTimeZone zone = DateTimeZone.getDefault();
long utc = zone.convertLocalToUTC(local.getTime(), false);
System.out.println("UTC: " + new Date(utc));
huljas
  • 147
  • 1
  • 3
  • 1
    You are working too hard. [Joda-Time](http://www.joda.org/joda-time/) can do this in a single line of code. See [my own answer](http://stackoverflow.com/a/19632076/642706) on this question. Call the `.toDateTime` method and pass the constant for the UTC time zone. – Basil Bourque Nov 08 '13 at 11:26
  • 1
    DateTime utcDate = new DateTime().toDateTime(DateTimeZone.UTC) – Maciej Miklas Jan 23 '14 at 07:58
6

You can directly use this

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
King of Masses
  • 18,405
  • 4
  • 60
  • 77
nithinreddy
  • 6,167
  • 4
  • 38
  • 44
6

You can use:

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

Then all operations performed using the aGMTCalendar object will be done with the GMT time zone and will not have the daylight savings time or fixed offsets applied. I think the previous poster is correct that the Date() object always returns a GMT it's not until you go to do something with the date object that it gets converted to the local time zone.

mjh2007
  • 776
  • 1
  • 8
  • 17
6

Here is my implementation of toUTC:

    public static Date toUTC(Date date){
    long datems = date.getTime();
    long timezoneoffset = TimeZone.getDefault().getOffset(datems);
    datems -= timezoneoffset;
    return new Date(datems);
}

There's probably several ways to improve it, but it works for me.

Ashallar
  • 990
  • 8
  • 15
6
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
stealthyninja
  • 10,343
  • 11
  • 51
  • 59
Justin
  • 61
  • 1
  • 1
5

Here an other suggestion to get a GMT Timestamp object:

import java.sql.Timestamp;
import java.util.Calendar;

...

private static Timestamp getGMT() {
   Calendar cal = Calendar.getInstance();
   return new Timestamp(cal.getTimeInMillis()
                       -cal.get(Calendar.ZONE_OFFSET)
                       -cal.get(Calendar.DST_OFFSET));
}
Rene
  • 59
  • 1
  • 1
5

Here is another way to get GMT time in String format

String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString =  sdf.format(new Date());
pb2q
  • 58,613
  • 19
  • 146
  • 147
shahtapa
  • 51
  • 1
  • 1
4

With:

Calendar cal = Calendar.getInstance();

Then cal have the current date and time.
You also could get the current Date and Time for timezone with:

Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));

You could ask cal.get(Calendar.DATE); or other Calendar constant about others details.
Date and Timestamp are deprecated in Java. Calendar class it isn't.

user2427
  • 7,842
  • 19
  • 61
  • 71
  • 6
    Certain methods and constructors of Date and Timestamp are deprecated, but the classes themselves are not. – Powerlord Nov 21 '08 at 13:19
4

The Simple Function that you can use:

Edit: this version uses the modern java.time classes.

private static final DateTimeFormatter FORMATTER
        = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss z");

public static String getUtcDateTime() {
    return ZonedDateTime.now(ZoneId.of("Etc/UTC")).format(FORMATTER);
}

Return value from the method:

26-03-2022 17:38:55 UTC

Original function:

 public String getUTC_DateTime() {
    SimpleDateFormat dateTimeFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss z");
    dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));//gmt
    return dateTimeFormat.format(new Date());

}

return of above function:

26-03-2022 08:07:21 UTC 
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Ammar
  • 765
  • 1
  • 8
  • 18
  • Thanks, @OleV.V. making it clear and more updated, for me and everyone. In short your comment also teach me well. keep it up. – Ammar Mar 26 '22 at 15:10
3

Just to make this simpler, to create a Date in UTC you can use Calendar :

Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Which will construct a new instance for Calendar using the "UTC" TimeZone.

If you need a Date object from that calendar you could just use getTime().

Ovidiu Latcu
  • 71,607
  • 15
  • 76
  • 84
3

Converting Current DateTime in UTC:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

DateTimeZone dateTimeZone = DateTimeZone.getDefault(); //Default Time Zone

DateTime currDateTime = new DateTime(); //Current DateTime

long utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(), false);

String currTime = formatter.print(utcTime); //UTC time converted to string from long in format of formatter

currDateTime = formatter.parseDateTime(currTime); //Converted to DateTime in UTC
sjain
  • 23,126
  • 28
  • 107
  • 185
  • 1
    You are doing too much work here. (a) The formatter patter you define is already built into a DateTime by default; just call `toString` on a DateTime to get that [ISO 8601](http://en.wikipedia.org/wiki/ISO_8601) string pattern. (b) Way too much code to convert between time zones. Simply call "toDateTime" and pass a time zone object. Like this: `myDateTime.toDateTime( DateTimeZone.UTC )`. For a specific time zone, instantiate and pass a time zone object based on a [proper name](http://joda-time.sourceforge.net/timezones.html), call `myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) )`. – Basil Bourque Jan 23 '14 at 21:48
3
public static void main(String args[]){
    LocalDate date=LocalDate.now();  
    System.out.println("Current date = "+date);
}
Alsatian
  • 3,086
  • 4
  • 25
  • 40
3

Sample code to render system time in a specific time zone and a specific format.

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class TimZoneTest {
    public static void main (String[] args){
        //<GMT><+/-><hour>:<minutes>
        // Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.

        System.out.println(my_time_in("GMT-5:00", "MM/dd/yyyy HH:mm:ss") );
        System.out.println(my_time_in("GMT+5:30", "'at' HH:mm a z 'on' MM/dd/yyyy"));

        System.out.println("---------------------------------------------");
        // Alternate format 
        System.out.println(my_time_in("America/Los_Angeles", "'at' HH:mm a z 'on' MM/dd/yyyy") );
        System.out.println(my_time_in("America/Buenos_Aires", "'at' HH:mm a z 'on' MM/dd/yyyy") );


    }

    public static String my_time_in(String target_time_zone, String format){
        TimeZone tz = TimeZone.getTimeZone(target_time_zone);
        Date date = Calendar.getInstance().getTime();
        SimpleDateFormat date_format_gmt = new SimpleDateFormat(format);
        date_format_gmt.setTimeZone(tz);
        return date_format_gmt.format(date);
    }

}

Output

10/08/2011 21:07:21
at 07:37 AM GMT+05:30 on 10/09/2011
at 19:07 PM PDT on 10/08/2011
at 23:07 PM ART on 10/08/2011
so_mv
  • 3,939
  • 5
  • 29
  • 40
2

This worked for me, returns the timestamp in GMT!

    Date currDate;
    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

    long currTime = 0;
    try {

        currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
        currTime = currDate.getTime();
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
Bogdan
  • 41
  • 3
2

Current date in the UTC

Instant.now().toString().replaceAll("T.*", "");
Arefe
  • 11,321
  • 18
  • 114
  • 168
2

This is the way I do it when I need to output a Date object, which is usually the case when you need to save a Date in an SQL database and I want it to be in UTC. I just subtract the offset time of the local time zone.

    ZonedDateTime now = ZonedDateTime.now();
    Date nowUTC = new Date(1000 * (now.toEpochSecond() - now.getOffset().getTotalSeconds()));

--UPDATE Basil's suggestion for a cleaner way to have the same result would be

    Date nowUTC = Date.from(ZonedDateTime.now().toInstant());

BUT after testing this in a non-UTC java system env, I saw that the results are not the same. With Basil's code, the Date is still on local zone

JohnPan
  • 1,185
  • 11
  • 21
  • You are mixing the terrible legacy class `Date` with its replacements, the modern *java.time* classes defined in JSR 310. There is no no need to use either `java.util.Date` or `java.sql.Date` class ever again. The functionality is entirely replaced by the *java.time* classes (specifically `Instant`, not `ZonedDateTime`). `Instant.now()` – Basil Bourque Jan 20 '22 at 22:12
  • 1
    Furthermore, if you really want a `java.util.Date` object, to interoperate with old code not yet updated to *java.time*, simply call the convenient **conversion methods added to the old classes**: `java.util.Date d = Date.fromInstant( myInstant );`. If you have a `ZonedDateTime`, you can extract an `Instant`: `java.util.Date.from( myZonedDateTime.toInstant() )`. No need for the calculations seen in this Answer. – Basil Bourque Jan 20 '22 at 22:13
1

To put it simple. A calendar object stores information about time zone but when you perform cal.getTime() then the timezone information will be lost. So for Timezone conversions I will advice to use DateFormat classes...

Hitesh
  • 703
  • 1
  • 9
  • 14
1

Use this Class to get ever the right UTC Time from a Online NTP Server:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


class NTP_UTC_Time
{
private static final String TAG = "SntpClient";

private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;

private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;

// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

private long mNtpTime;

public boolean requestTime(String host, int timeout) {
    try {
        DatagramSocket socket = new DatagramSocket();
        socket.setSoTimeout(timeout);
        InetAddress address = InetAddress.getByName(host);
        byte[] buffer = new byte[NTP_PACKET_SIZE];
        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

        buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

        writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

        socket.send(request);

        // read the response
        DatagramPacket response = new DatagramPacket(buffer, buffer.length);
        socket.receive(response);          
        socket.close();

        mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);            
    } catch (Exception e) {
      //  if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
        return false;
    }

    return true;
}


public long getNtpTime() {
    return mNtpTime;
}


/**
 * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
 */
private long read32(byte[] buffer, int offset) {
    byte b0 = buffer[offset];
    byte b1 = buffer[offset+1];
    byte b2 = buffer[offset+2];
    byte b3 = buffer[offset+3];

    // convert signed bytes to unsigned values
    int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
    int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
    int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
    int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);

    return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
}

/**
 * Reads the NTP time stamp at the given offset in the buffer and returns 
 * it as a system time (milliseconds since January 1, 1970).
 */    
private long readTimeStamp(byte[] buffer, int offset) {
    long seconds = read32(buffer, offset);
    long fraction = read32(buffer, offset + 4);
    return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);        
}

/**
 * Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
 */    
private void writeTimeStamp(byte[] buffer, int offset) {        
    int ofs =  offset++;

    for (int i=ofs;i<(ofs+8);i++)
      buffer[i] = (byte)(0);             
}

}

And use it with:

        long now = 0;

        NTP_UTC_Time client = new NTP_UTC_Time();

        if (client.requestTime("pool.ntp.org", 2000)) {              
          now = client.getNtpTime();
        }

If you need UTC Time "now" as DateTimeString use function:

private String get_UTC_Datetime_from_timestamp(long timeStamp){

    try{

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();

        int tzt = tz.getOffset(System.currentTimeMillis());

        timeStamp -= tzt;

        // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
        DateFormat sdf = new SimpleDateFormat();
        Date netDate = (new Date(timeStamp));
        return sdf.format(netDate);
    }
    catch(Exception ex){
        return "";
     }
    } 

and use it with:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
Ingo
  • 5,239
  • 1
  • 30
  • 24
  • In single line
     Calendar utcTime = Calendar.getInstance().add(Calendar.MILLISECOND, -time.getTimeZone().getOffset(time.getTimeInMillis()));
    – Harun Nov 28 '13 at 09:24
  • 2
    Yes, but this calls the local Device Time, which could changed manualy from the user to a false DateTime – Ingo Dec 03 '13 at 14:59
1

this is my implementation:

public static String GetCurrentTimeStamp()
{
    Calendar cal=Calendar.getInstance();
    long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
    return new java.sql.Timestamp(System.currentTimeMillis()+offset).toString();    
}
Gal Rom
  • 6,221
  • 3
  • 41
  • 33
1

If you want to avoid parsing the date and just want a timestamp in GMT, you could use:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));
Matthias van der Vlies
  • 3,834
  • 3
  • 24
  • 28
1
public class CurrentUtcDate 
{
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println("UTC Time is: " + dateFormat.format(date));
    }
}

Output:

UTC Time is: 22-01-2018 13:14:35

You can change the date format as needed.

Pang
  • 9,564
  • 146
  • 81
  • 122
  • 3
    Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat`. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). Also what are you providing that isn’t already in the answers by Dan, Antonio and others? – Ole V.V. Jul 04 '18 at 05:11
  • 2
    (a) How does this Answer add value over the dozens of existing Answers? (b) The troublesome classes used here were supplanted years ago by the modern *java.time* classes. Suggesting their use in 2018 is poor advice. – Basil Bourque Jul 04 '18 at 07:27
  • I am sorry, But that time I did't use time API. Anyway I agree with your point and will try my best to post latest better solutions. – santoshlokhande Jun 05 '21 at 14:16
0

If you're using joda time and want the current time in milliseconds without your local offset you can use this:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
Managarm
  • 1,070
  • 3
  • 12
  • 25
0

Use java.time package and include below code-

ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );

or

LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );

depending on your application need.

Asif
  • 465
  • 5
  • 6
  • 1
    (A) If using an offset (`ZoneOffset`) rather than a time zone (`ZoneId`), the `OffsetDateTime` is more appropriate than `ZonedDateTime`. (B) `LocalDateTime` should not be used for capturing the current moment as it has no concept of time zone or offset-from-UTC. (C) Other pre-existing Answers have covered this material and done a better job. I don’t see how this Answer adds value. – Basil Bourque Nov 02 '18 at 02:34
-1

If you are developing for Android and you are familiar with the Calendar class then here is a quick relevant code to convert your current time to UTC time. But remember it will not convert the timezone. (Converting timezone is another different story)

public Calendar getMyTimeInUTC(Calendar calendar) {
    final int utcOffset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
    calendar.setTimeInMillis(calendar.getTimeInMillis() - utcOffset);
    return calendar;
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Harpreet
  • 2,990
  • 3
  • 38
  • 52
  • 1
    If you are familiar with `Calendar` in 2023, then you need to read up on what has happened with Java in the last 10 years. `Calendar` was poorly deisgned and cumbersome to work with. Nicely illustrated by the fact that what you are doing in your code is wrong. Instead use [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/index.html) as illustrated in some of the other answers. – Ole V.V. Mar 31 '23 at 03:36
  • Hello @OleV.V. Thanks for sharing that information. But sorry for us (Android Developers) the `Calendar` is the only option left by Java so far. We don't have the updates of Java's new approaches. We still deal with J8 classes, that's the max support for us by Google/Android Environment as Java is almost obsolete by the Android platform. – Harpreet Mar 31 '23 at 13:54
  • Not so. java.time has been built in since API level 26 Oreo, that’s already a long time now. If you are still developing for older Android versions, you can have access to nearly all of java.time through [desugaring](https://developer.android.com/studio/write/java8-support). – Ole V.V. Mar 31 '23 at 19:13