2
votes

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"?

2
Your implication that the result of TimeZone.getTimeZone(String) depends upon the current time is incorrect.Andy Turner
There is multiple locations which are GMT-7 mapstudio.co.za/wp-content/uploads/2014/02/9781770265646.jpg how would it know you meant the one for Los Angeles?Peter Lawrey
GMT-07:00 is an offset (difference from UTC), while America/Los_Angeles is a timezone (set of all offsets a region uses during history), read more about the difference here. As already said, there's more than 1 timezone that uses the same offset, so only by having GMT-7, you can't say which timezone isuser7605325

2 Answers

9
votes

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.

0
votes

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?

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.