【问题标题】:How to convert UTC time to local time in android for sunset time如何将UTC时间转换为android中的当地时间以获取日落时间
【发布时间】:2022-01-06 14:47:03
【问题描述】:

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

问题是它会休息几个小时。

已编辑 例如:

在应用程序中,用户可以将位置设置为世界任何地方,假设他们将其设置为 Springfield MO(USA)。它返回 04:57:31 AM,在我转换它之后,它会变成5:57 AM,即使它应该说4:57 PM。这适用于 API 30。

现在更奇怪的是,如果我使用 API 22 电话,它会显示为 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
       
              
            }

          

        });

    }

提前谢谢你:)

【问题讨论】:

  • 请指定您获得的 UTC 时间、所需时区、该时区的预期结果以及打印语句输出的完整列表的示例问题是下班时间。 对问题陈述的表述含糊不清,根本没有提供足够的帮助来帮助您解决问题。 (让我猜,它可能会休息 12 小时?不,错了吗?你告诉我们!)
  • 考虑不使用SimpleDateFormatDate。这些课程设计不佳且早已过时。使用从 API 级别 26 内置的现代 Java 日期和时间 API java.time,以及通过脱糖获得的较低级别。请参阅 Basil Bourque 的答案。

标签: java android timezone utc


【解决方案1】:

你工作太辛苦了。

永远不要使用糟糕的旧日期时间类,例如 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 功能。

【讨论】:

  • 用户可以在世界任何地方设置时间,那么有没有办法在不设置Locale的情况下以自动本地化格式生成文本?跨度>
  • @sundrycode Locale 是本地化所必需的,提供用于翻译的人类语言以及提供大写、缩写、标点符号等的文化规范。要使用 JVM 当前的默认语言环境,请调用 Locale.getDefault()
  • @sundrycode A Locale 与用户在地球上的位置无关。语言环境是用户的偏好。一位来自魁北克的法语专业人士参加在日本东京举行的会议,他们希望在Asia/Tokyo 时区和Locale.CANADA_FRENCH 语言环境中查看会议日程。
猜你喜欢
  • 2015-09-26
  • 1970-01-01
  • 2013-03-12
  • 2011-03-25
  • 1970-01-01
  • 2019-03-30
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
相关资源
最近更新 更多