如何在 android 中将 UTC 时间转换为本地时间以获得日落时间

How to convert UTC time to local time in android for sunset time

我正在尝试为当地用户获取日落时间。我从 sunrise-sunset.org 得到 UTC 的日落时间。然后我将它转换为当地时间,然后我考虑夏令时,然后我将它转换为常规时间。

问题是它下班了。

已编辑 例如:

在应用程序中,用户可以将位置设置为世界任何地方,假设他们将其设置为密苏里州斯普林菲尔德(美国)。它 returns 04:57:31 AM,在我转换它之后,结果变成了 5:57 AM,尽管它应该是 4:57 PM。那是 API 30.

现在更奇怪的是,如果我使用 API 22 phone,它会显示为 7:57 PM

我需要支持 API 21 到 API 30(Android 11).

它还会在未开启时不断返回夏令时。

   public void RequestSunsetTime(String lat, String lng){

        // set loading text
        sunsetTimeTextView.setText(R.string.loading_text);

        ProjectRepository projectRepository = new ProjectRepository();
        String url = "https://api.sunrise-sunset.org/json?lat=" + lat + "&lng=" + lng + "&date=today";
        projectRepository.requestDataPartTwo(url, new ProjectRepository.VolleyResponseListenerForTwo() {
            @Override
            public void onResponse(String UTCtime) {

                // convert utc time to local time
                String time = UTCtime;
                System.out.println("== TIME ==" + time);


                try {
                    SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss a", Locale.ENGLISH);
                    df.setTimeZone(TimeZone.getTimeZone("UTC"));
                    Date  _date = df.parse(UTCtime);
                    df.setTimeZone(TimeZone.getDefault());
                    System.out.println(">>>>>>>>>>> Time zone: " + TimeZone.getDefault());
                    time = df.format(_date);
                    System.out.println(">>>>>>>>>>> time: " + time);

                    // convert army time to standard time
                    String[] timeParts = time.split(":"); // convert to array

                    // fetch
                    int hours = Integer.parseInt(timeParts[0]);
                    System.out.println(">>>>> army time hours: " +hours);
                    int minutes = Integer.parseInt(timeParts[1]);
                 

                    // --- *.getDSTSavings()* adds time for day light saving time
                    int timeForDST = (((TimeZone.getDefault().getDSTSavings() / 1000) / 60) / 60);
                 
                    System.out.println(">>>>>>>>>>> time: " + time);

                    // calculate
                    String  timeValue = "";

                    if (hours > 0 && hours <= 12) {
                        timeValue= "" + hours;
                    } else if (hours > 12) {
                        timeValue= "" + (hours - 12);
                    } else if (hours == 0) {
                        timeValue= "12";
                    }

                    if(timeForDST != 0){
                        int num = Integer.parseInt(timeValue);
                        timeValue =String.valueOf(num + timeForDST);
                    }

                    timeValue += (minutes < 10) ? ":0" + minutes : ":" + minutes;  // get minutes
                 
                    timeValue += (hours >= 12) ? " PM" : " AM";  // get AM/PM

                    time = timeValue;

                } catch (ParseException e) {
                    e.printStackTrace();
                }
                System.out.println(">>>>>>>>>> Final Time: " + time);
                // save
       
              
            }

          

        });

    }

提前谢谢你:)

你太辛苦了

永远不要使用糟糕的遗留日期时间 类,例如 SimpleDateFormatTimeZoneDateCalendar 类。仅使用 java.time 类.

我不清楚您收到的文本格式是什么。我假设它是标准的 ISO 8601 格式 YYYY-MM-DDTHH:MM:SSZ。 (如果不是,请为清楚起见编辑您的问题。)

Instant instant = Instant.parse( "2022-01-23T12:34:56.123456789Z" ) ;

如果需要,删除不需要的细节。

instant = instant.truncatedTo( ChronoUnit.MINUTES ) ;

从 UTC 到特定时区的零时分秒偏移进行调整。

ZoneId z = ZoneId.of( "America/Edmonton" ) ;  // Or ‘ZoneId.systemDefault()`. 
ZonedDateTime zdt = instant.atZone( z ) ;

提取一天中的时间。

LocalTime lt = zdt.toLocalTime() ;

以自动本地化格式生成文本。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( Locale.CANADA_FRENCH ) ;
String output = lt.format( f ) ;

看到这个code run live at IdeOne.com

这些 类 内置于 Android 26+。对于早期的 Android,使用最新的工具及其“API 脱糖”来访问大多数 java.time 功能。