-1

My weather App displays Datetime(last updated), Sunrise, and Sunset data from OpenWeatherMap in the form of milliseconds(i.e 1620792785). I'm trying to convert it to a real-time format (i.e hh:mm a).

I tried using this code for dt in my example class:

public String getPrettyDate() {
        SimpleDateFormat HMM = new SimpleDateFormat("hh:mm a", Locale.US);
        final Date date = new Date(dt*1000);
        return HMM.format(date);
    }

It converted the time well, but it didn't display the data accurately(i.e when it was 3pm here, it showed 9pm).

I as well checked this site for a similar issue but found none.

So I want to:

  • Convert the dt accurately
  • Convert Sunrise and Sunset time accurately using the right codes and classes.

Edit: My app can search for any city, so I'm not getting for a particular timezone but for all cities

My JSON Response:

{
   "coord":{
      "lon":-0.1257,
      "lat":51.5085
   },
   "weather":[
      {
         "id":804,
         "main":"Clouds",
         "description":"overcast clouds",
         "icon":"04d"
      }
   ],
   "base":"stations",
   "main":{
      "temp":289.16,
      "feels_like":288.07,
      "temp_min":286.87,
      "temp_max":290.76,
      "pressure":1009,
      "humidity":48
   },
   "visibility":10000,
   "wind":{
      "speed":0.45,
      "deg":109,
      "gust":2.68
   },
   "clouds":{
      "all":100
   },
   "dt":1620830862,
   "sys":{
      "type":2,
      "id":2019646,
      "country":"GB",
      "sunrise":1620792785,
      "sunset":1620848444
   },
   "timezone":3600,
   "id":2643743,
   "name":"London",
   "cod":200
}

My Example class:

public class Example {
    @SerializedName("coord")
    private Coord coord;
    @SerializedName("weather")
    private List<Weather> weather = null;
    @SerializedName("base")
    private String base;
    @SerializedName("main")
    private Main main;
    @SerializedName("visibility")
    private Integer visibility;
    @SerializedName("wind")
    private Wind wind;
    @SerializedName("clouds")
    private Clouds clouds;
    @SerializedName("dt")
    private Integer dt;
    @SerializedName("sys")
    private Sys sys;
    @SerializedName("timezone")
    private Integer timezone;
    @SerializedName("id")
    private Integer id;
    @SerializedName("name")
    private String name;
    @SerializedName("cod")
    private Integer cod;

    public Coord getCoord() {
        return coord;
    }

    public void setCoord(Coord coord) {
        this.coord = coord;
    }

    public List<Weather> getWeather() {
        return weather;
    }

    public void setWeather(List<Weather> weather) {
        this.weather = weather;
    }

    public String getBase() {
        return base;
    }

    public void setBase(String base) {
        this.base = base;
    }

    public Main getMain() {
        return main;
    }

    public void setMain(Main main) {
        this.main = main;
    }

    public Integer getVisibility() {
        return visibility;
    }

    public void setVisibility(Integer visibility) {
        this.visibility = visibility;
    }

    public Wind getWind() {
        return wind;
    }

    public void setWind(Wind wind) {
        this.wind = wind;
    }

    public Clouds getClouds() {
        return clouds;
    }

    public void setClouds(Clouds clouds) {
        this.clouds = clouds;
    }

    public Integer getDt() {
        return dt;
    }

    public void setDt(Integer dt) {
        this.dt = dt;
    }

    public Sys getSys() {
        return sys;
    }

    public void setSys(Sys sys) {
        this.sys = sys;
    }

    public Integer getTimezone() {
        return timezone;
    }

