如何解决将日期时间、日出和日落从毫秒转换为实时格式
我的天气应用以毫秒(即 1620792785)的形式显示来自 OpenWeatherMap 的日期时间(上次更新)、日出和日落数据。 我正在尝试将其转换为实时格式(即 hh:mm a)。
我尝试在示例类中为 dt 使用此代码:
public String getPrettyDate() {
SimpleDateFormat HMM = new SimpleDateFormat("hh:mm a",Locale.US);
final Date date = new Date(dt*1000);
return HMM.format(date);
}
时间转换的很好,但是没有准确显示数据(这里是下午3点的时候,显示的是晚上9点)。
我也检查了这个网站是否有类似的问题,但没有发现。
所以我想:
- 准确转换 dt
- 准确转换日出和日落时间 使用正确的代码和类。
编辑: 我的应用可以搜索任何城市,所以我不是针对特定时区而是针对所有城市
我的 JSON 响应:
{
"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
}
我的示例类:
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);
}
}
我的活动类(我称之为 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();
}
});
}
});
}
}
我的 FirstFragment 类(我称之为日出和日落):
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();
}
});
}
}
解决方法
tl;博士
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`.
详情
这在 Stack Overflow 上已经讲过很多次了。所以我会很简短。搜索以了解更多信息。
以毫秒的形式(即 1620792785)
不,这看起来像是整秒计数,而不是毫秒,自 1970-01-01T00:00Z 以来。
永远不要使用糟糕的遗留日期时间类。 仅使用 java.time 类。
将自 1970 年 UTC 的第一时刻以来的整秒数解析为 Instant
。
Instant instant = Instant.ofEpochSecond( 1_620_792_785L ) ;
要使用特定地区人民的挂钟时间查看同一时刻,请应用时区 (ZoneId
) 以获得 ZonedDateTime
。
以 Continent/Region
的格式指定 real time zone name。显然,您的区域比 UTC 晚了六个小时。目前有几个时区共享与 UTC 的偏移量。我随意选择了其中之一,America/Managua
。因此,请替换为您的特定时区。
ZoneId z = ZoneId.of( "America/Managua" ) ;
ZonedDateTime z = instant.atZone( z ) ;
要生成表示该值的文本,请使用 DateTimeFormatter
对象。这样的对象可以通过调用 DateTimeFormatter.ofLocalizedTime
来自动定位。
Android 26 及更高版本内置了 java.time。对于早期的 Android,大部分 java.time 功能都可以通过最新工具中的“API 脱糖”获得。
任何城市
编辑后,您更改了问题的性质,询问如何根据用户可能输入的任意城市名称更改时区。
没有神奇的解决方案。您必须将用户输入的城市转换为 particular time zone name。我知道没有图书馆可以做到这一点。从城市名称进行映射很棘手,因为城市名称远非唯一。例如,Paris France、Paris Texas。以及美国的许多斯普林菲尔德城镇。
通常应用会要求用户选择他们想要的时区。可以提示大洲缩小列表。
要获取运行时当前已知的所有时区的列表,请调用:
Set< String > timeZoneNames = ZoneId.getAvailableZoneIds() ;
查看您现在重复的问题的 excellent Answer by Ole V.V. 到 the original。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。