The System.out.println(cal_Two.getTime()) invocation returns a Date from getTime(). It is the Date which is getting converted to a string for println, and that conversion will use the default IST timezone in your case.

You'll need to explicitly use DateFormat.setTimeZone() to print the Date in the desired timezone.

EDIT: Courtesy of @Laurynas, consider this:

TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
SimpleDateFormat simpleDateFormat = 
       new SimpleDateFormat("EE MMM dd HH:mm:ss zzz yyyy", Locale.US);
simpleDateFormat.setTimeZone(timeZone);

System.out.println("Time zone: " + timeZone.getID());
System.out.println("default time zone: " + TimeZone.getDefault().getID());
System.out.println();

System.out.println("UTC:     " + simpleDateFormat.format(calendar.getTime()));
System.out.println("Default: " + calendar.getTime());
Answer from mockinterface on Stack Overflow
Top answer
1 of 8
172

The System.out.println(cal_Two.getTime()) invocation returns a Date from getTime(). It is the Date which is getting converted to a string for println, and that conversion will use the default IST timezone in your case.

You'll need to explicitly use DateFormat.setTimeZone() to print the Date in the desired timezone.

EDIT: Courtesy of @Laurynas, consider this:

TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
SimpleDateFormat simpleDateFormat = 
       new SimpleDateFormat("EE MMM dd HH:mm:ss zzz yyyy", Locale.US);
simpleDateFormat.setTimeZone(timeZone);

System.out.println("Time zone: " + timeZone.getID());
System.out.println("default time zone: " + TimeZone.getDefault().getID());
System.out.println();

System.out.println("UTC:     " + simpleDateFormat.format(calendar.getTime()));
System.out.println("Default: " + calendar.getTime());
2 of 8
22

java.util.Date is independent of the timezone. When you print cal_Two though the Calendar instance has got its timezone set to UTC, cal_Two.getTime() would return a Date instance which does not have a timezone (and is always in the default timezone)

Calendar cal_Two = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(cal_Two.getTime());
System.out.println(cal_Two.getTimeZone());

Output:

 Sat Jan 25 16:40:28 IST 2014
    sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] 

From the javadoc of TimeZone.setDefault()

Sets the TimeZone that is returned by the getDefault method. If zone is null, reset the default to the value it had originally when the VM first started.

Hence, moving your setDefault() before cal_Two is instantiated you would get the correct result.

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
Calendar cal_Two = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(cal_Two.getTime());

Calendar cal_Three = Calendar.getInstance();
System.out.println(cal_Three.getTime());

Output:

