如何转换不同时区的时间
how to convert time for different timezones
所以我正在制作一个消息传递应用程序,但我无法正确完成代码
这是发送按钮:
sendbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View _view) {
if (img == 0) {
if (edittext1.getText().toString().equals("")) {
}
else {
Numberrr++;
mm = new HashMap<>();
mm.put("username", get_name);
mm.put("pfp", get_pfp);
mm.put("messages", edittext1.getText().toString().trim());
mm.put("user_uid", FirebaseAuth.getInstance().getCurrentUser().getUid());
mm.put("number", String.valueOf((long)(Numberrr)));
cal = Calendar.getInstance();
mm.put("time", new SimpleDateFormat("E hh:mm s").format(cal.getTime()));
ch.push().updateChildren(mm);
mm.clear();
edittext1.setText("");
lastText.edit().putString("Lasttext", String.valueOf((long)(Numberrr))).commit();
}
}
else {
store.child(imgName).putFile(Uri.fromFile(new File(imgPath))).addOnFailureListener(_store_failure_listener).addOnProgressListener(_store_upload_progress_listener).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
@Override
public Task<Uri> then(Task<UploadTask.TaskSnapshot> task) throws Exception {
return store.child(imgName).getDownloadUrl();
}
}).addOnCompleteListener(_store_upload_success_listener);
progressbar1.setVisibility(View.VISIBLE);
sendbutton.setEnabled(false);
edittext1.setEnabled(false);
}
}
});
这是 ListView 代码的一部分:
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View _view = _v;
if (_view == null) {
_view = _inflater.inflate(R.layout.messgebubble, null);
}
final LinearLayout time = _view.findViewById(R.id.time);
final TextView textview1 = _view.findViewById(R.id.textview1);
final LinearLayout linear4 = _view.findViewById(R.id.linear4);
final TextView timetext = _view.findViewById(R.id.timetext);
final LinearLayout left = _view.findViewById(R.id.left);
final LinearLayout linear1 = _view.findViewById(R.id.linear1);
final de.hdodenhof.circleimageview.CircleImageView circleimageview1 = _view.findViewById(R.id.circleimageview1);
final TextView message = _view.findViewById(R.id.message);
final ImageView imageview1 = _view.findViewById(R.id.imageview1);
final TextView SystemText = _view.findViewById(R.id.systemtext);
final LinearLayout system = _view.findViewById(R.id.system);
//This is to set the time on text view
timetext.setText(new Sim("MM/yyyy hh:mm:ss").format(_data.get((int)_position).get("time").toString()));
//end
所以我正在尝试让消息在不同时区显示正确的消息时间
例如如果有人在 (UTC+1) 但消息来自 (UTC+5) 并且消息是在 17:35(UTC+5) 发送的,它会显示 17:35 但它应该显示 14:35...如您所知,这也会在代码中引起很多问题。
编辑:修订
你的问题不清楚。但这些要点可能会对您有所帮助:
- 永远不要使用遗留的 date-time classes,例如
Date
、Calendar
、SimpleDateFormat
等。它们 很糟糕。仅使用 JSR 310. 中定义的现代 java.time classes
- 要跟踪时刻,时间线上的特定点,请使用
java.time.Instant
class“以 UTC”(与 UTC 的偏移量为零 hours-minutes-seconds)执行此操作。
- 要以文本方式序列化时刻以进行数据存储或数据交换,请使用标准 ISO 8601 格式。通常最好在 UTC 中这样做,使用
Instant#toString
和 Instant.parse
.
这是一些简短的代码。但搜索以了解更多信息。所有这些都已在 Stack Overflow 上多次提及。
捕捉当下瞬间
使用 java.time.Instant
表示 UTC 中的时刻。
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
String s = instant.toString() ; // Generate text in standard ISO 8601 format.
解析
这里我们解析标准 ISO 8601 格式的文本。
Instant instant = Instant.parse( "2022-04-19T15:30:14.348767Z" ) ;
调整到时区
为了向用户展示,您可能需要调整到特定时区。同一时刻,时间轴上的同一点,不同的 wall-clock 时间。
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
生成文本
标准格式
要生成标准格式的文本,只需调用 toString
。
instant.toString(): 2022-04-19T15:30:14.348767Z
zdt.toString(): 2022-04-19T09:30:14.348767-06:00[America/Edmonton]
实际上最后一个是标准格式的明智扩展,将时区名称附加在方括号中。
本地化格式
要生成本地化格式的文本,请使用 DateTimeFormatter.ofLocalizedDateTime
。
FormatStyle style = FormatStyle.SHORT ;
Locale locale = Locale.CANADA_FRENCH ; // Or Locale.US or new Locale( "fr" , "MA" ) (French in Morocco), etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( style ).withLocale( locale ) ;
String output = zdt.format( f );
看到这个code run live at IdeOne.com。
output: 22-04-19 09 h 30
您当然可以通过 DateTimeFormatter.ofPattern
指定自定义格式。 (Search 以了解更多信息。)但自动本地化可能会让您的生活更简单。
所以我正在制作一个消息传递应用程序,但我无法正确完成代码
这是发送按钮:
sendbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View _view) {
if (img == 0) {
if (edittext1.getText().toString().equals("")) {
}
else {
Numberrr++;
mm = new HashMap<>();
mm.put("username", get_name);
mm.put("pfp", get_pfp);
mm.put("messages", edittext1.getText().toString().trim());
mm.put("user_uid", FirebaseAuth.getInstance().getCurrentUser().getUid());
mm.put("number", String.valueOf((long)(Numberrr)));
cal = Calendar.getInstance();
mm.put("time", new SimpleDateFormat("E hh:mm s").format(cal.getTime()));
ch.push().updateChildren(mm);
mm.clear();
edittext1.setText("");
lastText.edit().putString("Lasttext", String.valueOf((long)(Numberrr))).commit();
}
}
else {
store.child(imgName).putFile(Uri.fromFile(new File(imgPath))).addOnFailureListener(_store_failure_listener).addOnProgressListener(_store_upload_progress_listener).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
@Override
public Task<Uri> then(Task<UploadTask.TaskSnapshot> task) throws Exception {
return store.child(imgName).getDownloadUrl();
}
}).addOnCompleteListener(_store_upload_success_listener);
progressbar1.setVisibility(View.VISIBLE);
sendbutton.setEnabled(false);
edittext1.setEnabled(false);
}
}
});
这是 ListView 代码的一部分:
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View _view = _v;
if (_view == null) {
_view = _inflater.inflate(R.layout.messgebubble, null);
}
final LinearLayout time = _view.findViewById(R.id.time);
final TextView textview1 = _view.findViewById(R.id.textview1);
final LinearLayout linear4 = _view.findViewById(R.id.linear4);
final TextView timetext = _view.findViewById(R.id.timetext);
final LinearLayout left = _view.findViewById(R.id.left);
final LinearLayout linear1 = _view.findViewById(R.id.linear1);
final de.hdodenhof.circleimageview.CircleImageView circleimageview1 = _view.findViewById(R.id.circleimageview1);
final TextView message = _view.findViewById(R.id.message);
final ImageView imageview1 = _view.findViewById(R.id.imageview1);
final TextView SystemText = _view.findViewById(R.id.systemtext);
final LinearLayout system = _view.findViewById(R.id.system);
//This is to set the time on text view
timetext.setText(new Sim("MM/yyyy hh:mm:ss").format(_data.get((int)_position).get("time").toString()));
//end
所以我正在尝试让消息在不同时区显示正确的消息时间
例如如果有人在 (UTC+1) 但消息来自 (UTC+5) 并且消息是在 17:35(UTC+5) 发送的,它会显示 17:35 但它应该显示 14:35...如您所知,这也会在代码中引起很多问题。
编辑:修订
你的问题不清楚。但这些要点可能会对您有所帮助:
- 永远不要使用遗留的 date-time classes,例如
Date
、Calendar
、SimpleDateFormat
等。它们 很糟糕。仅使用 JSR 310. 中定义的现代 java.time classes
- 要跟踪时刻,时间线上的特定点,请使用
java.time.Instant
class“以 UTC”(与 UTC 的偏移量为零 hours-minutes-seconds)执行此操作。 - 要以文本方式序列化时刻以进行数据存储或数据交换,请使用标准 ISO 8601 格式。通常最好在 UTC 中这样做,使用
Instant#toString
和Instant.parse
.
这是一些简短的代码。但搜索以了解更多信息。所有这些都已在 Stack Overflow 上多次提及。
捕捉当下瞬间
使用 java.time.Instant
表示 UTC 中的时刻。
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
String s = instant.toString() ; // Generate text in standard ISO 8601 format.
解析
这里我们解析标准 ISO 8601 格式的文本。
Instant instant = Instant.parse( "2022-04-19T15:30:14.348767Z" ) ;
调整到时区
为了向用户展示,您可能需要调整到特定时区。同一时刻,时间轴上的同一点,不同的 wall-clock 时间。
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
生成文本
标准格式
要生成标准格式的文本,只需调用 toString
。
instant.toString(): 2022-04-19T15:30:14.348767Z
zdt.toString(): 2022-04-19T09:30:14.348767-06:00[America/Edmonton]
实际上最后一个是标准格式的明智扩展,将时区名称附加在方括号中。
本地化格式
要生成本地化格式的文本,请使用 DateTimeFormatter.ofLocalizedDateTime
。
FormatStyle style = FormatStyle.SHORT ;
Locale locale = Locale.CANADA_FRENCH ; // Or Locale.US or new Locale( "fr" , "MA" ) (French in Morocco), etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( style ).withLocale( locale ) ;
String output = zdt.format( f );
看到这个code run live at IdeOne.com。
output: 22-04-19 09 h 30
您当然可以通过 DateTimeFormatter.ofPattern
指定自定义格式。 (Search 以了解更多信息。)但自动本地化可能会让您的生活更简单。