I want to get the time zone information for Los Angeles, now 10/10/2017 is daylight saving time,
But I got a different result when I got the time zone in Los Angeles in two ways.
public class TimeZoneDemo2 {
public static void main(String[] args) {
TimeZone timeZoneLosAngeles =
TimeZone.getTimeZone("America/Los_Angeles");
System.out.println(timeZoneLosAngeles);
TimeZone timeZoneGmtMinus07 = TimeZone.getTimeZone("GMT-07:00");
System.out.println(timeZoneGmtMinus07);
}
}
the result is:
sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]
sun.util.calendar.ZoneInfo[id="GMT-07:00",offset=-25200000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
My question is: Information about daylight saving time in time zone information obtained by "America/Los_Angeles". Why not include daylight saving time information (useDaylight = false) in the time zone information obtained by "GMT -0700"?
I want to get the time zone information for Los Angeles, now 10/10/2017 is daylight saving time
So you should ask for the "America/Los_Angeles" zone. That's what it's there for.
The "GMT-07:00" zone is a fixed-offset zone - it's only suitable when you want to represent "a time zone which is permanently seven hours behind UTC". That doesn't apply to Los Angeles.
There are plenty of other time zones which are sometimes at UTC-7 - why would you expect GMT-07:00 to mean "the time zone observed in Los Angeles"?
In other words, Java is doing the right thing - it's your expectations of what the "GMT-07:00" zone means that are incorrect.
The Answer by Jon Skeet is correct and should be accepted. You cannot reliably determine a time zone from an offset-from-UTC as many zones may share an offset coincidentally. Also, the offset for a zone likely varies over time.
Here are some code samples addressing the issue using more modern classes than that seen in the Question.
java.time
You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
As others stated, if you know the intended time zone, always use that zone in preference to a mere offset-from-UTC. An offset is simply a number of hours, minutes, and seconds ahead of, or behind, UTC. A time zone is a history of changes to the offset used by the people of a region. A time zone knows the past, present, and (tentatively) the future of such changes in offset.
The ZoneId and ZoneOffset classes replace TimeZone.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; // Or "Africa/Tunis", "Pacific/Auckland", etc.
Get the current moment as seen through the lens of that zone.
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Fetch current moment for that zone.
Extract that same moment but adjusted into UTC.
Instant instant = zdt.toInstant() ; // Extract the same moment but in UTC.
Adjust that some moment into another zone.
ZonedDateTime zdtKolkata = instant.atZone( ZoneId.of( "Asia/Kolkata" ) ) ; // Determine same moment, same point on timeline, but in another time zone.
All three of these objects represent the very same simultaneous point on the timeline, but viewed with a different wall-clock time.
See the offset used by the people of that region at that moment.
ZoneOffset offset = z.getRules().getOffset( instant ) ; // Get the offset in place at that moment for that time zone.
You will find that for 2018, in part of that year the offset for America/Los_Angeles will be -07:00 (sever hours behind UTC). In the other part of the year, the offset will be -08:00 (eight hours behind UTC). This change in offset is due to politicians’ decision to observe Daylight Saving Time (DST).
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, 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
Other system send for us Timestamp in their time zone.If we run that in cloud in other system is +2 hours. Local is good because the server is the same time zone. How can I be sure that the time will always be right?
String TIME_STAMP_FORMAT = "yyyy-MM-dd-HH.mm.ss.SSSSSS";
DateTimeFormatter TIME_STAMP_FORMATTER = DateTimeFormatter.ofPattern(TIME_STAMP_FORMAT, Locale.getDefault());
private static Timestamp parseTimestamp(String dateString) {
try {
return Timestamp.valueOf(LocalDateTime.parse(dateString, TIME_STAMP_FORMATTER));
} catch (DateTimeParseException e) {
log.error("Not able to parse timestamp", e);
}
return null;
}
Date afterParse = parseTimestamp('2018-12-31-12.30.50.000200')
tl;dr
How can I be sure that the time will always be right?
Include an indicator of time zone or offset-from-UTC with your date-time input string.
Use standard ISO 8601 formats when exchanging date-time values.
Use only java.time classes in Java. Never use Date, Timestamp, Calendar, etc.
Tip: Adjust values from other zones to UTC before sending (generally speaking).
If not possible, then here is a workaround. This assumes you know the time zone intended by the sender of this poor data.
LocalDateTime // Represent a date and time-of-day without the context of a time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline. A meaningless value until you assign a zone/offset.
.parse(
"2018-12-31-12.30.50.000200" , // Avoid such custom formats. Use only ISO 8601 when exchanging date-time values textually.
DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" ) // Define formatting pattern to match youre input.
) // Returns a `LocalDateTime` object.
.atZone( // Give meaning to the `LocalDateTime` object by applying a time zone.
ZoneId.of( "Africa/Tunis" ) // Always specify a time zone with `Continent/Region` name, never the 2-4 character pseudo-zones popularly seen in the media.
) // Returns a `ZonedDateTime` object.
.toInstant() // Adjust from a time zone to UTC by extracting an `Instant` object. Same moment, same point on the timeline, different wall-clock time.
See this code run live at IdeOne.com.
Best to avoid java.util.Date class. But if you must interoperate with old code not yet updated to java.time, you can convert. Call on the new methods added to the old classes such as Date.from( Instant ).
Avoid legacy classes
Never use java.sql.Timestamp nor java.util.Date. All of the date-time classes bundled with the earliest versions of Java are now legacy, per the adoption of JSR 310. Use only the modern java.time classes.
Wrong data type
You are using the wrong data type. To track a moment, a specific point on the timeline, you must have a time zone or offset-from-UTC. The LocalDateTime class exactly the wrong class to use here. That class purposely lacks any concept of zone or offset. So it is the opposite of what you want.
To track a moment, use Instant, OffsetDateTime, or ZonedDateTime.
Where the java.time classes have methods with an optional time zone (ZoneId) or offset-from-UTC (ZoneOffset) argument, consider the argument required. Always pass a zone/offset. Then you never need worry about how the sysadmin is setting the JVM’s current default time zone at runtime.
ZonedDateTime.now( // Capture the current moment as seen through the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Pacific/Auckland" )
)
Or, use Instant which is always in UTC, by definition.
Instant.now() // Capture the current moment in UTC.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ISO 8601
Your question is not clear, but it seems you are receiving an input string for a date-time in a custom format. I suggest you educate the people publishing that data about the ISO 8601 standard. This standard defines practical formats for date-time values being exchanged between systems textually.
The java.time classes use the ISO 8601 formats by default when parsing/generating strings.
Workaround
If the data publisher is sending you values such as 2018-12-31-12.30.50.000200 in order to communicate a moment, they have failed. A date and time-of-day without a zone or offset is useless, like communicating an amount of money without indicating a currency.
Do you know for certain the time zone that was implicitly assumed by the sender of this faulty data input? If so, apply it, as a clumsy stop-gap measure for their poor practice.
First parse your input as a LocalDateTime given that it lacks any indicator of zone/offset.
String input = "2018-12-31-12.30.50.000200" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
Apply a ZoneId to get a ZonedDateTime object, thereby adjusting to view the moment through the wall-clock time used by the people of that particular region.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( ldt ) ;
Generally best to work with moments in UTC, unless you have a specific reason to use a time zone (such as presentation to user). So extract an Instant from your ZonedDateTime.
Instant instant = zdt.toInstant() ;
The Z at the end of an ISO 8601 compliant string means UTC, and is pronounced “Zulu”.
See this code run live at IdeOne.com.
input: 2018-12-31-12.30.50.000200
ldt: 2018-12-31T12:30:50.000200
zdt: 2018-12-31T12:30:50.000200+09:00[Asia/Tokyo]
instant: 2018-12-31T03:30:50.000200Z
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Just a small supplement to Basil Bourque’s clever and very informative answer.
I know the date is in CET timezone.
I am sorry, this is not enough. Central European Time (CET) is the common term for quite many European and African(!) time zones the details of which differ. The European ones are generally at offset +01:00 during standard time and at +02:00 during summer (known as Central European Summer Time or CEST). The African ones are at +01:00 all year. For past dates, just a few decades back, some zones used summer time (DST), others didn’t, some were at +00:00, +01:00 or +02:00, and further back in history many other offsets were used, generally not whole hours.
The future is even worse! It has been suggested that the European Union abandons summer time and leaves it to each member state whether they will use permanent standard time or permanent summer time, avoiding the time adjustments in spring and autumn. There is a power struggle going on about this, so we don’t know whether it will happen, nor what each member state chooses. So even if you could tell me the exact time zone of your string from the other system (for example, Europe/Sarajevo), no one knows yet whether 2019-11-01-00.30.50.000200 — less than 7 months from now — will be at offset +01:00 or +02:00.
Link: European MPs vote to end summer time clock changes on BBC News.
I have a method using 2 Instants in parameters getIssuesBillable(Instant start, Instant end, ....), my question is how I get the first day of a month and the last day of the month using a Java 8 Instant?
I already tried use withDayOfMonth(), and lengthOfMonth():
LocalDate initial = LocalDate.now();
LocalDate start = initial.withDayOfMonth(firstDayOfMonth());
LocalDate end = initial.withDayOfMonth(lastDayOfMonth());
But in this case, I need to convert and make some workarounds in this case, if someone knows a better way to do it I really appreciate any response.
tl;dr
Use modern java.time classes.
Here is a brief nonsensical example of starting with an Instant (a moment in UTC), assigning a time zone to view that moment through the wall-clock time used by the people of a particular region (a time zone), extracting the year-and-month as perceived in that time zone, and determining the first and last day of that month, rendering LocalDate objects.
YearMonth // Represent a year-and-month, the entire month as a whole.
.from( // Determine the year-and-month of some other date-time object.
Instant // Represent a moment in UTC.
.now() // Capture the current moment in UTC.
.atZone( // Adjust from UTC to a particular time zone.
ZoneId.of( "Pacific/Auckland" )
) // Returns a `ZonedDateTime` object.
) // Returns a `YearMonth` object.
.atDay( 1 ) // Returns a `LocalDate` object.
…or
…
.atEndOfMonth() // Returns a `LocalDate` object.
By the way, a realistic version of that particular code would be: YearMonth.now( ZoneId.of( "Pacific/Auckland" ) ).atDay( 1 )
Moment versus date-only
Instant is a moment in UTC, a date with time-of-day and an offset-from-UTC of zero.
A LocalDate is a date-only value, without time-of-day and without time zone.
You need to specify the time zone by which you want to perceive the date, the wall-clock time used by the people of a particular region.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Extract the date-only.
LocalDate ld = zdt.toLocalDate() ;
From there, proceed with your other code.
Or work with the month as a whole, using YearMonth class.
YearMonth ym = YearMonth.from( zdt ) ;
LocalDate first = ym.atDay( 1 ) ;
LocalDate last = ym.atEndOfMonth() ;
Tip: You might find helpful the LocalDateRange and Interval classes in the ThreeTen-Extra library.
Tip: Learn about the Half-Open approach to define a span of time, where the beginning is inclusive while the ending is exclusive. So a month starts on the first and runs up to, but does not include, the first day of the following month.
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.
For the first day of the month, depends on the time zone:
YearMonth.from(Instant.now().atZone(ZoneId.of("UTC"))).atDay(1);
For the last day of the month, depends on the time zone:
YearMonth.from(Instant.now().atZone(ZoneId.of("UTC"))).atEndOfMonth();
I would like to get the 10 days before today and also set the time to 12:00 midnight
I have figured out that a day has 24 hours so 10 days will have 240 hours so I have
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) - 240);
The above works but now when I want to set the time to 12:00
I have tried
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
After adding the above the 10 days before are now reset to today.
What could be wrong?
If you are using java.time library it can be more easier, you can use :
LocalDateTime date = LocalDateTime.of(
LocalDate.now().minusDays(10),
LocalTime.of(12, 0)
);
For example :
Now it is :
2018-04-01T13:30
Before 10 days, at 12 it return :
2018-03-22T12:00
You use https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html and method set have this behaviour
set(f, value) changes calendar field f to value. In addition, it sets
an internal member variable to indicate that calendar field f has been
changed. Although calendar field f is changed immediately, the
calendar's time value in milliseconds is not recomputed until the next
call to get(), getTime(), getTimeInMillis(), add(), or roll() is made.
Thus, multiple calls to set() do not trigger multiple, unnecessary
computations. As a result of changing a calendar field using set(),
other calendar fields may also change, depending on the calendar
field, the calendar field value, and the calendar system. In addition,
get(f) will not necessarily return value set by the call to the set
method after the calendar fields have been recomputed. The specifics
are determined by the concrete calendar class.
Example: Consider a GregorianCalendar originally set to August 31,
1999. Calling set(Calendar.MONTH, Calendar.SEPTEMBER) sets the date to September 31, 1999. This is a temporary internal representation that
resolves to October 1, 1999 if getTime()is then called. However, a
call to set(Calendar.DAY_OF_MONTH, 30) before the call to getTime()
sets the date to September 30, 1999, since no recomputation occurs
after set() itself.
You call set three times and result is last set time. So for you purposes you need to use method add after(with) set.
tl;dr
ZonedDateTime.now( // Capture the current moment as seen through the wall-clock time used by the people of a certain region (a time zone).
ZoneId.of( "Pacific/Auckland" ) // Specify a time zone using proper name, `continent/region`, never 3-4 pseudo-codes such as `PST`, `EST`, `IST`.
)
.minusDays( 10 ) // Go back in time ten days, adjusting for time-of-day as need be.
.toLocalDate() // Extract a date-only value.
.atStartOfDay( // Determine the first moment of that date in a certain time zone. Not always 00:00:00.
ZoneId.of( "Pacific/Auckland" )
)
.toString() // Generate a String in standard ISO 8601 format.
2018-03-23T00:00+13:00[Pacific/Auckland]
Avoid legacy date-time classes.
You are using troublesome old date-time classes supplanted years ago by the java.time classes.
java.time
Instead of Calendar, use ZonedDateTime to represent a moment on the timeline with a wall-clock time used by people of a certain region (time zone).
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment.
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment.
Math
Specify a span of time unattached to the timeline of years-months-days using Period.
Period p = Period.ofDays( 10 ) ;
Go back in time. Anomalies such as Daylight Saving Time (DST) are handled automatically, adjusting time-of-day as need be.
ZonedDateTime zdtTenDaysAgo = zdt.minus( p ) ;
“Midnight” is a trick concept, ambiguous and amorphous. Instead, focus on the idea of “first moment of the day”.
Always let java.time determine the first moment. Do not assume the day starts at 00:00:00. Anomalies such as DST mean the day may start at another time such as 01:00:00. To get that first moment, extract a date-only LocalDate object. Specify a time zone to determine when that date began in that place.
LocalDate ldTenDaysAgo = zdtTenDaysAgo.toLocalDate() ;
ZonedDateTime zdtTenDaysAgoStartOfDay = ldTenDaysAgo.atStartOfDay( z ) ;
If you want to view the same moment as UTC, extract a Instant.
Instant instant = zdtTenDaysAgoStartOfDay.toInstant() ;
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, 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.
To add or subtract, you should use the add method :
cal.add(Calendar.HOUR, -240);
But beware of that, because a day is not always the same as 24 hours, due to Daylight Saving Time effects: https://www.timeanddate.com/time/dst/transition.html
Anyway, Calendar is a very bugged class and it's better to use java.time classes (API level 26), or threetenbp if java.time is not available: http://www.threeten.org/threetenbp/
See here how to configure in Android: How to use ThreeTenABP in Android Project
To consider DST effects, use a ZonedDateTime:
// current date/time
ZonedDateTime.now()
// minus 10 days
.minusDays(10)
// set time to midnight
.with(LocalTime.MIDNIGHT);
This will take care of the complicated details of DST, including the cases where DST starts at midnight and the day actually starts at 1am - the time is automatically adjusted.
It's not clear if you want midnight (00:00) or noon (12:00). Anyway, if you want noon, just use LocalTime.NOON.
How do I get the time difference from GMT for a specific date and time zone in Java?
Determining whether a specific time zone is in DST is quite straight-forward:
boolean isIsraelInDST = TimeZone.getTimeZone("Israel").inDaylightTime(new Date());
How do I get the actual time difference?
Use TimeZone.getRawOffset(): 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 you want the offset including DST then you use TimeZone.getOffset(long date). You should provide the concrete date to the method, eg now - System.currentTimeMillis()
tl;dr
ZoneId.of( "Pacific/Auckland" ) // Specify a time zone.
.getRules() // Get the object representing the rules for all the past, present, and future changes in offset used by the people in the region of that zone.
.getOffset( Instant.now() ) // Get a `ZoneOffset` object representing the number of hours, minutes, and seconds displaced from UTC. Here we ask for the offset in effect right now.
.toString() // Generate a String in standard ISO 8601 format.
+13:00
For the first moment of a certain date.
ZoneId.of( "Pacific/Auckland" )
.getRules()
.getOffset(
LocalDate.of( 2018 , Month.AUGUST , 23 ) // Specify a certain date. Has no concept of time zone or offset.
.atStartOfDay( ZoneId.of( "Pacific/Auckland" ) ) // Determine the first moment of the day on that date in that region. Not always `00:00:00` because of anomalies such as Daylight Saving Time.
.toInstant() // Adjust to UTC by extracting an `Instant`.
)
.toString()
+12:00
Avoid legacy date-time classes
The other Answers are outmoded, as the TimeZone class is now legacy. This and other troublesome old date-time classes are supplanted by the java.time time classes.
java.time
Now we use ZoneId, ZoneOffset, and ZoneRules instead of the legacy TimeZone class.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
Fetch the rules for that zone.
ZoneRules rules = z.getRules() ;
Ask the rules if Daylight Saving Time (DST) is in effect at a certain moment. Specify the moment as an 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).
Instant instant = Instant.now() ; // Capture current moment in UTC.
boolean isDst = rules.isDaylightSavings( instant ) ;
How do I get the actual time difference?
Not sure what you mean, but I will guess you are asking for the offset-from-UTC in effect at that moment for than zone. An offset is a number of hours, minutes, and seconds displacement from UTC. We represent an offset using ZoneOffset class. A time zone is a history of past, present, and future changes in offset used by the people of a particular region. We represent a time zone using ZoneId class.
Because the offset may vary over time for a region, we must pass a moment when asking for an offset.
ZoneOffset offset = rules.getOffset( instant ) ;
Generate a String representing that offset in ISO 8601 standard format.
String output output = offset.toString() ;
You can ask for the offset as a total number of seconds.
int offsetInSeconds = offset.getTotalSeconds() ;
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.
I suggest to add summer/winter time offset to getRawOffset:
TimeZone tz1 = TimeZone.getTimeZone("GMT");
TimeZone tz2 = TimeZone.getTimeZone("America/New_York");
long timeDifference = tz1.getRawOffset() - tz2.getRawOffset() + tz1.getDSTSavings() - tz2.getDSTSavings();
I see this is an old thread - but adding this since I had a similar requirement recently -
This gives the actual difference in millis based on the CURRENT time(millis from epoch).
TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis())
public String timeZone(Date date) {
TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
long millis = timeZone.getRawOffset() + (timeZone.inDaylightTime(date) ? timeZone.getDSTSavings() : 0);
return String.format("%s%s:%s",
millis < 0 ? "-" : "+",
String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toHours(millis))),
String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))))
);
}
This may be a very basic question, but i could'nt find any satisfactory answers.Hope my doubts gets clear on stackoverflow.
Q 1. Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
Q 2. Is there any way to get timezone using JavaScript?
Q 3. A timezone is just the representation of time in a particular zone, but actually every zone is at the same time,just representation wise it may be different depending on geographical conditions. - Is this understanding Correct?
possible duplicate link
Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
Create a formatter and set the timezone in there.
Internally, java.util.Date just stores milliseconds since the Epoch in the UTC timezone.
When you use Date.toString() or new SimpleDateFormat() without a timezone, then the default timezone of your VM is used.
So in a sense, Java always converts to your current/default timezone (unless you happen to be in UTC).
Is there any way to get timezone using Java Script?
It depends. You can use getTimezoneOffset() but that gives you only the offset. There is no API to get the client's OSs timezone ID (like UTC, Europe/Berlin, etc.)
A timezone is just the representation of time...
Not really. See above.
Q 1. Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
The modern way is with the java.time classes.
Firstly, do much of your work in UTC. Apply a time zone only where necessary, such as presentation to a user.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
If you have only an offset-from-UTC rather than a time zone, apply a ZoneOffset to get a OffsetDateTime.
ZoneOffset offset = ZoneOffset.ofHours( -4 );
OffsetDateTime odt = instant.atOffset( offset );
A time zone is an offset-from-UTC (a specific number of hours, minutes, and seconds) plus a set of rules for handling anomalies such as Daylight Saving Time (DST). Represent a time zone with a ZoneId object. Specify a proper time zone name. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
Apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
You can apply other time zones to either the Instant or the ZonedDateTime.
ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );
Q 2. Is there any way to get timezone using JavaScript?
The issue of determining a time zone from a web browser has been handled countless times on Stack Overflow already.
So I'll skip this, except to say the upshot: No, not really in a reliable way; When important to know the time zone precisely you must ask the user herself.
Q 3. A timezone is just the representation of time in a particular zone, but actually every zone is at the same time,just representation wise it may be different depending on geographical conditions. - Is this understanding Correct?
No, a time zone is not a date-time moment.
A time zone adds meaningful context to a date-time in the same way that a currency designation adds meaningful context to an amount of money. A date-time without a time zone is just a rough idea of possible moments, not a precise point on the timeline. Noon at Auckland is earlier than noon in Kolkata which is earlier than noon in Paris which is earlier than noon in Montréal Québec.
You can think of it as pseudo-math statement:
Time Zone = ( Offset-from-UTC + set-of-rules-for-anomalies )
An example of an imaginary time zone:
An offset might be “one hour ahead of UTC”, plus
This set of rules: “On this date we will engage DST, on this date we will disengage DST, on this date during World War II we did shift ahead one hour, on this date after World War II we shifted back one hour, on this date our government shifted clocks forward a half-hour to make us distinct from our arch-rival neighbor country, …”.
You can apply a time zone to a point on the timeline. Like looking at art through a lens, it changes your perception but not the artifact itself. Looking at a point on the timeline through the lens of a time zone distorts the time-of-day and possibly the date into that of a particular community’s wall-clock time.
Another pseudo-math equation as a way of thinking about the class representations of a time zone and a moment on the timeline:
ZonedDateTime = Instant + ZoneId
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.
I can answer to your second question and correct the Aaron Digulla very complete response
Is there any way to get timezone using Java Script?
try to use this library, it will return a TimeZone ID with particular limitation (menthioned in the developer's page):
https://bitbucket.org/pellepim/jstimezonedetect