Sat Jan 25 11:15:29 UTC 2014
Sat Jan 25 11:15:29 UTC 2014
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › TimeZone.html
TimeZone (Java Platform SE 8 )
2 weeks ago - Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone. Because this value is not affected by daylight saving time, it is called raw offset. If an underlying TimeZone implementation subclass supports historical GMT offset changes, the method returns ...
🌐
Microsoft Learn
learn.microsoft.com › en-us › answers › questions › 2277185 › getting-utc-time-from-coordinates-using-the-timezo
Getting UTC Time from Coordinates Using the Timezone API - Microsoft Q&A
May 19, 2025 - This will return the timezone details, ... Once you have the timezone details, you can apply the appropriate offset to your local time of "2025-05-19T18:15:00" to convert it into UTC....
🌐
Phrase
phrase.com › home › resources › blog › how to get the current utc date and time in java?
Solved: How to Get the Current UTC Date and Time in Java?
September 23, 2022 - package com.thdespou; import java.util.Date; import java.util.TimeZone; public class Main { public static void main(String[] args) { // Date Date now = new Date(); System.out.println("Current Date in milliseconds is :" + now.getTime()); // Display the instant in three different time zones TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); System.out.println(now); TimeZone.setDefault( TimeZone.getTimeZone("GMT")); System.out.println(now); TimeZone.setDefault( TimeZone.getTimeZone("UTC")); System.out.println(now); } }
🌐
Baeldung
baeldung.com › home › java › java dates › display all time zones with gmt and utc in java
Display All Time Zones With GMT and UTC in Java | Baeldung
March 17, 2024 - Time zones in UTC: (UTC+14:00) Pacific/Apia (UTC+14:00) Pacific/Kiritimati (UTC+14:00) Pacific/Tongatapu (UTC+14:00) Etc/GMT-14 · Java 8 makes this task easier by using the Stream and Date and Time APIs.
🌐
Time and Date
timeanddate.com › time zones › world › utc
UTC Time Standard
UTC—Coordinated Universal Time—is the 24-hour time standard used as a basis for civil time today. All time zones are defined by their offset from UTC.
🌐
TimeAndDate
timeanddate.com › time zones › world clock › utc
Current UTC — Coordinated Universal Time
Current local time in UTC. See a clock with the accurate time and find out where it is observed.
🌐
Oracle
docs.oracle.com › javase › 6 › docs › api › java › util › TimeZone.html
TimeZone (Java Platform SE 6)
Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone. Because this value is not affected by daylight saving time, it is called raw offset. If an underlying TimeZone implementation subclass supports historical GMT offset changes, the method returns ...
🌐
Bureau of Economic Geology
beg.utexas.edu › lmod › agi.servlet › doc › detail › java › util › TimeZone.html
java.util Class TimeZone
TimeZone tz = TimeZone.getTimeZone("PST"); You can use getAvailableIDs method to iterate through all the supported time zone IDs. You can then choose a supported ID to get a TimeZone.
Find elsewhere
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › util › TimeZone.html
TimeZone (Java SE 17 & JDK 17)
January 20, 2026 - Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone. static TimeZone · getTimeZone · (String ID) Gets the TimeZone for the given ID. static TimeZone · getTimeZone · (ZoneId zoneId) Gets the TimeZone for the given zoneId.
🌐
GeeksforGeeks
geeksforgeeks.org › java › timezone-gettimezone-method-in-java-with-examples
TimeZone getTimeZone() Method in Java with Examples - GeeksforGeeks
January 2, 2019 - The TimeZone is: sun.util.calendar.ZoneInfo[id="GMT+05:30", offset=19800000, dstSavings=0, useDaylight=false, transitions=0, lastRule=null] Example 2: ... // Java code to illustrate getTimeZone() method import java.util.*; public class TimeZoneDemo { public static void main(String args[]) { // Creating a TimeZone TimeZone the_time_zone = TimeZone.getDefault(); // Knowing the TimeZone System.out.println("The TimeZone is: " + the_time_zone .getTimeZone("GMT-3:30")); } }
🌐
Jenkov
jenkov.com › tutorials › java-date-time › java-util-timezone.html
Java's java.util.TimeZone
June 23, 2014 - The getOffset() method returns the offset in milliseconds for the given time zone to UTC, at the given time. For instance, the "Europe/Copenhagen" time zone may have one hour offset during the winter, and two hours during the summer time due ...
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › Date › getTimezoneOffset
Date.prototype.getTimezoneOffset() - JavaScript | MDN
The getTimezoneOffset() method of Date instances returns the difference, in minutes, between this date as evaluated in the UTC time zone, and the same date as evaluated in the local time zone.
Top answer
1 of 3
5

The Timezone class does exactly what you are looking for. As far as I know, it covers the entire tz database, and I know that it covers some historical changes in the database, as shown below.

Timezone tz = Timezone.getTimeZone('America/New_York');

//before the 2007 shift of DST into November
DateTime dtpre = DateTime.newInstanceGMT(2000, 11, 1, 0, 0, 0);
system.debug(tz.getOffset(dtpre));   //-18000000 (= -5 hours = EST)

//after the 2007 shift of DST into November
DateTime dtpost = DateTime.newInstanceGMT(2012, 11, 1, 0, 0, 0);
system.debug(tz.getOffset(dtpost));   //-14400000 (= -4 hours = EDT)

It also gets the exact time at which DST starts or ends.

Timezone tz = Timezone.getTimeZone('America/New_York');

DateTime dtpre = DateTime.newInstanceGMT(2014, 11, 2, 5, 59, 59);  //1:59:59AM local
system.debug(tz.getOffset(dtpre));   //-14400000 (= -4 hours = still on DST)

DateTime dtpost = DateTime.newInstanceGMT(2014, 11, 2, 6, 0, 0); //2:00:00AM local
system.debug(tz.getOffset(dtpost));  //-18000000 (= -5 hours = back one hour)
2 of 3
2

The following anonymous apex uses TimeZone.getOffset() to convert from the time in New York to UTC. Note that the getOffset() method is detecting the DST change from the perspective of a UTC input rather than the target timezones input. I.e. The offset will change between 5:59 am and 6 am in UTC rather than between 1:59 am and 2 am EST.

My current solution for this is to check the reverse offset once in UTC. If it differs for the original offset use the corrected UTC offset.

If I create a UTC DateTime for the 2nd of November 2014 at 2:00:00 a.m in EST then getOffset will return 4 hours. Checking the offset again from the 2nd of November 2014 at 6:00:00 a.m in UTC shows an offset of 5 hours. So we should actually use the 5 hour offset to determine the correct UTC value.

TimeZone tz = UserInfo.getTimeZone();
// Your results for this assertion will of course vary.
System.assertEquals('New Zealand Standard Time', tz.getDisplayName(), 'Proving the current user is in a completely different timezone to UTC and the source Timezone');

string customerTimeZoneSidId = 'America/New_York';

System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 0, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 20:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 1, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 21:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 2, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 22:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 3, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 23:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 4, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 0:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 5, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 1:00:00'), 'Sunday, 2 November 2014 at 1:00:00 a.m.');
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 5, 59, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 1:59:00'), 'Sunday, 2 November 2014 at 1:59:00 a.m.');

// Note, skips 6 am UTC to 7 am UTC

// http://www.timeanddate.com/worldclock/converted.html?iso=20141102T02&p1=179&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 7, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 2:00:00'), 'Sunday, 2 November 2014 at 2:00:00 a.m');

// http://www.timeanddate.com/worldclock/converted.html?iso=20141102T03&p1=179&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 8, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 3:00:00'), 'Sunday, 2 November 2014 at 3:00:00 a.m.');

public DateTime toUtc(string customerTimeZone, string timeZoneString) {
    DateTime customerDateTime = DateTime.valueofGmt(timeZoneString);

    TimeZone ctz = TimeZone.getTimeZone(customerTimeZone);

    integer offsetToUtc = ctz.getOffset(customerDateTime);

    //System.debug('GMT Offset: ' + offsetToUtc + ' (milliseconds) ');

    DateTime utcDateTime = customerDateTime.addMinutes(-1 * offsetToUtc / (1000 * 60));

    // Reverse check as getOffset will be working against UTC. We can't create an instance in the customers time zone.
    // May need to use the revised UTC offset once we can actaully work from UTC.
    integer utcOffset = ctz.getOffset(utcDateTime);
    //DateTime revisedCustomerDateTime = utcDateTime.addMinutes(utcOffset / (1000 * 60));
    // Exercise for the reader, check what occurs with the other DST transition
    if(offsetToUtc != utcOffset) {
        System.debug(LoggingLevel.Warn, 'Revised UTC offset to ' + utcOffset);
        utcDateTime = customerDateTime.addMinutes(-1 * utcOffset / (1000 * 60));
    }

    System.debug('Converted ' + customerDateTime + ' to ' + utcDateTime);

    return utcDateTime;
}

Extra test cases you can try:

customerTimeZoneSidId = 'America/El_Salvador'; // San Salvador, El Salvador
//http://www.timeanddate.com/worldclock/converted.html?iso=20141101T18&p1=228&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 0, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 18:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 1, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 19:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 2, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 20:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 3, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 21:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 4, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 22:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 5, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-01 23:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 6, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 0:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 7, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 1:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 7, 59, 0), toUtc(customerTimeZoneSidId, '2014-11-02 1:59:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 8, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 2:00:00'));

customerTimeZoneSidId = 'Asia/Kathmandu'; // Nepal
//http://www.timeanddate.com/worldclock/converted.html?iso=20141102T1045&p1=117&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 5, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 10:45:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 6, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 11:45:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 7, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 12:45:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 8, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 13:45:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 9, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 14:45:00'));

customerTimeZoneSidId = 'America/Chicago'; // Central Standard Time
//http://www.timeanddate.com/worldclock/converted.html?iso=20141102T00&p1=64&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 5, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 0:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 6, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 1:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 8, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 2:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 9, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 3:00:00'));
System.assertEquals(DateTime.newInstanceGMT(2014, 11, 2, 10, 0, 0),  toUtc(customerTimeZoneSidId, '2014-11-02 4:00:00'))

Transition into Summer Time (losing 1 hour):

customerTimeZoneSidId = 'Europe/Lisbon';
//http://www.timeanddate.com/worldclock/converted.html?iso=20140330T02&p1=133&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 3, 29, 23, 0, 0), toUtc(customerTimeZoneSidId, '2014-03-29 23:00:00')); 

System.assertEquals(DateTime.newInstanceGMT(2014, 3, 30, 0, 0, 0), toUtc(customerTimeZoneSidId, '2014-03-30 00:00:00')); 
System.assertEquals(DateTime.newInstanceGMT(2014, 3, 30, 0, 59, 0), toUtc(customerTimeZoneSidId, '2014-03-30 00:59:00')); 

// http://www.timeanddate.com/worldclock/converted.html?iso=20140330T01&p1=133&p2=0
// The time Sunday, 30 March 2014 at 1:00:00 a.m. does not exist in Lisbon. 
// Daylight Saving Time skipped one hour.
//System.assertEquals(DateTime.newInstanceGMT(2014, 3, 30, 0, 0, 0), toUtc(customerTimeZoneSidId, '2014-03-30 01:00:00')); // Will Fail 

//http://www.timeanddate.com/worldclock/converted.html?iso=20140330T02&p1=133&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 3, 30, 1, 0, 0), toUtc(customerTimeZoneSidId, '2014-03-30 02:00:00')); 
//http://www.timeanddate.com/worldclock/converted.html?iso=20140330T03&p1=133&p2=0
System.assertEquals(DateTime.newInstanceGMT(2014, 3, 30, 2, 0, 0), toUtc(customerTimeZoneSidId, '2014-03-30 03:00:00')); 
System.assertEquals(DateTime.newInstanceGMT(2014, 3, 30, 3, 0, 0), toUtc(customerTimeZoneSidId, '2014-03-30 04:00:00')); 
🌐
GitHub
github.com › quarkusio › quarkus › discussions › 39923
Timezone UTC not working without -Duser.timezone=UTC · quarkusio/quarkus · Discussion #39923
April 5, 2024 - public App() { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); } private void registerFilters(HashSet<Class<?>> set) { set.add(JacksonJavaTimeMappingProvider.class); } @Provider public class JacksonJavaTimeMappingProvider implements ContextResolver<ObjectMapper> { private final ObjectMapper mapper; public JacksonJavaTimeMappingProvider() { mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); mapper.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault())); } @Override public ObjectMapper getContext(Class<?> type) { return mapper; } } Since upgrading to the latest version, I have had the problem that Hibernate saves all dates in the database with European time.
Author   quarkusio
🌐
Oracle
docs.oracle.com › en › java › javase › 22 › docs › api › java.base › java › util › TimeZone.html
TimeZone (Java SE 22 & JDK 22)
July 16, 2024 - Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone. static TimeZone · getTimeZone · (String ID) Gets the TimeZone for the given ID. static TimeZone · getTimeZone · (ZoneId zoneId) Gets the TimeZone for the given zoneId.
🌐
UTC Time
utctime.net
UTC Time Now
UTC time now (Coordinated Universal Time) helps you to get the current time and date in UTC (GMT) local time zone, what is the time now in UTC.
🌐
UTC Time
utctime.net › utc-time-zone-converter
UTC Time Zone Converter
Convert UTC time zone to other time zones, including bst, ast, est, edt, mst, pst, ist, aest and more time zones, get the current time utc to all time zones.
🌐
Adobe
helpx.adobe.com › coldfusion › cfml-reference › coldfusion-functions › functions-e-g › gettimezoneinfo.html
GetTimeZoneInfo
February 25, 2025 - ColdFusion (2025 release): Accepts timezone and locale as optional parameters. ... <cfscript> curdatetime = now(); writeOutput("The local date and time are " & curdatetime & "<br/>"); info = GetTimeZoneInfo(); writeOutput("Total offset in seconds is " & info.utcTotalOffset & "<br/>"); writeOutput("Offset in hours is " & info.utcHourOffset & "<br/>"); writeOutput("Total offset in minutes minus is " & info.utcMinuteOffset & "<br/>"); writeOutput("Is DST?
🌐
GeeksforGeeks
geeksforgeeks.org › java › gregoriancalendar-gettimezone-method-in-java
GregorianCalendar getTimeZone() Method in Java - GeeksforGeeks
July 27, 2021 - public TimeZone getTimeZone() Parameters: This method does not accept any parameter. Return Values: This method returns a TimeZone object which denotes the time zone of this calendar.