Get TimeZone offset value from TimeZone without TimeZone name

后端 未结 7 734
[愿得一人]
[愿得一人] 2020-12-02 10:22

I need to save the phone\'s timezone in the format [+/-]hh:mm

I am using TimeZone class to deal with this, but the only format I can get is the following:

         


        
相关标签:
7条回答
  • 2020-12-02 10:56

    We can easily get the millisecond offset of a TimeZone with only a TimeZone instance and System.currentTimeMillis(). Then we can convert from milliseconds to any time unit of choice using the TimeUnit class.

    Like so:

    public static int getOffsetHours(TimeZone timeZone) {
        return (int) TimeUnit.MILLISECONDS.toHours(timeZone.getOffset(System.currentTimeMillis()));
    }
    

    Or if you prefer the new Java 8 time API

    public static ZoneOffset getOffset(TimeZone timeZone) { //for using ZoneOffsett class
        ZoneId zi = timeZone.toZoneId();
        ZoneRules zr = zi.getRules();
        return zr.getOffset(LocalDateTime.now());
    }
    
    public static int getOffsetHours(TimeZone timeZone) { //just hour offset
        ZoneOffset zo = getOffset(timeZone);
        TimeUnit.SECONDS.toHours(zo.getTotalSeconds());
    }
    
    0 讨论(0)
  • 2020-12-02 11:01

    I need to save the phone's timezone in the format [+/-]hh:mm

    No, you don't. Offset on its own is not enough, you need to store the whole time zone name/id. For example I live in Oslo where my current offset is +02:00 but in winter (due to dst) it is +01:00. The exact switch between standard and summer time depends on factors you don't want to explore.

    So instead of storing + 02:00 (or should it be + 01:00?) I store "Europe/Oslo" in my database. Now I can restore full configuration using:

    TimeZone tz = TimeZone.getTimeZone("Europe/Oslo")
    

    Want to know what is my time zone offset today?

    tz.getOffset(new Date().getTime()) / 1000 / 60   //yields +120 minutes
    

    However the same in December:

    Calendar christmas = new GregorianCalendar(2012, DECEMBER, 25);
    tz.getOffset(christmas.getTimeInMillis()) / 1000 / 60   //yields +60 minutes
    

    Enough to say: store time zone name or id and every time you want to display a date, check what is the current offset (today) rather than storing fixed value. You can use TimeZone.getAvailableIDs() to enumerate all supported timezone IDs.

    0 讨论(0)
  • 2020-12-02 11:01
    ZoneId here = ZoneId.of("Europe/Kiev");
    ZonedDateTime hereAndNow = Instant.now().atZone(here);
    String.format("%tz", hereAndNow);
    

    will give you a standardized string representation like "+0300"

    0 讨论(0)
  • 2020-12-02 11:03

    @MrBean - I was in a similar situation where I had to call a 3rd-party web service and pass in the Android device's current timezone offset in the format +/-hh:mm. Here is my solution:

    public static String getCurrentTimezoneOffset() {
    
        TimeZone tz = TimeZone.getDefault();  
        Calendar cal = GregorianCalendar.getInstance(tz);
        int offsetInMillis = tz.getOffset(cal.getTimeInMillis());
    
        String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
        offset = (offsetInMillis >= 0 ? "+" : "-") + offset;
    
        return offset;
    } 
    
    0 讨论(0)
  • 2020-12-02 11:03

    With Java 8, you can achieve this by following code.

        TimeZone tz = TimeZone.getDefault();
        String offsetId = tz.toZoneId().getRules().getStandardOffset(Instant.now()).getId();
    

    and the offsetId will be something like +01:00

    Please notice the function getStandardOffset need a Instant as parameter. It is the specific time point, at which you want to check the offset of given timezone, as timezone's offset may varies during time. For the reason of some areas have Daylight Saving Time.

    I think it is the reason why @Tomasz Nurkiewicz recommand not to store offset in signed hour format directly, but to check the offset each time you need it.

    0 讨论(0)
  • 2020-12-02 11:06

    With java8 now, you can use

    Integer offset  = ZonedDateTime.now().getOffset().getTotalSeconds();
    

    to get the current system time offset from UTC. Then you can convert it to any format you want. Found it useful for my case. Example : https://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

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