    public void setTimezone(Integer timezone) {
        this.timezone = timezone;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCod() {
        return cod;
    }

    public void setCod(Integer cod) {
        this.cod = cod;
    }

    public class Clouds {

        @SerializedName("all")
        private Integer all;

        public Integer getAll() {
            return all;
        }

        public void setAll(Integer all) {
            this.all = all;
        }

    }

    public class Coord {

        @SerializedName("lon")
        private Double lon;
        @SerializedName("lat")
        private Double lat;

        public Double getLon() {
            return lon;
        }

        public void setLon(Double lon) {
            this.lon = lon;
        }

        public Double getLat() {
            return lat;
        }

        public void setLat(Double lat) {
            this.lat = lat;
        }

    }

    public class Main {

        @SerializedName("temp")
        private Double temp;
        @SerializedName("feels_like")
        private Double feelsLike;
        @SerializedName("temp_min")
        private Double tempMin;
        @SerializedName("temp_max")
        private Double tempMax;
        @SerializedName("pressure")
        private Integer pressure;
        @SerializedName("humidity")
        private Integer humidity;

        public Double getTemp() {
            return temp;
        }

        public void setTemp(Double temp) {
            this.temp = temp;
        }

        public Double getFeelsLike() {
            return feelsLike;
        }

        public void setFeelsLike(Double feelsLike) {
            this.feelsLike = feelsLike;
        }

        public Double getTempMin() {
            return tempMin;
        }

        public void setTempMin(Double tempMin) {
            this.tempMin = tempMin;
        }

        public Double getTempMax() {
            return tempMax;
        }

        public void setTempMax(Double tempMax) {
            this.tempMax = tempMax;
        }

        public Integer getPressure() {
            return pressure;
        }

        public void setPressure(Integer pressure) {
            this.pressure = pressure;
        }

        public Integer getHumidity() {
            return humidity;
        }

        public void setHumidity(Integer humidity) {
            this.humidity = humidity;
        }

    }

    public class Sys {

        @SerializedName("type")
        private Integer type;
        @SerializedName("id")
        private Integer id;
        @SerializedName("country")
        private String country;
        @SerializedName("sunrise")
        private Integer sunrise;
        @SerializedName("sunset")
        private Integer sunset;

        public Integer getType() {
            return type;
        }

        public void setType(Integer type) {
            this.type = type;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getCountry() {
            return country;
        }

        public void setCountry(String country) {
            this.country = country;
        }

        public Integer getSunrise() {
            return sunrise;

        }

        public void setSunrise(Integer sunrise) {
            this.sunrise = sunrise;
        }

        public Integer getSunset() {
            return sunset;

        }

        public void setSunset(Integer sunset) {
            this.sunset = sunset;
        }

    }

    public class Weather {

        @SerializedName("id")
        private Integer id;
        @SerializedName("main")
        private String main;
        @SerializedName("description")
        private String description;
        @SerializedName("icon")
        private String icon;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getMain() {
            return main;
        }

        public void setMain(String main) {
            this.main = main;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getIcon() {
            return icon;
        }

        public void setIcon(String icon) {
            this.icon = icon;
        }

    }

    public class Wind {

        @SerializedName("speed")
        private Double speed;
        @SerializedName("deg")
        private Integer deg;
        @SerializedName("gust")
        private Double gust;

        public Double getSpeed() {
            return speed;
        }

        public void setSpeed(Double speed) {
            this.speed = speed;
        }

        public Integer getDeg() {
            return deg;
        }

        public void setDeg(Integer deg) {
            this.deg = deg;
        }

        public Double getGust() {
            return gust;
        }

        public void setGust(Double gust) {
            this.gust = gust;
        }
    }

    public String getPrettyDate() {
        SimpleDateFormat HMM = new SimpleDateFormat("hh:mm a", Locale.US);
        final Date date = new Date(dt*1000);
        return HMM.format(date);
    }
}

My Activity class(Where i called dt):

public class HomeActivity extends AppCompatActivity {
    // User current time
    TextView time_field;
    ImageView Search;
    EditText textfield;
    ConstraintLayout constraintLayout;
    // For scheduling background image change
    public static int count=0;
    int[] drawable =new int[]{R.drawable.dubai,R.drawable.central_bank_of_nigeria,R.drawable.eiffel_tower,R.drawable.hong_kong,R.drawable.statue_of_liberty};
    Timer _t;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        time_field = findViewById(R.id.textView9);
        Search = findViewById(R.id.imageView4);
        textfield = findViewById(R.id.textfield);

        BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
        final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        assert navHostFragment != null;
        final NavController navController = navHostFragment.getNavController();
        NavigationUI.setupWithNavController(bottomNavigationView, navController);

        Search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                getWeatherData(textfield.getText().toString().trim());
                FirstFragment firstFragment = (FirstFragment) navHostFragment.getChildFragmentManager().getFragments().get(0);
                firstFragment.getWeatherData(textfield.getText().toString().trim());

                            constraintLayout = findViewById(R.id.layout);
                            constraintLayout.setBackgroundResource(R.drawable.dubai);
                            _t = new Timer();
                            _t.scheduleAtFixedRate(new TimerTask() {
                                @Override
                                public void run() {
                                    // run on ui thread
                                    runOnUiThread(() -> {
                                        if (count < drawable.length) {

                                            constraintLayout.setBackgroundResource(drawable[count]);
                                            count = (count + 1) % drawable.length;
                                        }
                                    });
                                }
                            }, 5000, 5000);
                        }

            private void getWeatherData(String name) {

                ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

                Call<Example> call = apiInterface.getWeatherData(name);

                call.enqueue(new Callback<Example>() {
                    @Override
                    public void onResponse(@NotNull Call<Example> call, @NotNull Response<Example> response) {

                        assert response.body() != null;
                        time_field.setText("Last Updated:" + " " + response.body().getPrettyDate());

                    }

                    @Override
                    public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                        t.printStackTrace();
                    }

                });
            }

        });
    }
}

My FirstFragment class(Where i called sunrise and sunset):

