converting a UTC time to a local time zone in Java

后端 未结 2 823
梦毁少年i
梦毁少年i 2021-01-18 17:40

I know this subject has been beaten to death but after searching for a few hours to this problem I had to ask.

My Problem: do calculations on dates on a server based

相关标签:
2条回答
  • 2021-01-18 18:11

    You timezone string is formulated incorrectly. Try this,

    String sign = secondsFromGMT > 0 ? "+" : "-";
    secondsFromGMT = Math.abs(secondsFromGMT);      
    int hours = secondsFromGMT/3600;
    int mins = (secondsFromGMT%3600)/60;
    String zone = String.format("GMT%s%02d:%02d", sign, hours, mins);          
    TimeZone t = TimeZone.getTimeZone(zone);
    
    0 讨论(0)
  • 2021-01-18 18:12

    tl;dr

    get the HOUR of a UTC Date object after it has been converted to this local time zone

    Zone (preferred)

    ZonedDateTime.now(
        ZoneId.of( "Africa/Tunis" )  // Use a zone rather than a mere offset-from-UTC whenever possible.
    ).getHour()
    

    23

    Offset

    OffsetDateTime.now(
        ZoneOffset.ofTotalSeconds( secondsFromGMT )  // Use a mere offset-from-UTC only when the appropriate zone is unavailable AND you have been assured this particular offset is correct for your input data.
    ).getHour()
    

    23

    Avoid legacy date-time classes

    You are using troublesome old date-time classes that are now legacy, supplanted by the modern industry-leading java.time classes.

    java.time

    Get the current moment in UTC 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() ;
    

    Adjust into a particular time zone.

    Specify a [proper time zone name](https://en.wikipedia.org/wiki/List_of_tz_zones_by_name) in the format of `continent/region`, such as [`America/Montreal`](https://en.wikipedia.org/wiki/America/Montreal), [`Africa/Casablanca`](https://en.wikipedia.org/wiki/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/Montreal" );
    

    If at runtime you want the JVM’s current default time zone, ask for it. Keep in mind this can change at any moment. So if critical, you should ask or confirm with the user.

    ZoneId z = ZoneId.systemDefault() ;
    

    Apply the time zone to produce a ZonedDateTime object.

    ZonedDateTime zdt = instant.atZone( z ) ;
    

    You said you want only the hour-of-day from this zoned date-time. Interrogate with a specific method.

    int hourOfDay = zdt.getHour() ;
    

    By the way, you may find the LocalTime class useful.

    LocalTime lt = zdt.toLocalTime() ;
    

    Offset vs Zone

    The variables hour and mins represent the hour and mins the local time zone is away from GMT

    No, not a time zone. You have conflated zone with offset. Very important to understand the distinction.

    • Offset
      An offset-from-UTC is a number of hours and minutes and seconds before/after UTC (GMT). Nothing more, nothing less.
    • Zone
      A time zone is a history of the various offsets in use by the peoples of a particular regian. A zone represents all the changes in the offset over time, past, present, and near-future. Politicians around the world have shown a penchant for frequently changing the offset of their time zone(s).

    A particular offset may be in use in multiple places by coincidence. For example, sometimes Dublin, London, Casablanca, Lagos, and Brazzaville all share the same offset of +01:00, one hour ahead of UTC. But at other times they may not, such as in the winter this year when Lagos remains one hour ahead of UTC while the other three switch to zero hours ahead of UTC (that is, UTC itself).

    With a zone and a moment, you can determine an offset. But not so going the other direction; with only an offset, you cannot reliably determine a zone.

    So your number of hours and minutes is merely an offset. That offset may not be correct for your zone for the input’s particular date. So always prefer a time zone over a mere offset.

    OffsetDateTime

    If you are stuck for some reason with an offset that you are certain is correct for your given inputs but you do not know the time zone, then use ZoneOffset & OffsetDateTime rather than ZoneId & ZonedDateTime. But if at all possible, use zone instead of offset as explained above.

    ZoneOffset offset = ZoneOffset.ofTotalSeconds( secondsFromGMT ) ;
    OffsetDateTime odt = OffsetDateTime.now( offset ) ;
    

    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.

    0 讨论(0)
提交回复
热议问题