public class FirstFragment extends Fragment {
    // User current time, current temperature, current condition, sunrise, sunset, temperature, pressure, humidity, wind_speed, visibility, clouds
    TextView current_temp, current_output, rise_time, set_time, temp_out, Press_out, Humid_out, Ws_out, Visi_out, Cloud_out;
    // TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public FirstFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment SecondFragment.
     */
// TODO: Rename and change types and number of parameters
    public static FirstFragment newInstance(String param1, String param2) {
        FirstFragment fragment = new FirstFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);

        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_first, container, false);
        // For displaying weather data
        current_temp = rootView.findViewById(R.id.textView10);
        current_output = rootView.findViewById(R.id.textView11);
        rise_time = rootView.findViewById(R.id.textView25);
        set_time = rootView.findViewById(R.id.textView26);
        temp_out = rootView.findViewById(R.id.textView28);
        Press_out = rootView.findViewById(R.id.textView29);
        Humid_out = rootView.findViewById(R.id.textView30);
        Ws_out = rootView.findViewById(R.id.textView33);
        Visi_out = rootView.findViewById(R.id.textView34);
        Cloud_out = rootView.findViewById(R.id.textView35);

        return rootView;
    }

    public void getWeatherData(String name) {

        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

        Call<Example> call = apiInterface.getWeatherData(name);

        call.enqueue(new Callback<Example>() {
            @Override
            public void onResponse(@NotNull Call<Example> call, @NotNull Response<Example> response) {

                assert response.body() !=null;
                current_temp.setText(response.body().getMain().getTemp() + " ℃");
                current_output.setText(response.body().getWeather().get(0).getDescription());
                rise_time.setText(response.body().getSys().getSunrise() + " ");
                set_time.setText(response.body().getSys().getSunset() + " ");
                temp_out.setText(response.body().getMain().getTemp() + " ℃");
                Press_out.setText(response.body().getMain().getPressure() + " hpa");
                Humid_out.setText(response.body().getMain().getHumidity() + " %");
                Ws_out.setText(response.body().getWind().getSpeed() + " Km/h");
                Visi_out.setText(response.body().getVisibility() + " m");
                Cloud_out.setText(response.body().getClouds().getAll()+ " %");
            }

            @Override
            public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                t.printStackTrace();
            }
        });
    }
}
Chinez
  • 551
  • 2
  • 6
  • 29
  • Your edit has changed the nature of your Question. Please, do not make such a change. Altering the nature of your Question confuses the reader, such as your title now having nothing to do with your actual question. And such changes make existing Answers look off-topic, which is rude to the author and unhelpful to other readers. – Basil Bourque May 12 '21 at 23:51

1 Answers1

-1

tl;dr

Instant                                      // Represents a moment, a point on the timeline, as seen in UTC (an offset of zero), with resolution of nanoseconds.
.ofEpochSecond( 1_620_792_785L )             // Returns a `Instant`.
.atZone(
    ZoneId.of( "Africa/Tunis" )              // Returns a `ZoneId`.

)                                            // Returns a `ZonedDateTime`.
.format(
    DateTimeFormatter
    .ofLocalizedTime( FormatStyle.MEDIUM )   // Returns a `DateTimeFormatter`.
    .withLocale( Locale.US ) ;               // Returns another `DateTimeFormatter` rather than altering the original, per immutable objects pattern. 
)                                            // Returns a `String`.

Details

This has been covered many times on Stack Overflow. So I’ll be brief. Search to learn more.

in the form of milliseconds(i.e 1620792785)

No, that looks like a count of whole seconds, not milliseconds, since 1970-01-01T00:00Z.

Never use the terrible legacy date-time classes. Use only java.time classes.

Parse your count of whole seconds since first moment of 1970 UTC as a Instant.

Instant instant = Instant.ofEpochSecond( 1_620_792_785L ) ;

To see that same moment using the wall-clock time kept by the people of a particular region, apply a time zone (ZoneId) to get a ZonedDateTime.

Specify a real time zone name in format of Continent/Region. Apparently your zone is six hours behind UTC. Several time zones currently share that offset-from-UTC. I arbitrarily chose one of them, America/Managua. So replace with your particular time zone.

ZoneId z = ZoneId.of( "America/Managua" ) ;
ZonedDateTime z = instant.atZone( z ) ;

To generate text representing that value, use a DateTimeFormatter object. Such an object can automatically localize by calling DateTimeFormatter.ofLocalizedTime.

Android 26 and later has java.time built-in. For earlier Android, most of the java.time functionality is available through “API desugaring” in the latest tooling.

Any city

After editing, you changed the nature of your Question to ask about how to change time zones according to any arbitrary city name the user may enter.

No magic solution there. You must translate from the user's entered city to a particular time zone name. I know of no library to do that. Mapping from a city name is tricky, as city names are far from unique For example, Paris France, Paris Texas. And many Springfield towns in the United States.

Usually an app asks the user to select their desired time zone. You can prompt for continent to narrow down the list.

To get a list of all time zones currently known at runtime by calling:

Set< String > timeZoneNames = ZoneId.getAvailableZoneIds() ;

See the excellent Answer by Ole V.V. to the original of your now-duplicate Question.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Thanks for taking out time to explain these things but I'm not converting for a particular time zone but any city(not specific) the app searches any city typed on the search button. Also I understand that it has been addressed severally before, but I couldn't find anyone helpful enough, that's why I posted this. No offense – Chinez May 12 '21 at 18:36